Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.

Commit 70216b2

Browse files
authored
motion 1 Fly In (#801)
* Motion1 Fly-in demo * update build.gradle * add drag demo * add mult state demo * tweak mult-state
1 parent d361dd9 commit 70216b2

File tree

6 files changed

+722
-3
lines changed

6 files changed

+722
-3
lines changed

demoProjects/ExamplesComposeMotionLayout/app/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ android {
4949
dependencies {
5050
implementation 'androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha07'
5151
implementation 'com.google.accompanist:accompanist-pager:0.29.1-alpha'
52-
52+
debugImplementation "androidx.compose.ui:ui-tooling:1.0.0-rc01"
53+
implementation "androidx.compose.ui:ui-tooling-preview:1.0.0-rc01"
5354
implementation 'androidx.core:core-ktx:1.9.0'
5455
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
5556
implementation 'androidx.activity:activity-compose:1.6.1'
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package com.example.examplescomposemotionlayout
2+
3+
import android.annotation.SuppressLint
4+
import androidx.compose.animation.core.Animatable
5+
import androidx.compose.animation.core.tween
6+
import androidx.compose.foundation.background
7+
import androidx.compose.foundation.layout.Box
8+
import androidx.compose.foundation.layout.fillMaxSize
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.shape.RoundedCornerShape
11+
import androidx.compose.material.Text
12+
import androidx.compose.runtime.*
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.draw.clip
15+
import androidx.compose.ui.graphics.Color
16+
import androidx.compose.ui.layout.layoutId
17+
import androidx.compose.ui.res.painterResource
18+
import androidx.compose.ui.tooling.preview.Preview
19+
import androidx.compose.ui.unit.dp
20+
import androidx.constraintlayout.compose.*
21+
import kotlin.math.abs
22+
23+
// A simple fly in effect
24+
@SuppressLint("Range")
25+
@OptIn(ExperimentalMotionApi::class)
26+
@Preview(group = "motion101")
27+
@Composable
28+
fun M1FlyIn() {
29+
val imgId = "image"
30+
val id = arrayOf<String>("w1", "w2", "w3", "w4", "w5", "w6")
31+
val emojis = "😀 🙂 🤨 😐 😒 😬".split(' ')
32+
33+
var scene = MotionScene() {
34+
val refs = id.map { createRefFor(it) }.toTypedArray()
35+
val imgRef = createRefFor("image")
36+
val start1 = constraintSet {
37+
constrain(imgRef) {
38+
width = Dimension.value(10.dp)
39+
height = Dimension.value(10.dp)
40+
alpha = 0f
41+
centerHorizontallyTo(parent)
42+
top.linkTo(parent.top)
43+
bottom.linkTo(parent.bottom, 100.dp)
44+
customFloat("sat", 0f)
45+
customFloat("bright", 0f)
46+
customFloat("rot", -360f)
47+
}
48+
for (i in refs.indices) {
49+
constrain(refs[i]) {
50+
width = Dimension.value(32.dp)
51+
height = Dimension.value(32.dp)
52+
bottom.linkTo(parent.bottom, (abs(i * 2 - refs.size + 1) * 200).dp)
53+
centerHorizontallyTo(parent, (i % 2) * 4 - 2f)
54+
55+
}
56+
}
57+
}
58+
59+
val end1 = constraintSet {
60+
constrain(imgRef) {
61+
width = Dimension.fillToConstraints
62+
height = Dimension.fillToConstraints
63+
centerHorizontallyTo(parent)
64+
top.linkTo(parent.top)
65+
bottom.linkTo(parent.bottom, 100.dp)
66+
customFloat("sat", 1f)
67+
customFloat("bright", 1f)
68+
customFloat("rot", 0f)
69+
}
70+
createHorizontalChain(elements = refs)
71+
for (i in refs.indices) {
72+
constrain(refs[i]) {
73+
width = Dimension.value(32.dp)
74+
height = Dimension.value(32.dp)
75+
bottom.linkTo(parent.bottom, 16.dp)
76+
}
77+
}
78+
}
79+
transition(start1, end1, "default") {
80+
motionArc = Arc.StartHorizontal
81+
82+
keyPositions(*refs) {
83+
frame(50) {
84+
type = RelativePosition.Delta
85+
percentY = 0.1f
86+
}
87+
}
88+
keyAttributes(*refs) {
89+
frame(50) {
90+
scaleX = 6f
91+
scaleY = 6f
92+
}
93+
}
94+
keyAttributes(imgRef) {
95+
frame(70) {
96+
customFloat("sat", 0f)
97+
customFloat("bright", 1.6f)
98+
99+
}
100+
}
101+
keyCycles(imgRef) {
102+
frame(0) {
103+
period = 0f
104+
translationY = 0f
105+
}
106+
frame(50) {
107+
period = 1f
108+
translationY = 200f
109+
}
110+
frame(100) {
111+
period = 0f
112+
translationY = 0f
113+
}
114+
}
115+
}
116+
}
117+
val painter = painterResource(id = R.drawable.pepper)
118+
119+
var animateToEnd by remember { mutableStateOf(true) }
120+
val progress = remember { Animatable(0f) }
121+
LaunchedEffect(animateToEnd) {
122+
progress.animateTo(
123+
if (animateToEnd) 1f else 0f,
124+
animationSpec = tween(5000)
125+
)
126+
}
127+
MotionLayout(
128+
modifier = Modifier
129+
.background(Color(0xFF221010))
130+
.fillMaxSize()
131+
.padding(1.dp),
132+
motionScene = scene,
133+
progress = progress.value
134+
) {
135+
MotionImage(
136+
painter = painter,
137+
brightness = customFloat(imgId, "bright"),
138+
saturation = customFloat(imgId, "sat"),
139+
rotate = customFloat(imgId, "rot"),
140+
modifier = Modifier.layoutId(imgId)
141+
)
142+
for (i in id.indices) {
143+
Box(
144+
modifier = Modifier
145+
.layoutId(id[i])
146+
.clip(RoundedCornerShape(20.dp))
147+
) {
148+
Text(text = emojis[i])
149+
}
150+
}
151+
}
152+
}
153+
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package com.example.examplescomposemotionlayout
2+
3+
import android.annotation.SuppressLint
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.layout.Box
6+
import androidx.compose.foundation.layout.fillMaxSize
7+
import androidx.compose.foundation.layout.padding
8+
import androidx.compose.foundation.shape.RoundedCornerShape
9+
import androidx.compose.material.Text
10+
import androidx.compose.runtime.*
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.draw.clip
13+
import androidx.compose.ui.graphics.Color
14+
import androidx.compose.ui.layout.layoutId
15+
import androidx.compose.ui.res.painterResource
16+
import androidx.compose.ui.tooling.preview.Preview
17+
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
18+
import androidx.compose.ui.unit.dp
19+
import androidx.compose.ui.unit.sp
20+
import androidx.constraintlayout.compose.*
21+
22+
// A simple fly in effect
23+
@SuppressLint("Range")
24+
@OptIn(ExperimentalMotionApi::class)
25+
@Preview(group = "motion101")
26+
@Composable
27+
fun M2DragReveal() {
28+
val imageId = "image"
29+
val titleId = "title"
30+
val wordsId = "words"
31+
32+
var scene = MotionScene() {
33+
val imageRef = createRefFor(imageId)
34+
val titleRef = createRefFor(titleId)
35+
val wordsRef = createRefFor(wordsId)
36+
37+
38+
val start1 = constraintSet {
39+
constrain(imageRef) {
40+
width = Dimension.fillToConstraints
41+
height = Dimension.value(400.dp)
42+
alpha = 1f
43+
centerHorizontallyTo(parent)
44+
top.linkTo(parent.top)
45+
customFloat("sat", 1f)
46+
customFloat("bright", 1f)
47+
}
48+
constrain(titleRef) {
49+
width = Dimension.wrapContent
50+
height = Dimension.wrapContent
51+
centerHorizontallyTo(parent)
52+
top.linkTo(imageRef.bottom,2.dp)
53+
}
54+
constrain(wordsRef) {
55+
width = Dimension.fillToConstraints
56+
height = Dimension.wrapContent
57+
centerHorizontallyTo(parent)
58+
top.linkTo(titleRef.bottom)
59+
}
60+
}
61+
62+
val end1 = constraintSet {
63+
constrain(imageRef) {
64+
width = Dimension.value(80.dp)
65+
height =Dimension.value(80.dp)
66+
centerHorizontallyTo(parent,0f)
67+
top.linkTo(parent.top)
68+
customFloat("sat", 0.8f)
69+
customFloat("bright", 0.8f)
70+
}
71+
constrain(titleRef) {
72+
width = Dimension.wrapContent
73+
height = Dimension.wrapContent
74+
centerHorizontallyTo(parent)
75+
top.linkTo(imageRef.top)
76+
bottom.linkTo(imageRef.bottom)
77+
}
78+
constrain(wordsRef) {
79+
width = Dimension.fillToConstraints
80+
height = Dimension.wrapContent
81+
centerHorizontallyTo(parent)
82+
top.linkTo(imageRef.bottom)
83+
}
84+
}
85+
transition( start1,end1,"default") {
86+
87+
onSwipe = OnSwipe(
88+
side = SwipeSide.Top,
89+
direction = SwipeDirection.Up,
90+
anchor = wordsRef,
91+
mode = SwipeMode.Spring(damping = 40f),
92+
)
93+
keyPositions(titleRef){
94+
frame(40){
95+
percentY = 0.3f
96+
type = RelativePosition.Path
97+
}
98+
}
99+
keyAttributes(imageRef) {
100+
frame(70) {
101+
customFloat("sat", 0f)
102+
customFloat("bright", 1.6f)
103+
104+
}
105+
}
106+
107+
}
108+
}
109+
val painter = painterResource(id = R.drawable.pepper)
110+
111+
112+
MotionLayout(
113+
modifier = Modifier
114+
.background(Color(0xFF221010))
115+
.fillMaxSize()
116+
.padding(1.dp),
117+
motionScene = scene,
118+
119+
) {
120+
MotionImage(
121+
painter = painter,
122+
modifier = Modifier.layoutId(imageId),
123+
brightness = customFloat(imageId, "bright"),
124+
saturation = customFloat(imageId, "sat"),
125+
)
126+
Text(
127+
modifier = Modifier.layoutId(titleId),
128+
text = "Pepper",
129+
fontSize = 30.sp,
130+
color = Color.White
131+
)
132+
Box(
133+
modifier = Modifier
134+
.layoutId(wordsId) .clip(RoundedCornerShape(20.dp))
135+
) {
136+
Text(
137+
text = LoremIpsum(222).values.first(),
138+
modifier = Modifier
139+
.background(Color.White).padding(8.dp)
140+
.layoutId("title"),
141+
)
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)