Skip to content

Commit 46be050

Browse files
add easing as param
1 parent 8434a49 commit 46be050

File tree

1 file changed

+40
-28
lines changed
  • Tutorial1-1Basics/src/main/java/com/smarttoolfactory/tutorial1_1basics/chapter9_animation

1 file changed

+40
-28
lines changed

Tutorial1-1Basics/src/main/java/com/smarttoolfactory/tutorial1_1basics/chapter9_animation/ParticleAnimations.kt

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ import androidx.compose.ui.geometry.Size
4141
import androidx.compose.ui.graphics.Color
4242
import androidx.compose.ui.graphics.ImageBitmap
4343
import androidx.compose.ui.graphics.asAndroidBitmap
44+
import androidx.compose.ui.graphics.asImageBitmap
4445
import androidx.compose.ui.graphics.drawscope.DrawScope
4546
import androidx.compose.ui.graphics.drawscope.Stroke
47+
import androidx.compose.ui.graphics.drawscope.clipRect
4648
import androidx.compose.ui.graphics.rememberGraphicsLayer
4749
import androidx.compose.ui.platform.LocalContext
4850
import androidx.compose.ui.platform.LocalDensity
@@ -59,7 +61,6 @@ import com.smarttoolfactory.tutorial1_1basics.ui.Pink400
5961
import kotlinx.coroutines.CancellationException
6062
import kotlin.random.Random
6163

62-
6364
@Preview
6465
@Composable
6566
fun SingleParticleTrajectorySample() {
@@ -219,12 +220,13 @@ fun ParticleAnimationSample() {
219220
.border(2.dp, Color.Red)
220221
.size(widthDp)
221222
.disintegrate(
222-
// progress = progress,
223+
progress = progress,
223224
particleState = particleState,
224225
onStart = {
225226
Toast.makeText(context, "Animation started...", Toast.LENGTH_SHORT).show()
226227
},
227228
onEnd = {
229+
// particleState.animationStatus = AnimationStatus.Idle
228230
Toast.makeText(context, "Animation ended...", Toast.LENGTH_SHORT).show()
229231
}
230232
),
@@ -323,22 +325,23 @@ fun Modifier.disintegrate(
323325
}
324326
}
325327

326-
Modifier.drawWithCache {
327-
onDrawWithContent {
328-
if (animationStatus != AnimationStatus.Playing) {
329-
drawContent()
330-
graphicsLayer.record {
331-
this@onDrawWithContent.drawContent()
328+
Modifier
329+
.drawWithCache {
330+
onDrawWithContent {
331+
if (animationStatus != AnimationStatus.Playing) {
332+
drawContent()
333+
graphicsLayer.record {
334+
this@onDrawWithContent.drawContent()
335+
}
332336
}
333-
}
334337

335-
particleState.updateAndDrawParticles(
336-
drawScope = this,
337-
particleList = particleState.particleList,
338-
progress = progress
339-
)
338+
particleState.updateAndDrawParticles(
339+
drawScope = this,
340+
particleList = particleState.particleList,
341+
progress = progress
342+
)
343+
}
340344
}
341-
}
342345
}
343346

344347
@Composable
@@ -365,6 +368,11 @@ class ParticleState internal constructor(particleSize: Dp) {
365368
var bitmap: Bitmap? = null
366369
internal set
367370

371+
var animationSpec = tween<Float>(
372+
durationMillis = 2000,
373+
easing = FastOutSlowInEasing
374+
)
375+
368376
fun addParticle(particle: Particle) {
369377
particleList.add(particle)
370378
}
@@ -377,6 +385,15 @@ class ParticleState internal constructor(particleSize: Dp) {
377385
with(drawScope) {
378386
if (animationStatus != AnimationStatus.Idle) {
379387

388+
// TODO disintegrate image non-uniformly, with blend mode of particles
389+
// clipRect(
390+
// left = progress * size.width
391+
// ) {
392+
// bitmap?.asImageBitmap()?.let {
393+
// drawImage(it)
394+
// }
395+
// }
396+
380397
particleList.forEach { particle ->
381398

382399
updateParticle(progress, particle)
@@ -394,13 +411,6 @@ class ParticleState internal constructor(particleSize: Dp) {
394411
)
395412
}
396413

397-
// TODO disintegrate image non-uniformly, with blend mode of particles
398-
// clipRect(
399-
// left = progress * size.width
400-
// ) {
401-
// this@onDrawWithContent.drawContent()
402-
// }
403-
404414
// For debugging
405415
drawRect(
406416
color = Color.Black,
@@ -422,7 +432,6 @@ class ParticleState internal constructor(particleSize: Dp) {
422432
val width = bitmap.width
423433
val height = bitmap.height
424434

425-
426435
val particleRadius = particleSize / 2
427436

428437
// divide image into squares based on particle size
@@ -467,9 +476,11 @@ class ParticleState internal constructor(particleSize: Dp) {
467476
// Add some vertical randomization for trajectory so particles don't start
468477
// animating vertically as well. Particles with smaller y value in same x
469478
// coordinate tend to start earlier
479+
val startYOffset =
480+
(fractionToImageHeight * Random.nextFloat()).coerceAtMost(.2f)
481+
470482
trajectoryProgressRange =
471-
trajectoryProgressRange.start + fractionToImageHeight * Random.nextFloat()
472-
.coerceAtMost(.2f)..trajectoryProgressRange.endInclusive
483+
trajectoryProgressRange.start + startYOffset..trajectoryProgressRange.endInclusive
473484

474485
val endSize = randomInRange(0f, particleSize.toFloat() * .5f)
475486

@@ -565,13 +576,14 @@ class ParticleState internal constructor(particleSize: Dp) {
565576
try {
566577
onStart()
567578
animatable.snapTo(0f)
568-
animatable.animateTo(1f, tween(durationMillis = 2400, easing = FastOutSlowInEasing))
569-
animationStatus = AnimationStatus.Idle
579+
animatable.animateTo(
580+
targetValue = 1f,
581+
animationSpec = animationSpec
582+
)
570583
} catch (e: CancellationException) {
571584
println("FAILED: ${e.message}")
572585
} finally {
573586
onEnd()
574-
animationStatus = AnimationStatus.Idle
575587
}
576588
}
577589

0 commit comments

Comments
 (0)