Skip to content

Commit 0e89ea0

Browse files
move bitmap creation to another thread
1 parent 186f02b commit 0e89ea0

File tree

1 file changed

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

1 file changed

+75
-57
lines changed

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

Lines changed: 75 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.foundation.Canvas
99
import androidx.compose.foundation.Image
1010
import androidx.compose.foundation.background
1111
import androidx.compose.foundation.border
12+
import androidx.compose.foundation.clickable
1213
import androidx.compose.foundation.layout.Arrangement
1314
import androidx.compose.foundation.layout.Column
1415
import androidx.compose.foundation.layout.Spacer
@@ -63,6 +64,11 @@ import com.smarttoolfactory.tutorial1_1basics.chapter6_graphics.randomInRange
6364
import com.smarttoolfactory.tutorial1_1basics.chapter6_graphics.scale
6465
import com.smarttoolfactory.tutorial1_1basics.ui.Pink400
6566
import kotlinx.coroutines.CancellationException
67+
import kotlinx.coroutines.Dispatchers
68+
import kotlinx.coroutines.android.awaitFrame
69+
import kotlinx.coroutines.async
70+
import kotlinx.coroutines.delay
71+
import kotlinx.coroutines.withContext
6672
import kotlin.math.roundToInt
6773
import kotlin.random.Random
6874

@@ -227,24 +233,27 @@ fun ParticleAnimationSample() {
227233
mutableFloatStateOf(0f)
228234
}
229235

230-
231-
SentMessageRowAlt(
232-
modifier = Modifier.disintegrate(
233-
// progress = progress,
234-
particleState = particleState,
235-
onStart = {
236-
Toast.makeText(context, "Animation started...", Toast.LENGTH_SHORT).show()
237-
},
238-
onEnd = {
239-
particleState.animationStatus = AnimationStatus.Idle
240-
Toast.makeText(context, "Animation ended...", Toast.LENGTH_SHORT).show()
241-
}
242-
),
243-
quotedImage = R.drawable.avatar_4_raster,
244-
text = "Some long message",
245-
messageTime = "11.02.2024",
246-
messageStatus = MessageStatus.READ
247-
)
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+
// )
248257

249258
Spacer(Modifier.height(16.dp))
250259

@@ -253,14 +262,17 @@ fun ParticleAnimationSample() {
253262
modifier = Modifier
254263
.border(2.dp, Color.Red)
255264
.size(widthDp)
265+
.clickable {
266+
particleState2.startAnimation()
267+
}
256268
.disintegrate(
257-
// progress = progress,
269+
progress = progress,
258270
particleState = particleState2,
259271
onStart = {
260272
Toast.makeText(context, "Animation started...", Toast.LENGTH_SHORT).show()
261273
},
262274
onEnd = {
263-
particleState2.animationStatus = AnimationStatus.Idle
275+
// particleState2.animationStatus = AnimationStatus.Idle
264276
Toast.makeText(context, "Animation ended...", Toast.LENGTH_SHORT).show()
265277
}
266278
),
@@ -275,15 +287,6 @@ fun ParticleAnimationSample() {
275287
progress = it
276288
}
277289
)
278-
Button(
279-
modifier = Modifier.fillMaxWidth(),
280-
onClick = {
281-
particleState.startAnimation()
282-
particleState2.startAnimation()
283-
}
284-
) {
285-
Text("Convert graphicsLayer to particles")
286-
}
287290
}
288291
}
289292

@@ -337,28 +340,37 @@ fun Modifier.disintegrate(
337340
LaunchedEffect(animationStatus != AnimationStatus.Idle) {
338341
if (animationStatus != AnimationStatus.Idle) {
339342

340-
if (particleState.bitmap == null || particleState.bitmap?.isRecycled == true) {
341-
val bitmap = graphicsLayer
342-
.toImageBitmap()
343-
.asAndroidBitmap()
344-
.copy(Bitmap.Config.ARGB_8888, false)
345-
346-
bitmap.prepareToDraw()
347-
348-
particleState.bitmap = bitmap
343+
withContext(Dispatchers.Default) {
344+
val bitmap =
345+
if (particleState.bitmap == null || particleState.bitmap?.isRecycled == true) {
346+
347+
val bitmap = graphicsLayer
348+
.toImageBitmap()
349+
.asAndroidBitmap()
350+
.copy(Bitmap.Config.ARGB_8888, false)
351+
.apply {
352+
this.prepareToDraw()
353+
}
354+
bitmap
355+
356+
} else particleState.bitmap
357+
358+
bitmap?.let {
359+
particleState.createParticles(
360+
particleList = particleState.particleList,
361+
particleSize = particleSizePx,
362+
bitmap = bitmap
363+
)
349364

350-
particleState.createParticles(
351-
particleList = particleState.particleList,
352-
particleSize = particleSizePx,
353-
bitmap = bitmap
354-
)
365+
withContext(Dispatchers.Main) {
366+
particleState.animationStatus = AnimationStatus.Playing
367+
particleState.animate(
368+
onStart = onStart,
369+
onEnd = onEnd
370+
)
371+
}
372+
}
355373
}
356-
357-
particleState.animationStatus = AnimationStatus.Playing
358-
particleState.animate(
359-
onStart = onStart,
360-
onEnd = onEnd
361-
)
362374
}
363375
}
364376

@@ -370,19 +382,19 @@ fun Modifier.disintegrate(
370382
graphicsLayer.record {
371383
this@onDrawWithContent.drawContent()
372384
}
385+
} else {
386+
particleState.updateAndDrawParticles(
387+
drawScope = this,
388+
particleList = particleState.particleList,
389+
progress = progress
390+
)
373391
}
374-
375-
particleState.updateAndDrawParticles(
376-
drawScope = this,
377-
particleList = particleState.particleList,
378-
progress = progress
379-
)
380392
}
381393
}
382394
}
383395

384396
@Composable
385-
fun rememberParticleState(particleSize: Dp = 1.dp): ParticleState {
397+
fun rememberParticleState(particleSize: Dp = 2.dp): ParticleState {
386398
return remember {
387399
ParticleState(particleSize)
388400
}
@@ -405,6 +417,7 @@ class ParticleState internal constructor(particleSize: Dp) {
405417
var bitmap: Bitmap? = null
406418
internal set
407419

420+
408421
var animationSpec = tween<Float>(
409422
durationMillis = 2000,
410423
easing = FastOutSlowInEasing
@@ -431,6 +444,7 @@ class ParticleState internal constructor(particleSize: Dp) {
431444
val position = particle.currentPosition
432445
val alpha = particle.alpha
433446

447+
// Destination
434448
drawCircle(
435449
color = color,
436450
radius = radius,
@@ -442,10 +456,12 @@ class ParticleState internal constructor(particleSize: Dp) {
442456
clipRect(
443457
left = progress * size.width
444458
) {
459+
460+
// Source
445461
bitmap?.asImageBitmap()?.let {
446462
drawImage(
447463
image = it,
448-
blendMode = BlendMode.SrcIn
464+
blendMode = BlendMode.SrcOut
449465
)
450466
}
451467
}
@@ -467,6 +483,8 @@ class ParticleState internal constructor(particleSize: Dp) {
467483
particleSize: Int,
468484
bitmap: Bitmap
469485
) {
486+
487+
println("CREATE particles thread: ${Thread.currentThread().name}")
470488
particleList.clear()
471489

472490
val width = bitmap.width

0 commit comments

Comments
 (0)