@@ -386,15 +386,17 @@ fun rememberParticleState(
386
386
durationMillis = 2000,
387
387
easing = FastOutLinearInEasing
388
388
),
389
- strategy : ParticleStrategy = DisintegrateStrategy ()
389
+ strategy : ParticleStrategy = DisintegrateStrategy (),
390
+ particleBoundaries : ParticleBoundaries ? = null
390
391
): ParticleState {
391
392
return remember(
392
- // particleSize, strategy, animationSpec
393
+ // particleSize, strategy, animationSpec, particleBoundaries
393
394
) {
394
395
ParticleState (
395
396
particleSize = particleSize,
396
397
animationSpec = animationSpec,
397
- strategy = strategy
398
+ strategy = strategy,
399
+ particleBoundaries = particleBoundaries
398
400
)
399
401
}
400
402
}
@@ -404,6 +406,7 @@ class ParticleState internal constructor(
404
406
val particleSize : Dp ,
405
407
val animationSpec : AnimationSpec <Float >,
406
408
val strategy : ParticleStrategy ,
409
+ val particleBoundaries : ParticleBoundaries ? ,
407
410
) {
408
411
val animatable = Animatable (0f )
409
412
val particleList = mutableStateListOf<Particle >()
@@ -431,21 +434,34 @@ class ParticleState internal constructor(
431
434
) {
432
435
if (animationStatus != AnimationStatus .Idle ) {
433
436
bitmap?.let {
434
- strategy.updateAndDrawParticles(drawScope, particleList, bitmap, progress)
437
+ strategy.updateAndDrawParticles(
438
+ drawScope = drawScope,
439
+ particleList = particleList, imageBitmap = bitmap,
440
+ progress = progress,
441
+ particleBoundaries = particleBoundaries
442
+ )
435
443
}
436
444
}
437
445
}
438
446
439
447
fun createParticles (
440
448
particleList : SnapshotStateList <Particle >,
441
449
particleSize : Int ,
442
- bitmap : Bitmap
450
+ bitmap : Bitmap ,
443
451
) {
444
- strategy.createParticles(particleList, particleSize, bitmap)
452
+ strategy.createParticles(
453
+ particleList = particleList,
454
+ particleSize = particleSize,
455
+ bitmap = bitmap,
456
+ particleBoundaries = particleBoundaries
457
+ )
445
458
}
446
459
447
460
fun updateParticle (progress : Float , particle : Particle ) {
448
- strategy.updateParticle(progress, particle)
461
+ strategy.updateParticle(
462
+ progress = progress,
463
+ particle = particle
464
+ )
449
465
}
450
466
451
467
fun startAnimation () {
@@ -485,7 +501,8 @@ open class DisintegrateStrategy : ParticleStrategy {
485
501
override fun createParticles (
486
502
particleList : SnapshotStateList <Particle >,
487
503
particleSize : Int ,
488
- bitmap : Bitmap
504
+ bitmap : Bitmap ,
505
+ particleBoundaries : ParticleBoundaries ?
489
506
) {
490
507
491
508
particleList.clear()
@@ -542,24 +559,56 @@ open class DisintegrateStrategy : ParticleStrategy {
542
559
543
560
val imageMinDimension = width.coerceAtMost(height) * 1f
544
561
562
+ val velocityHorizontalMin =
563
+ particleBoundaries?.velocityLowerBound?.x ? : (particleSize * 20f )
564
+ val velocityHorizontalMax =
565
+ particleBoundaries?.velocityUpperBound?.x ? : (particleSize * 20f )
566
+
567
+ val velocityVerticalMin =
568
+ particleBoundaries?.velocityLowerBound?.y ? : (particleSize * 30f )
569
+ val velocityVerticalMax =
570
+ particleBoundaries?.velocityUpperBound?.y ? : (particleSize * 30f )
571
+
545
572
val velocityX = randomInRange(
546
573
// Particles close to end should have less randomization to start of image
547
- - (particleSize * 20f * (1 - fractionToImageWidth))
574
+ - (velocityHorizontalMin * (1 - fractionToImageWidth))
548
575
.coerceAtMost(imageMinDimension),
549
- (particleSize * 20f ).coerceAtMost(imageMinDimension)
576
+ (velocityHorizontalMax ).coerceAtMost(imageMinDimension)
550
577
)
551
578
val velocityY = randomInRange(
552
- - (particleSize * 30f ).coerceAtMost(imageMinDimension),
553
- (particleSize * 30f ).coerceAtMost(imageMinDimension)
579
+ - (velocityVerticalMin ).coerceAtMost(imageMinDimension),
580
+ (velocityVerticalMax ).coerceAtMost(imageMinDimension)
554
581
)
555
582
556
- val acceleration =
557
- Acceleration (0f , randomInRange(- velocityY * .1f , - velocityY * .2f ))
583
+ val accelerationHorizontalMin =
584
+ particleBoundaries?.accelerationLowerBound?.x ? : 0f
585
+ val accelerationHorizontalMax =
586
+ particleBoundaries?.accelerationLowerBound?.x ? : 0f
587
+
588
+ val accelerationVerticalMin =
589
+ particleBoundaries?.accelerationLowerBound?.y ? : (- velocityY * .1f )
590
+ val accelerationVerticalMax =
591
+ particleBoundaries?.accelerationLowerBound?.y ? : (- velocityY * .2f )
558
592
593
+ val acceleration = Acceleration (
594
+ randomInRange(accelerationHorizontalMin, accelerationHorizontalMax),
595
+ randomInRange(accelerationVerticalMin, accelerationVerticalMax)
596
+ )
597
+
598
+ // TODO Add boundaries for size
559
599
// Set initial and final sizes
560
600
val initialSize = Size (particleSize.toFloat(), particleSize.toFloat())
561
601
val endSize = randomInRange(.4f , particleSize.toFloat() * .7f )
562
602
603
+ // Set alpha
604
+ val alphaStartMin = (particleBoundaries?.alphaLowerBound?.start) ? : 1f
605
+ val alphaStartMax = (particleBoundaries?.alphaLowerBound?.endInclusive) ? : 1f
606
+ val alphaStart = randomInRange(alphaStartMin, alphaStartMax)
607
+
608
+ val alphaEndMin = (particleBoundaries?.alphaLowerBound?.start) ? : 0f
609
+ val alphaEndMax = (particleBoundaries?.alphaLowerBound?.endInclusive) ? : 0f
610
+ val alphaEnd = randomInRange(alphaEndMin, alphaEndMax)
611
+
563
612
particleList.add(
564
613
Particle (
565
614
initialCenter = initialCenter,
@@ -571,7 +620,9 @@ open class DisintegrateStrategy : ParticleStrategy {
571
620
x = velocityX,
572
621
y = velocityY
573
622
),
574
- acceleration = acceleration
623
+ acceleration = acceleration,
624
+ initialAlpha = alphaStart,
625
+ endAlpha = alphaEnd
575
626
)
576
627
)
577
628
@@ -587,12 +638,16 @@ open class DisintegrateStrategy : ParticleStrategy {
587
638
particleList : SnapshotStateList <Particle >,
588
639
imageBitmap : ImageBitmap ,
589
640
progress : Float ,
641
+ particleBoundaries : ParticleBoundaries ?
590
642
) {
591
643
with (drawScope) {
592
644
593
645
drawWithLayer {
594
646
particleList.forEach { particle ->
595
- updateParticle(progress, particle)
647
+ updateParticle(
648
+ progress = progress,
649
+ particle = particle
650
+ )
596
651
597
652
val color = particle.color
598
653
val radius = particle.currentSize.width * .5f
@@ -628,7 +683,10 @@ open class DisintegrateStrategy : ParticleStrategy {
628
683
}
629
684
}
630
685
631
- override fun updateParticle (progress : Float , particle : Particle ) {
686
+ override fun updateParticle (
687
+ progress : Float ,
688
+ particle : Particle
689
+ ) {
632
690
particle.run {
633
691
// Trajectory progress translates progress from 0f-1f to
634
692
// trajectoryStart-trajectoryEnd
@@ -653,7 +711,7 @@ open class DisintegrateStrategy : ParticleStrategy {
653
711
// reduce to zero for particles to disappear
654
712
alpha = if (trajectoryProgress == 0f ) 0f
655
713
else if (trajectoryProgress < .4f ) 1f
656
- else scale(.4f , 1f , trajectoryProgress, 1f , 0f )
714
+ else scale(.4f , 1f , trajectoryProgress, particle.initialAlpha, particle.endAlpha )
657
715
658
716
// Set position
659
717
val horizontalDisplacement =
@@ -687,17 +745,22 @@ interface ParticleStrategy {
687
745
fun createParticles (
688
746
particleList : SnapshotStateList <Particle >,
689
747
particleSize : Int ,
690
- bitmap : Bitmap
748
+ bitmap : Bitmap ,
749
+ particleBoundaries : ParticleBoundaries ?
691
750
)
692
751
693
752
fun updateAndDrawParticles (
694
753
drawScope : DrawScope ,
695
754
particleList : SnapshotStateList <Particle >,
696
755
imageBitmap : ImageBitmap ,
697
- progress : Float
756
+ progress : Float ,
757
+ particleBoundaries : ParticleBoundaries ?
698
758
)
699
759
700
- fun updateParticle (progress : Float , particle : Particle )
760
+ fun updateParticle (
761
+ progress : Float ,
762
+ particle : Particle
763
+ )
701
764
}
702
765
703
766
/* *
@@ -748,6 +811,8 @@ data class Particle(
748
811
val initialSize : Size ,
749
812
val endSize : Size ,
750
813
val trajectoryProgressRange : ClosedRange <Float > = 0f ..1f ,
814
+ val initialAlpha : Float = 1f ,
815
+ val endAlpha : Float = 0f ,
751
816
var color : Color ,
752
817
var velocity : Velocity = Velocity (0f, 0f),
753
818
var acceleration : Acceleration = Acceleration (0f, 0f)
@@ -798,16 +863,4 @@ value class Acceleration internal constructor(private val packedValue: Long) {
798
863
*/
799
864
@Stable
800
865
val y: Float get() = unpackFloat2(packedValue)
801
-
802
- /* *
803
- * The horizontal component of the velocity in pixels per second.
804
- */
805
- @Stable
806
- inline operator fun component1 (): Float = x
807
-
808
- /* *
809
- * The vertical component of the velocity in pixels per second.
810
- */
811
- @Stable
812
- inline operator fun component2 (): Float = y
813
866
}
0 commit comments