Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6be9ae1

Browse files
update particle sample
1 parent c4edb49 commit 6be9ae1

File tree

1 file changed

+74
-58
lines changed

1 file changed

+74
-58
lines changed

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

Lines changed: 74 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.smarttoolfactory.tutorial1_1basics
33
import android.graphics.Bitmap
44
import android.widget.Toast
55
import androidx.compose.animation.core.Animatable
6+
import androidx.compose.animation.core.LinearEasing
67
import androidx.compose.animation.core.tween
78
import androidx.compose.foundation.Canvas
89
import androidx.compose.foundation.Image
@@ -29,6 +30,7 @@ import androidx.compose.runtime.mutableStateListOf
2930
import androidx.compose.runtime.mutableStateOf
3031
import androidx.compose.runtime.remember
3132
import androidx.compose.runtime.setValue
33+
import androidx.compose.ui.Alignment
3234
import androidx.compose.ui.Modifier
3335
import androidx.compose.ui.composed
3436
import androidx.compose.ui.draw.drawWithCache
@@ -38,13 +40,15 @@ import androidx.compose.ui.graphics.Color
3840
import androidx.compose.ui.graphics.ImageBitmap
3941
import androidx.compose.ui.graphics.asAndroidBitmap
4042
import androidx.compose.ui.graphics.asImageBitmap
43+
import androidx.compose.ui.graphics.drawscope.clipRect
4144
import androidx.compose.ui.graphics.rememberGraphicsLayer
4245
import androidx.compose.ui.platform.LocalContext
4346
import androidx.compose.ui.platform.LocalDensity
4447
import androidx.compose.ui.res.painterResource
4548
import androidx.compose.ui.tooling.preview.Preview
4649
import androidx.compose.ui.unit.dp
4750
import androidx.compose.ui.unit.sp
51+
import com.smarttoolfactory.tutorial1_1basics.chapter6_graphics.randomInRange
4852
import com.smarttoolfactory.tutorial1_1basics.chapter6_graphics.scale
4953
import com.smarttoolfactory.tutorial1_1basics.chapter6_graphics.toPx
5054
import com.smarttoolfactory.tutorial1_1basics.ui.Pink400
@@ -186,8 +190,9 @@ fun ParticleAnimationSample() {
186190
modifier = Modifier
187191
.fillMaxSize()
188192
.verticalScroll(rememberScrollState())
189-
.padding(horizontal = 16.dp, vertical = 32.dp),
190-
verticalArrangement = Arrangement.spacedBy(8.dp)
193+
.padding(horizontal = 16.dp, vertical = 100.dp),
194+
verticalArrangement = Arrangement.spacedBy(8.dp),
195+
horizontalAlignment = Alignment.CenterHorizontally
191196
) {
192197

193198
val density = LocalDensity.current
@@ -244,8 +249,8 @@ data class Particle(
244249
val endSize: Size,
245250
val color: Color,
246251
val trajectoryProgressRange: ClosedRange<Float> = 0f..1f,
247-
val velocity: Float = 4 * displacement.y,
248-
val acceleration: Float = -2 * velocity,
252+
var velocity: Float = 4 * displacement.y,
253+
var acceleration: Float = -2 * velocity,
249254
val column: Int,
250255
val row: Int
251256
) {
@@ -314,16 +319,14 @@ fun Modifier.explode(
314319

315320
if (animationStatus != AnimationStatus.Idle) {
316321

317-
// val progress = particleState.progress
322+
val animatedProgress = particleState.progress
318323

319324
particleState.particleList.forEach { particle ->
320325

321-
if (progress > 0 && progress <= 1f) {
322-
particleState.updateParticle(progress, particle)
323-
}
326+
particleState.updateParticle(animatedProgress, particle)
324327

325328
val color = particle.color
326-
val radius = particle.currentSize.width /2f
329+
val radius = particle.currentSize.width * .7f
327330
val position = particle.currentPosition
328331
val alpha = particle.alpha
329332

@@ -336,6 +339,12 @@ fun Modifier.explode(
336339
// alpha = alpha
337340
)
338341
}
342+
343+
// clipRect(
344+
// left = animatedProgress * size.width
345+
// ) {
346+
// this@onDrawWithContent.drawContent()
347+
// }
339348
}
340349
}
341350
}
@@ -352,7 +361,7 @@ fun rememberParticleState(): ParticleState {
352361
@Stable
353362
class ParticleState internal constructor() {
354363

355-
var particleSize by mutableStateOf(200.dp)
364+
var particleSize by mutableStateOf(2.dp)
356365

357366
val animatable = Animatable(0f)
358367
val particleList = mutableStateListOf<Particle>()
@@ -397,31 +406,34 @@ class ParticleState internal constructor() {
397406
val pixel: Int = bitmap.getPixel(pixelCenterX, pixelCenterY)
398407
val color = Color(pixel)
399408

400-
println(
401-
"Column: $column, " +
402-
"row: $row," +
403-
" pixelCenterX: $pixelCenterX, " +
404-
"pixelCenterY: $pixelCenterY, color: $color"
405-
)
409+
// println(
410+
// "Column: $column, " +
411+
// "row: $row," +
412+
// " pixelCenterX: $pixelCenterX, " +
413+
// "pixelCenterY: $pixelCenterY, color: $color"
414+
// )
406415

407416
if (color != Color.Unspecified) {
408417

409418
val initialCenter = Offset(pixelCenterX.toFloat(), pixelCenterY.toFloat())
410-
val horizontalDisplacement = width /2f
411-
val verticalDisplacement = height /2f
419+
val horizontalDisplacement = randomInRange(-50f, 50f)
420+
val verticalDisplacement = randomInRange(-height * .1f, height * .2f)
412421

413-
val velocity = 4 * verticalDisplacement
414-
val acceleration = -2 * velocity
422+
val velocity = verticalDisplacement
423+
val acceleration = randomInRange(-2f, 2f)
424+
val progressStart = (initialCenter.x / width).coerceAtMost(.7f)
425+
val progressEnd = progressStart + 0.3f
415426

416427
particleList.add(
417428
Particle(
418429
initialCenter = initialCenter,
419430
displacement = Offset(horizontalDisplacement, verticalDisplacement),
420431
initialSize = Size(particleSize.toFloat(), particleSize.toFloat()),
432+
// trajectoryProgressRange = progressStart..progressEnd,
421433
endSize = Size.Zero,
422434
color = color,
423-
column = column,
424-
row = row,
435+
column = column/ particleSize,
436+
row = row/ particleRadius,
425437
velocity = velocity,
426438
acceleration = acceleration
427439
)
@@ -432,12 +444,9 @@ class ParticleState internal constructor() {
432444
}
433445
}
434446
}
435-
436-
println("PARTICLE count: ${particleList.size}")
437-
438447
}
439448

440-
fun updateParticle(explosionProgress: Float, particle: Particle) {
449+
fun updateParticle(progress: Float, particle: Particle) {
441450

442451
particle.run {
443452
// Trajectory progress translates progress from 0f-1f to
@@ -449,58 +458,65 @@ class ParticleState internal constructor() {
449458
// Each 0.1f change in trajectoryProgress 0.5f total range
450459
// corresponds to 0.2f change of current time
451460

452-
val trajectoryProgressStart = trajectoryProgressRange.start
453-
val trajectoryProgressEnd = trajectoryProgressRange.endInclusive
454-
455-
val startXPosition = initialCenter.x
456-
val startYPosition = initialCenter.x
457-
458-
val maxHorizontalDisplacement = displacement.x
459-
460-
trajectoryProgress =
461-
if (explosionProgress < trajectoryProgressStart) {
462-
0f
463-
} else if (explosionProgress > trajectoryProgressEnd) {
464-
1f
465-
} else {
466-
scale(
467-
a1 = trajectoryProgressStart,
468-
b1 = trajectoryProgressEnd,
469-
x1 = explosionProgress,
470-
a2 = 0f,
471-
b2 = 1f
472-
)
473-
}
461+
setTrajectoryProgress(progress)
474462

475463
currentTime = trajectoryProgress
476-
// .mapInRange(0f, 1f, 0f, 1.4f)
464+
// .mapInRange(0f, 1f, 0f, 1.4f)
465+
466+
// Set size
467+
val width = initialSize.width + (endSize.width - initialSize.width) * currentTime
468+
val height = initialSize.height + (endSize.height - initialSize.height) * currentTime
469+
// currentSize = Size(width, height)
477470

471+
// Set alpha
478472
// While trajectory progress is less than 70% have full alpha then slowly cre
479-
// alpha = if (trajectoryProgress < .7f) 1f else
480-
// scale(.7f, 1f, trajectoryProgress, 1f, 0f)
473+
// alpha = if (trajectoryProgress == 0f) 0f
474+
// else if (trajectoryProgress < .7f) 1f
475+
// else scale(.7f, 1f, trajectoryProgress, 1f, 0f)
481476

482-
val horizontalDisplacement = maxHorizontalDisplacement * trajectoryProgress
477+
// Set position
478+
// acceleration = randomInRange(-5f, 5f)
479+
// velocity = 1f * Random.nextInt(10)
483480

481+
val maxHorizontalDisplacement = displacement.x
482+
val horizontalDisplacement = maxHorizontalDisplacement * trajectoryProgress
484483
val verticalDisplacement =
485484
velocity * currentTime + 0.5f * acceleration * currentTime * currentTime
486-
487-
println("horizontalDisplacement: $horizontalDisplacement, verticalDisplacement: $verticalDisplacement")
488-
489485
currentPosition = Offset(
490-
x = startXPosition + horizontalDisplacement,
491-
y = startYPosition - verticalDisplacement
486+
x = initialCenter.x + horizontalDisplacement,
487+
y = initialCenter.y - verticalDisplacement
492488
)
493489
}
494490
}
495491

492+
private fun Particle.setTrajectoryProgress(progress: Float) {
493+
val trajectoryProgressStart = trajectoryProgressRange.start
494+
val trajectoryProgressEnd = trajectoryProgressRange.endInclusive
495+
496+
trajectoryProgress =
497+
if (progress < trajectoryProgressStart) {
498+
0f
499+
} else if (progress > trajectoryProgressEnd) {
500+
1f
501+
} else {
502+
scale(
503+
a1 = trajectoryProgressStart,
504+
b1 = trajectoryProgressEnd,
505+
x1 = progress,
506+
a2 = 0f,
507+
b2 = 1f
508+
)
509+
}
510+
}
511+
496512
fun startAnimation() {
497513
animationStatus = AnimationStatus.Initializing
498514
}
499515

500516
suspend fun animate() {
501517
try {
502518
animatable.snapTo(0f)
503-
animatable.animateTo(1f, tween(2000))
519+
animatable.animateTo(1f, tween(durationMillis =2000, easing =LinearEasing))
504520
// animationStatus = AnimationStatus.Idle
505521
} catch (e: CancellationException) {
506522
println("FAILED: ${e.message}")

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /