1 /*
2 * Copyright 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.compose.animation.core.samples
18
19 import androidx.annotation.Sampled
20 import androidx.compose.animation.animateColor
21 import androidx.compose.animation.core.FastOutLinearInEasing
22 import androidx.compose.animation.core.LinearEasing
23 import androidx.compose.animation.core.RepeatMode
24 import androidx.compose.animation.core.VectorConverter
25 import androidx.compose.animation.core.animateFloat
26 import androidx.compose.animation.core.animateValue
27 import androidx.compose.animation.core.infiniteRepeatable
28 import androidx.compose.animation.core.keyframes
29 import androidx.compose.animation.core.rememberInfiniteTransition
30 import androidx.compose.animation.core.tween
31 import androidx.compose.foundation.layout.Box
32 import androidx.compose.foundation.layout.fillMaxSize
33 import androidx.compose.foundation.layout.offset
34 import androidx.compose.material.Icon
35 import androidx.compose.material.icons.Icons
36 import androidx.compose.material.icons.filled.Favorite
37 import androidx.compose.runtime.Composable
38 import androidx.compose.runtime.getValue
39 import androidx.compose.ui.Alignment
40 import androidx.compose.ui.Modifier
41 import androidx.compose.ui.graphics.Color
42 import androidx.compose.ui.graphics.graphicsLayer
43 import androidx.compose.ui.unit.Dp
44 import androidx.compose.ui.unit.dp
45
46 @Sampled
47 @Composable
InfiniteTransitionSamplenull48 fun InfiniteTransitionSample() {
49 @Composable
50 fun InfinitelyPulsingHeart() {
51 // Creates an [InfiniteTransition] instance for managing child animations.
52 val infiniteTransition = rememberInfiniteTransition()
53
54 // Creates a child animation of float type as a part of the [InfiniteTransition].
55 val scale by
56 infiniteTransition.animateFloat(
57 initialValue = 3f,
58 targetValue = 6f,
59 animationSpec =
60 infiniteRepeatable(
61 // Infinitely repeating a 1000ms tween animation using default easing curve.
62 animation = tween(1000),
63 // After each iteration of the animation (i.e. every 1000ms), the animation
64 // will
65 // start again from the [initialValue] defined above.
66 // This is the default [RepeatMode]. See [RepeatMode.Reverse] below for an
67 // alternative.
68 repeatMode = RepeatMode.Restart
69 )
70 )
71
72 // Creates a Color animation as a part of the [InfiniteTransition].
73 val color by
74 infiniteTransition.animateColor(
75 initialValue = Color.Red,
76 targetValue = Color(0xff800000), // Dark Red
77 animationSpec =
78 infiniteRepeatable(
79 // Linearly interpolate between initialValue and targetValue every 1000ms.
80 animation = tween(1000, easing = LinearEasing),
81 // Once [TargetValue] is reached, starts the next iteration in reverse (i.e.
82 // from
83 // TargetValue to InitialValue). Then again from InitialValue to
84 // TargetValue. This
85 // [RepeatMode] ensures that the animation value is *always continuous*.
86 repeatMode = RepeatMode.Reverse
87 )
88 )
89
90 Box(Modifier.fillMaxSize()) {
91 Icon(
92 Icons.Filled.Favorite,
93 contentDescription = null,
94 modifier =
95 Modifier.align(Alignment.Center).graphicsLayer(scaleX = scale, scaleY = scale),
96 tint = color
97 )
98 }
99 }
100 }
101
102 @Sampled
103 @Composable
InfiniteTransitionAnimateValueSamplenull104 fun InfiniteTransitionAnimateValueSample() {
105 // Creates an [InfiniteTransition] instance to run child animations.
106 val infiniteTransition = rememberInfiniteTransition()
107 // Infinitely animate a Dp offset from 0.dp to 100.dp
108 val offsetX by
109 infiniteTransition.animateValue(
110 initialValue = 0.dp,
111 targetValue = 100.dp,
112 typeConverter = Dp.VectorConverter,
113 animationSpec =
114 infiniteRepeatable(
115 animation =
116 keyframes {
117 durationMillis = 500
118 0.dp at 200 // ms
119 80.dp at 300 using FastOutLinearInEasing
120 }
121 // Use the default RepeatMode.Restart to start from 0.dp after each iteration
122 )
123 )
124
125 Box(Modifier.offset(x = offsetX)) {
126 // Content goes here
127 }
128 }
129