[go: nahoru, domu]

blob: ec055cf37c967b72566df327646e38e54cbd01c7 [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.animation.demos
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.FloatPropKey
import androidx.compose.animation.core.ManualAnimationClock
import androidx.compose.animation.core.TweenSpec
import androidx.compose.animation.core.transitionDefinition
import androidx.compose.animation.core.tween
import androidx.compose.Composable
import androidx.compose.Providers
import androidx.compose.remember
import androidx.compose.animation.transition
import androidx.compose.animation.animatedFloat
import androidx.ui.core.AnimationClockAmbient
import androidx.ui.core.Modifier
import androidx.ui.core.gesture.DragObserver
import androidx.ui.core.gesture.pressIndicatorGestureFilter
import androidx.ui.core.gesture.rawDragGestureFilter
import androidx.compose.foundation.Box
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Text
import androidx.ui.geometry.Offset
import androidx.ui.geometry.Size
import androidx.ui.graphics.Color
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.preferredHeight
import androidx.compose.foundation.layout.preferredSize
import androidx.ui.unit.dp
import androidx.ui.unit.sp
@Composable
fun AnimatableSeekBarDemo() {
val clock = remember { ManualAnimationClock(0L) }
Providers(AnimationClockAmbient provides clock) {
Column {
Text(
"Drag to update AnimationClock",
fontSize = 20.sp,
modifier = Modifier.padding(40.dp)
)
Box(Modifier.padding(start = 10.dp, end = 10.dp, bottom = 30.dp)) {
MovingTargetExample(clock)
}
val state = transition(
definition = transDef,
initState = "start",
toState = "end"
)
Canvas(Modifier.preferredSize(600.dp, 400.dp)) {
val rectSize = size * 0.2f
drawRect(Color(1.0f, 0f, 0f, state[alphaKey]), size = rectSize)
drawRect(
Color(0f, 0f, 1f, state[alphaKey]),
topLeft = Offset(state[offset1] * size.width, 0.0f),
size = rectSize
)
drawRect(
Color(0f, 1f, 1f, state[alphaKey]),
topLeft = Offset(state[offset2] * size.width, 0.0f),
size = rectSize
)
drawRect(
Color(0f, 1f, 0f, state[alphaKey]),
topLeft = Offset(state[offset3] * size.width, 0.0f),
size = rectSize
)
}
}
}
}
@Composable
fun MovingTargetExample(clock: ManualAnimationClock) {
val animValue = animatedFloat(0f)
val dragObserver = object : DragObserver {
override fun onDrag(dragDistance: Offset): Offset {
animValue.snapTo(animValue.targetValue + dragDistance.x)
return dragDistance
}
}
val onPress: (Offset) -> Unit = { position ->
animValue.animateTo(position.x, TweenSpec(durationMillis = 400))
}
DrawSeekBar(
Modifier
.rawDragGestureFilter(dragObserver)
.pressIndicatorGestureFilter(onStart = onPress),
animValue.value,
clock
)
}
@Composable
fun DrawSeekBar(modifier: Modifier = Modifier, x: Float, clock: ManualAnimationClock) {
Canvas(modifier.fillMaxWidth().preferredHeight(60.dp)) {
val xConstraint = x.coerceIn(0f, size.width)
clock.clockTimeMillis = (400 * (x / size.width)).toLong().coerceIn(0, 399)
// draw bar
val barHeight = 10.0f
val offset = Offset(0.0f, center.y - 5)
drawRect(
Color.Gray,
topLeft = offset,
size = Size(size.width, barHeight)
)
drawRect(
Color.Magenta,
topLeft = offset,
size = Size(xConstraint, barHeight)
)
// draw ticker
drawCircle(
Color.Magenta,
center = Offset(xConstraint, center.y),
radius = 40f
)
}
}
private val alphaKey = FloatPropKey()
private val offset1 = FloatPropKey()
private val offset2 = FloatPropKey()
private val offset3 = FloatPropKey()
private val transDef = transitionDefinition {
state("start") {
this[alphaKey] = 1f
this[offset1] = 0f
this[offset2] = 0f
this[offset3] = 0f
}
state("end") {
this[alphaKey] = 0.2f
this[offset1] = 0.26f
this[offset2] = 0.53f
this[offset3] = 0.8f
}
transition {
alphaKey using tween(
easing = FastOutSlowInEasing,
durationMillis = 400
)
offset1 using tween(
easing = FastOutSlowInEasing,
durationMillis = 400
)
offset2 using tween(
easing = FastOutSlowInEasing,
durationMillis = 400
)
offset3 using tween(
easing = FastOutSlowInEasing,
durationMillis = 400
)
}
}