@@ -65,9 +65,6 @@ import com.smarttoolfactory.tutorial1_1basics.chapter6_graphics.scale
65
65
import com.smarttoolfactory.tutorial1_1basics.ui.Pink400
66
66
import kotlinx.coroutines.CancellationException
67
67
import kotlinx.coroutines.Dispatchers
68
- import kotlinx.coroutines.android.awaitFrame
69
- import kotlinx.coroutines.async
70
- import kotlinx.coroutines.delay
71
68
import kotlinx.coroutines.withContext
72
69
import kotlin.math.roundToInt
73
70
import kotlin.random.Random
@@ -233,27 +230,27 @@ fun ParticleAnimationSample() {
233
230
mutableFloatStateOf(0f )
234
231
}
235
232
236
- // SentMessageRowAlt(
237
- // modifier = Modifier
238
- // .clickable {
239
- // particleState.startAnimation()
240
- // }
241
- // .disintegrate(
242
- // // progress = progress,
243
- // particleState = particleState,
244
- // onStart = {
245
- // Toast.makeText(context, "Animation started...", Toast.LENGTH_SHORT).show()
246
- // },
247
- // onEnd = {
248
- // particleState.animationStatus = AnimationStatus.Idle
249
- // Toast.makeText(context, "Animation ended...", Toast.LENGTH_SHORT).show()
250
- // }
251
- // ),
252
- // quotedImage = R.drawable.avatar_4_raster,
253
- // text = "Some long message",
254
- // messageTime = "11.02.2024",
255
- // messageStatus = MessageStatus.READ
256
- // )
233
+ SentMessageRowAlt (
234
+ modifier = Modifier
235
+ .clickable {
236
+ particleState.startAnimation()
237
+ }
238
+ .disintegrate(
239
+ // progress = progress,
240
+ particleState = particleState,
241
+ onStart = {
242
+ Toast .makeText(context, " Animation started..." , Toast .LENGTH_SHORT ).show()
243
+ },
244
+ onEnd = {
245
+ particleState.animationStatus = AnimationStatus .Idle
246
+ Toast .makeText(context, " Animation ended..." , Toast .LENGTH_SHORT ).show()
247
+ }
248
+ ),
249
+ quotedImage = R .drawable.avatar_4_raster,
250
+ text = " Some long message" ,
251
+ messageTime = " 11.02.2024" ,
252
+ messageStatus = MessageStatus .READ
253
+ )
257
254
258
255
Spacer (Modifier .height(16 .dp))
259
256
@@ -266,13 +263,13 @@ fun ParticleAnimationSample() {
266
263
particleState2.startAnimation()
267
264
}
268
265
.disintegrate(
269
- progress = progress,
266
+ // progress = progress,
270
267
particleState = particleState2,
271
268
onStart = {
272
269
Toast .makeText(context, " Animation started..." , Toast .LENGTH_SHORT ).show()
273
270
},
274
271
onEnd = {
275
- // particleState2.animationStatus = AnimationStatus.Idle
272
+ particleState2.animationStatus = AnimationStatus .Idle
276
273
Toast .makeText(context, " Animation ended..." , Toast .LENGTH_SHORT ).show()
277
274
}
278
275
),
@@ -290,40 +287,6 @@ fun ParticleAnimationSample() {
290
287
}
291
288
}
292
289
293
- data class Particle (
294
- val initialCenter : Offset ,
295
- val initialSize : Size ,
296
- val endSize : Size ,
297
- val trajectoryProgressRange : ClosedRange <Float > = 0f ..1f ,
298
- var color : Color ,
299
- var velocity : Velocity = Velocity (0f, 0f),
300
- var acceleration : Float = 0f
301
- ) {
302
- var currentPosition: Offset = initialCenter
303
- internal set
304
- var currentSize: Size = initialSize
305
- internal set
306
- var alpha = 1f
307
- internal set
308
- var currentTime: Float = 0f
309
- internal set
310
- var trajectoryProgress: Float = 0f
311
- internal set
312
- }
313
-
314
- fun Modifier.disintegrate (
315
- particleState : ParticleState ,
316
- onStart : () -> Unit = {},
317
- onEnd : () -> Unit = {}
318
- ) = this .then(
319
- Modifier .disintegrate(
320
- progress = particleState.progress,
321
- particleState = particleState,
322
- onStart = onStart,
323
- onEnd = onEnd
324
- )
325
- )
326
-
327
290
fun Modifier.disintegrate (
328
291
progress : Float ,
329
292
particleState : ParticleState ,
@@ -356,6 +319,7 @@ fun Modifier.disintegrate(
356
319
} else particleState.bitmap
357
320
358
321
bitmap?.let {
322
+ particleState.bitmap = bitmap
359
323
particleState.createParticles(
360
324
particleList = particleState.particleList,
361
325
particleSize = particleSizePx,
@@ -393,6 +357,19 @@ fun Modifier.disintegrate(
393
357
}
394
358
}
395
359
360
+ fun Modifier.disintegrate (
361
+ particleState : ParticleState ,
362
+ onStart : () -> Unit = {},
363
+ onEnd : () -> Unit = {}
364
+ ) = this .then(
365
+ Modifier .disintegrate(
366
+ progress = particleState.progress,
367
+ particleState = particleState,
368
+ onStart = onStart,
369
+ onEnd = onEnd
370
+ )
371
+ )
372
+
396
373
@Composable
397
374
fun rememberParticleState (particleSize : Dp = 2.dp): ParticleState {
398
375
return remember {
@@ -444,7 +421,7 @@ class ParticleState internal constructor(particleSize: Dp) {
444
421
val position = particle.currentPosition
445
422
val alpha = particle.alpha
446
423
447
- // Destination
424
+ // Source
448
425
drawCircle(
449
426
color = color,
450
427
radius = radius,
@@ -453,17 +430,11 @@ class ParticleState internal constructor(particleSize: Dp) {
453
430
)
454
431
}
455
432
456
- clipRect(
457
- left = progress * size.width
458
- ) {
459
-
460
- // Source
461
- bitmap?.asImageBitmap()?.let {
462
- drawImage(
463
- image = it,
464
- blendMode = BlendMode .SrcOut
465
- )
466
- }
433
+ bitmap?.asImageBitmap()?.let {
434
+ drawImage(
435
+ image = it,
436
+ blendMode = BlendMode .SrcIn
437
+ )
467
438
}
468
439
469
440
// For debugging
@@ -540,7 +511,7 @@ class ParticleState internal constructor(particleSize: Dp) {
540
511
541
512
val velocityX = randomInRange(
542
513
// Particles close to end should have less randomization to start of image
543
- - (particleSize * 30f * (1 - fractionToImageWidth* . 7f ))
514
+ - (particleSize * 30f * (1 - fractionToImageWidth))
544
515
.coerceAtMost(imageMinDimension),
545
516
(particleSize * 30f ).coerceAtMost(imageMinDimension)
546
517
)
@@ -615,26 +586,6 @@ class ParticleState internal constructor(particleSize: Dp) {
615
586
}
616
587
}
617
588
618
- private fun Particle.setTrajectoryProgress (progress : Float ) {
619
- val trajectoryProgressStart = trajectoryProgressRange.start
620
- val trajectoryProgressEnd = trajectoryProgressRange.endInclusive
621
-
622
- trajectoryProgress =
623
- if (progress < trajectoryProgressStart) {
624
- 0f
625
- } else if (progress > trajectoryProgressEnd) {
626
- 1f
627
- } else {
628
- scale(
629
- a1 = trajectoryProgressStart,
630
- b1 = trajectoryProgressEnd,
631
- x1 = progress,
632
- a2 = 0f ,
633
- b2 = 1f
634
- )
635
- }
636
- }
637
-
638
589
fun startAnimation () {
639
590
animationStatus = AnimationStatus .Initializing
640
591
}
@@ -694,6 +645,72 @@ fun getTrajectoryRange(
694
645
return min.. max
695
646
}
696
647
648
+ /*
649
+ fun getTrajectoryRange(
650
+ fraction: Float,
651
+ sectionFraction: Float,
652
+ from: Float = 0f,
653
+ until: Float = 1f,
654
+ ): ClosedRange<Float> {
655
+
656
+ if (sectionFraction == 0f || sectionFraction > 1f) return from..until
657
+ val remainder = fraction % sectionFraction
658
+ val multiplier = fraction / sectionFraction
659
+
660
+ val min = (
661
+ (sectionFraction * (multiplier - 1) - remainder) + randomInRange(
662
+ -sectionFraction,
663
+ sectionFraction
664
+ )
665
+ ).coerceAtLeast(from)
666
+
667
+ val max = randomInRange(min + 5 * sectionFraction, until).coerceAtMost(until)
668
+
669
+ return min..max
670
+ }
671
+ */
672
+
673
+ private fun Particle.setTrajectoryProgress (progress : Float ) {
674
+ val trajectoryProgressStart = trajectoryProgressRange.start
675
+ val trajectoryProgressEnd = trajectoryProgressRange.endInclusive
676
+
677
+ trajectoryProgress =
678
+ if (progress < trajectoryProgressStart) {
679
+ 0f
680
+ } else if (progress > trajectoryProgressEnd) {
681
+ 1f
682
+ } else {
683
+ scale(
684
+ a1 = trajectoryProgressStart,
685
+ b1 = trajectoryProgressEnd,
686
+ x1 = progress,
687
+ a2 = 0f ,
688
+ b2 = 1f
689
+ )
690
+ }
691
+ }
692
+
693
+ data class Particle (
694
+ val initialCenter : Offset ,
695
+ val initialSize : Size ,
696
+ val endSize : Size ,
697
+ val trajectoryProgressRange : ClosedRange <Float > = 0f ..1f ,
698
+ var color : Color ,
699
+ var velocity : Velocity = Velocity (0f, 0f),
700
+ var acceleration : Float = 0f
701
+ ) {
702
+ var currentPosition: Offset = initialCenter
703
+ internal set
704
+ var currentSize: Size = initialSize
705
+ internal set
706
+ var alpha = 1f
707
+ internal set
708
+ var currentTime: Float = 0f
709
+ internal set
710
+ var trajectoryProgress: Float = 0f
711
+ internal set
712
+ }
713
+
697
714
enum class AnimationStatus {
698
715
Idle , Initializing , Playing
699
716
}
0 commit comments