1 /*
2  * Copyright 2022 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 @file:OptIn(ExperimentalMotionApi::class)
18 
19 package androidx.constraintlayout.compose.demos
20 
21 import androidx.compose.foundation.background
22 import androidx.compose.foundation.layout.Box
23 import androidx.compose.foundation.layout.fillMaxSize
24 import androidx.compose.material.Text
25 import androidx.compose.runtime.Composable
26 import androidx.compose.ui.Modifier
27 import androidx.compose.ui.graphics.Color
28 import androidx.compose.ui.graphics.toArgb
29 import androidx.compose.ui.layout.layoutId
30 import androidx.compose.ui.tooling.preview.Preview
31 import androidx.compose.ui.unit.dp
32 import androidx.constraintlayout.compose.Dimension
33 import androidx.constraintlayout.compose.ExperimentalMotionApi
34 import androidx.constraintlayout.compose.MotionLayout
35 import androidx.constraintlayout.compose.MotionScene
36 import androidx.constraintlayout.compose.OnSwipe
37 import androidx.constraintlayout.compose.SwipeDirection
38 import androidx.constraintlayout.compose.SwipeSide
39 
40 /**
41  * Shows how to use MotionLayout to interpolate custom values such as colors during animation.
42  *
43  * This example animates the background color of a box from [Color.Red] to [Color.Blue] while using
44  * KeyFrames to add intermediate colors [Color.Yellow] and [Color.Green] at 33% and 66% points of
45  * the animation, respectively.
46  *
47  * The animation is driven with an swipe gesture defined by [OnSwipe].
48  */
49 @Preview
50 @Composable
CustomColorInKeyAttributesDemonull51 fun CustomColorInKeyAttributesDemo() {
52     val boxId = "box"
53     val textId = "text"
54     MotionLayout(
55         motionScene =
56             MotionScene {
57                 val box = createRefFor(boxId)
58                 val text = createRefFor(textId)
59                 defaultTransition(
60                     from =
61                         constraintSet {
62                             constrain(text) {
63                                 top.linkTo(box.bottom, 10.dp)
64                                 start.linkTo(box.start)
65                             }
66                             constrain(box) {
67                                 width = Dimension.value(50.dp)
68                                 height = Dimension.value(50.dp)
69 
70                                 centerVerticallyTo(parent)
71                                 start.linkTo(parent.start)
72 
73                                 customColor("background", Color.Red)
74                             }
75                         },
76                     to =
77                         constraintSet {
78                             constrain(text) {
79                                 top.linkTo(box.bottom, 10.dp)
80                                 end.linkTo(box.end)
81                             }
82                             constrain(box) {
83                                 width = Dimension.value(50.dp)
84                                 height = Dimension.value(50.dp)
85 
86                                 centerVerticallyTo(parent)
87                                 end.linkTo(parent.end)
88 
89                                 customColor("background", Color.Blue)
90                             }
91                         }
92                 ) {
93                     onSwipe =
94                         OnSwipe(
95                             anchor = box,
96                             side = SwipeSide.Middle,
97                             direction = SwipeDirection.End
98                         )
99                     keyAttributes(box) {
100                         frame(33) { customColor("background", Color.Yellow) }
101                         frame(66) { customColor("background", Color.Green) }
102                     }
103                 }
104             },
105         progress = 0f,
106         modifier = Modifier.fillMaxSize()
107     ) {
108         val background = customColor(boxId, "background")
109         Box(modifier = Modifier.layoutId(boxId).background(background))
110         Text(
111             modifier = Modifier.layoutId(textId),
112             text = "Color: ${background.toArgb().toUInt().toString(16)}"
113         )
114     }
115 }
116