From 18d1fbcb7dba7516823a8a212ad2ed0f8b38eaf4 Mon Sep 17 00:00:00 2001 From: lavafrai Date: Thu, 12 Dec 2024 23:00:59 +0300 Subject: [PATCH 1/9] feat: snowflakes fading --- README.md | 1 + .../github/skeptick/snowfall/sample/RootView.kt | 15 +++++++++++++++ .../github/skeptick/snowfall/compose/Snowfall.kt | 13 ++++++++++++- .../snowfall/compose/internal/SnowfallState.kt | 16 +++++++++------- .../snowfall/compose/internal/SnowflakeState.kt | 6 +++++- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 190276c..937e980 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Box( .snowfall( color = Color.White, alpha = 0.3f, + fading = 3f, strokeWidth = 1f, drawPosition = SnowfallDrawPosition.Ahead, snowflakeMinSize = 10.dp, diff --git a/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt b/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt index 7a4a135..adb75de 100644 --- a/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt +++ b/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt @@ -49,6 +49,7 @@ import io.github.skeptick.snowfall.compose.snowfall fun RootView() { var color by remember { mutableStateOf(Color.White) } var alpha by remember { mutableFloatStateOf(0.5f) } + var fading by remember { mutableFloatStateOf(3f) } var strokeWidth by remember { mutableFloatStateOf(1f) } var drawPosition by remember { mutableStateOf(SnowfallDrawPosition.Ahead) } var snowflakeMinSize by remember { mutableStateOf(10.dp) } @@ -63,6 +64,7 @@ fun RootView() { modifier = modifier, color = color, alpha = alpha, + fading = fading, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakeMinSize = snowflakeMinSize, @@ -80,6 +82,7 @@ fun RootView() { modifier = modifier, color = color, alpha = alpha, + fading = fading, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakeMinSize = snowflakeMinSize, @@ -89,6 +92,7 @@ fun RootView() { snowflakeDensity = snowflakeDensity, onColorChange = { color = it }, onAlphaChange = { alpha = it }, + onFadingChange = { fading = it }, onStrokeChange = { strokeWidth = it }, onDrawPositionChange = { drawPosition = it }, onSnowflakeSizeChange = { min, max -> @@ -133,6 +137,7 @@ fun RootView() { private fun Preview( color: Color, alpha: Float, + fading: Float, strokeWidth: Float, drawPosition: SnowfallDrawPosition, snowflakeMinSize: Dp, @@ -148,6 +153,7 @@ private fun Preview( .snowfall( color = color, alpha = alpha, + fading = fading, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakeMinSize = snowflakeMinSize, @@ -172,6 +178,7 @@ private fun Preview( private fun Settings( color: Color, alpha: Float, + fading: Float, strokeWidth: Float, drawPosition: SnowfallDrawPosition, snowflakeMinSize: Dp, @@ -181,6 +188,7 @@ private fun Settings( snowflakeDensity: Float, onColorChange: (Color) -> Unit, onAlphaChange: (Float) -> Unit, + onFadingChange: (Float) -> Unit, onStrokeChange: (Float) -> Unit, onDrawPositionChange: (SnowfallDrawPosition) -> Unit, onSnowflakeSizeChange: (Dp, Dp) -> Unit, @@ -207,6 +215,13 @@ private fun Settings( onValueChange = onAlphaChange ) + SliderSelector( + title = "Fading", + selectedValue = fading, + valueRange = 0f..10f, + onValueChange = onFadingChange + ) + SliderSelector( title = "Stroke Width", selectedValue = strokeWidth, diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt index b6dab7f..90869b1 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt @@ -34,6 +34,7 @@ import io.github.skeptick.snowfall.compose.internal.pathSizes import io.github.skeptick.snowfall.compose.internal.times import kotlinx.coroutines.launch import kotlin.math.cos +import kotlin.math.pow import kotlin.math.roundToInt import kotlin.math.sin import kotlin.random.Random @@ -47,6 +48,7 @@ public enum class SnowfallDrawPosition { public fun Modifier.snowfall( color: Color = Color.White, alpha: Float = 0.3f, + fading: Float = 3f, strokeWidth: Float = 1f, drawPosition: SnowfallDrawPosition = SnowfallDrawPosition.Ahead, snowflakes: List = DefaultSnowflakes, @@ -59,6 +61,7 @@ public fun Modifier.snowfall( this then SnowfallElement( color = color, alpha = alpha, + fading = fading, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakes = snowflakes, @@ -77,6 +80,7 @@ public fun Modifier.snowfall( private data class SnowfallElement( val color: Color, val alpha: Float, + val fading: Float, val strokeWidth: Float, val drawPosition: SnowfallDrawPosition, val snowflakes: List, @@ -92,6 +96,7 @@ private data class SnowfallElement( return Snowfall( color = color, alpha = alpha, + fading = fading, stroke = Stroke(strokeWidth), drawPosition = drawPosition, snowflakes = ArrayList(snowflakes), @@ -111,6 +116,7 @@ private data class SnowfallElement( val speedInvalidationRequired = speedInvalidationRequired(node) node.color = color node.alpha = alpha + node.fading = fading node.stroke = Stroke(strokeWidth) node.drawPosition = drawPosition node.snowflakes = ArrayList(snowflakes) @@ -150,6 +156,7 @@ private data class SnowfallElement( private class Snowfall( var color: Color, var alpha: Float, + var fading: Float, var stroke: Stroke, var drawPosition: SnowfallDrawPosition, var snowflakes: List, @@ -196,7 +203,7 @@ private class Snowfall( scale(scale, offset) translate(offset.x, offset.y) }) { - drawPath(path, color, alpha, stroke) + drawPath(path, color, (alpha * flake.alpha), stroke) } } } @@ -245,6 +252,9 @@ private class Snowfall( x = (x + speed * cos(angle)).coerceIn(-flakeSize, canvasSize.width + flakeSize) y = (y + speed * sin(angle)).coerceIn(-canvasSize.height, canvasSize.height + flakeSize) angle += Random.nextFloat() * AddableAngleRange + + val yPos = 1 - (y / canvasSize.height) + alpha = yPos.pow(fading) /* TODO */ if (y == canvasSize.height + flakeSize) recycle(index) } @@ -253,6 +263,7 @@ private class Snowfall( scaleRatio = Random.nextFloat() speedRatio = Random.nextFloat() angle = Random.nextFloat() * SourceAngleRange + alpha = 1f scale = scaleRatio * snowflakeSize / pathSize speed = speedRatio * snowflakeSpeed x = Random.nextFloat() * canvasSize.width diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowfallState.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowfallState.kt index c47613f..159c0c9 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowfallState.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowfallState.kt @@ -11,10 +11,11 @@ internal class SnowfallState( ) { companion object StateSaver : Saver by listSaver( save = { state -> - buildList(state.snowflakes.size * 7) { + buildList(state.snowflakes.size * 8) { state.snowflakes.fastForEach { snowflake -> add(snowflake.x) add(snowflake.y) + add(snowflake.alphaOffset) add(snowflake.angle) add(snowflake.scale) add(snowflake.speed) @@ -25,15 +26,16 @@ internal class SnowfallState( }, restore = { list: List -> SnowfallState( - snowflakes = List((list.size) / 7) { index -> + snowflakes = List((list.size) / 8) { index -> SnowflakeState( x = list[index * 7 + 0], y = list[index * 7 + 1], - angle = list[index * 7 + 2], - scale = list[index * 7 + 3], - speed = list[index * 7 + 4], - scaleRatio = list[index * 7 + 5], - speedRatio = list[index * 7 + 6], + alphaOffset = list[index * 7 + 2], + angle = list[index * 7 + 3], + scale = list[index * 7 + 4], + speed = list[index * 7 + 5], + scaleRatio = list[index * 7 + 6], + speedRatio = list[index * 7 + 7], ) } ) diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt index 0773915..f92edca 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt @@ -11,6 +11,7 @@ import kotlin.random.Random internal class SnowflakeState( x: Float, y: Float, + alphaOffset: Float, angle: Float, scale: Float, speed: Float, @@ -19,6 +20,8 @@ internal class SnowflakeState( ) { var x by mutableFloatStateOf(x) var y by mutableFloatStateOf(y) + var alpha by mutableFloatStateOf(1f) + var alphaOffset by mutableFloatStateOf(alphaOffset) var angle by mutableFloatStateOf(angle) var scale by mutableFloatStateOf(scale) var speed by mutableFloatStateOf(speed) @@ -28,13 +31,14 @@ internal fun SnowflakeState( canvasSize: Size, pathSize: Float, size: ClosedRange, - speed: ClosedRange + speed: ClosedRange, ): SnowflakeState { val scaleRatio = Random.nextFloat() val speedRatio = Random.nextFloat() return SnowflakeState( x = Random.nextFloat() * canvasSize.width, y = Random.nextFloat() * canvasSize.height * -1f, + alphaOffset = Random.nextFloat() + 0.5f, angle = Random.nextFloat() * SourceAngleRange, scale = scaleRatio * size / pathSize, speed = speedRatio * speed, From b912dd353946b7642a5bc42f6fcaea519de770fd Mon Sep 17 00:00:00 2001 From: lavafrai Date: Thu, 12 Dec 2024 23:02:21 +0300 Subject: [PATCH 2/9] fix: todo removed --- .../kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt index 90869b1..aafaf39 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt @@ -254,7 +254,7 @@ private class Snowfall( angle += Random.nextFloat() * AddableAngleRange val yPos = 1 - (y / canvasSize.height) - alpha = yPos.pow(fading) /* TODO */ + alpha = yPos.pow(fading) if (y == canvasSize.height + flakeSize) recycle(index) } From 148b4cd9d34d75e689f37f62b560104d68504652 Mon Sep 17 00:00:00 2001 From: lavafrai Date: Thu, 12 Dec 2024 23:28:53 +0300 Subject: [PATCH 3/9] feat: randomness of fading --- .../kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt | 2 +- .../github/skeptick/snowfall/compose/internal/SnowflakeState.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt index aafaf39..b990952 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt @@ -253,7 +253,7 @@ private class Snowfall( y = (y + speed * sin(angle)).coerceIn(-canvasSize.height, canvasSize.height + flakeSize) angle += Random.nextFloat() * AddableAngleRange - val yPos = 1 - (y / canvasSize.height) + val yPos = 1 - (y / canvasSize.height) + alphaOffset alpha = yPos.pow(fading) if (y == canvasSize.height + flakeSize) recycle(index) } diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt index f92edca..d466604 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt @@ -38,7 +38,7 @@ internal fun SnowflakeState( return SnowflakeState( x = Random.nextFloat() * canvasSize.width, y = Random.nextFloat() * canvasSize.height * -1f, - alphaOffset = Random.nextFloat() + 0.5f, + alphaOffset = Random.nextFloat() * 0.2f - 0.1f, angle = Random.nextFloat() * SourceAngleRange, scale = scaleRatio * size / pathSize, speed = speedRatio * speed, From 07cffdaf5d7c7f56d2ed3a4cd82a6220c700dc0c Mon Sep 17 00:00:00 2001 From: lavafrai Date: Fri, 13 Dec 2024 02:31:52 +0300 Subject: [PATCH 4/9] feat: fade threshold and fade threshold spread --- .../skeptick/snowfall/sample/RootView.kt | 39 +++++++++++++------ .../skeptick/snowfall/compose/Snowfall.kt | 28 ++++++++----- .../compose/internal/SnowflakeState.kt | 2 +- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt b/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt index adb75de..954b15a 100644 --- a/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt +++ b/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt @@ -49,7 +49,8 @@ import io.github.skeptick.snowfall.compose.snowfall fun RootView() { var color by remember { mutableStateOf(Color.White) } var alpha by remember { mutableFloatStateOf(0.5f) } - var fading by remember { mutableFloatStateOf(3f) } + var fadeThreshold by remember { mutableFloatStateOf(1f) } + var fadeThresholdSpread by remember { mutableFloatStateOf(0f) } var strokeWidth by remember { mutableFloatStateOf(1f) } var drawPosition by remember { mutableStateOf(SnowfallDrawPosition.Ahead) } var snowflakeMinSize by remember { mutableStateOf(10.dp) } @@ -64,7 +65,8 @@ fun RootView() { modifier = modifier, color = color, alpha = alpha, - fading = fading, + fadeThreshold = fadeThreshold, + fadeThresholdSpread = fadeThresholdSpread, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakeMinSize = snowflakeMinSize, @@ -82,7 +84,8 @@ fun RootView() { modifier = modifier, color = color, alpha = alpha, - fading = fading, + fadeThreshold = fadeThreshold, + fadeThresholdSpread = fadeThresholdSpread, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakeMinSize = snowflakeMinSize, @@ -92,7 +95,8 @@ fun RootView() { snowflakeDensity = snowflakeDensity, onColorChange = { color = it }, onAlphaChange = { alpha = it }, - onFadingChange = { fading = it }, + onFadeThresholdChange = { fadeThreshold = it }, + onFadeThresholdSpreadChange = { fadeThresholdSpread = it }, onStrokeChange = { strokeWidth = it }, onDrawPositionChange = { drawPosition = it }, onSnowflakeSizeChange = { min, max -> @@ -137,7 +141,8 @@ fun RootView() { private fun Preview( color: Color, alpha: Float, - fading: Float, + fadeThreshold: Float, + fadeThresholdSpread: Float, strokeWidth: Float, drawPosition: SnowfallDrawPosition, snowflakeMinSize: Dp, @@ -153,7 +158,8 @@ private fun Preview( .snowfall( color = color, alpha = alpha, - fading = fading, + fadeThreshold = fadeThreshold, + fadeThresholdSpread = fadeThresholdSpread, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakeMinSize = snowflakeMinSize, @@ -178,7 +184,8 @@ private fun Preview( private fun Settings( color: Color, alpha: Float, - fading: Float, + fadeThreshold: Float, + fadeThresholdSpread: Float, strokeWidth: Float, drawPosition: SnowfallDrawPosition, snowflakeMinSize: Dp, @@ -188,7 +195,8 @@ private fun Settings( snowflakeDensity: Float, onColorChange: (Color) -> Unit, onAlphaChange: (Float) -> Unit, - onFadingChange: (Float) -> Unit, + onFadeThresholdChange: (Float) -> Unit, + onFadeThresholdSpreadChange: (Float) -> Unit, onStrokeChange: (Float) -> Unit, onDrawPositionChange: (SnowfallDrawPosition) -> Unit, onSnowflakeSizeChange: (Dp, Dp) -> Unit, @@ -216,10 +224,17 @@ private fun Settings( ) SliderSelector( - title = "Fading", - selectedValue = fading, - valueRange = 0f..10f, - onValueChange = onFadingChange + title = "Fade threshold", + selectedValue = fadeThreshold, + valueRange = 0f..1f, + onValueChange = onFadeThresholdChange + ) + + SliderSelector( + title = "Fade threshold spread", + selectedValue = fadeThresholdSpread, + valueRange = 0f..1f, + onValueChange = onFadeThresholdSpreadChange ) SliderSelector( diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt index b990952..0631555 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt @@ -34,7 +34,6 @@ import io.github.skeptick.snowfall.compose.internal.pathSizes import io.github.skeptick.snowfall.compose.internal.times import kotlinx.coroutines.launch import kotlin.math.cos -import kotlin.math.pow import kotlin.math.roundToInt import kotlin.math.sin import kotlin.random.Random @@ -48,7 +47,8 @@ public enum class SnowfallDrawPosition { public fun Modifier.snowfall( color: Color = Color.White, alpha: Float = 0.3f, - fading: Float = 3f, + fadeThreshold: Float = 1f, + fadeThresholdSpread: Float = 0f, strokeWidth: Float = 1f, drawPosition: SnowfallDrawPosition = SnowfallDrawPosition.Ahead, snowflakes: List = DefaultSnowflakes, @@ -61,7 +61,8 @@ public fun Modifier.snowfall( this then SnowfallElement( color = color, alpha = alpha, - fading = fading, + fadeThreshold = fadeThreshold, + fadeThresholdSpread = fadeThresholdSpread, strokeWidth = strokeWidth, drawPosition = drawPosition, snowflakes = snowflakes, @@ -80,7 +81,8 @@ public fun Modifier.snowfall( private data class SnowfallElement( val color: Color, val alpha: Float, - val fading: Float, + val fadeThreshold: Float, + val fadeThresholdSpread: Float, val strokeWidth: Float, val drawPosition: SnowfallDrawPosition, val snowflakes: List, @@ -96,7 +98,8 @@ private data class SnowfallElement( return Snowfall( color = color, alpha = alpha, - fading = fading, + fadeThreshold = fadeThreshold, + fadeThresholdSpread = fadeThresholdSpread, stroke = Stroke(strokeWidth), drawPosition = drawPosition, snowflakes = ArrayList(snowflakes), @@ -116,7 +119,8 @@ private data class SnowfallElement( val speedInvalidationRequired = speedInvalidationRequired(node) node.color = color node.alpha = alpha - node.fading = fading + node.fadeThreshold = fadeThreshold + node.fadeThresholdSpread = fadeThresholdSpread node.stroke = Stroke(strokeWidth) node.drawPosition = drawPosition node.snowflakes = ArrayList(snowflakes) @@ -156,7 +160,8 @@ private data class SnowfallElement( private class Snowfall( var color: Color, var alpha: Float, - var fading: Float, + var fadeThreshold: Float, + var fadeThresholdSpread: Float, var stroke: Stroke, var drawPosition: SnowfallDrawPosition, var snowflakes: List, @@ -253,8 +258,13 @@ private class Snowfall( y = (y + speed * sin(angle)).coerceIn(-canvasSize.height, canvasSize.height + flakeSize) angle += Random.nextFloat() * AddableAngleRange - val yPos = 1 - (y / canvasSize.height) + alphaOffset - alpha = yPos.pow(fading) + val yPos = (y / canvasSize.height) + // alpha = yPos.pow(fading) + alpha = when { + yPos < fadeThreshold -> 1f + yPos > (fadeThreshold + fadeThresholdSpread) -> 0f + else -> 1 - (yPos - fadeThreshold) / (fadeThresholdSpread) - alphaOffset + } if (y == canvasSize.height + flakeSize) recycle(index) } diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt index d466604..90587fd 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt @@ -38,7 +38,7 @@ internal fun SnowflakeState( return SnowflakeState( x = Random.nextFloat() * canvasSize.width, y = Random.nextFloat() * canvasSize.height * -1f, - alphaOffset = Random.nextFloat() * 0.2f - 0.1f, + alphaOffset = Random.nextFloat() * 0.5f, angle = Random.nextFloat() * SourceAngleRange, scale = scaleRatio * size / pathSize, speed = speedRatio * speed, From 6fcb17d2790874a9cf2e24d7634883ad99de6980 Mon Sep 17 00:00:00 2001 From: lavafrai Date: Fri, 13 Dec 2024 02:36:16 +0300 Subject: [PATCH 5/9] fix: readme and sample adapted to new fadeThreshold and fadeThresholdSpread --- README.md | 3 ++- .../kotlin/io/github/skeptick/snowfall/sample/RootView.kt | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 937e980..80761a9 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ Box( .snowfall( color = Color.White, alpha = 0.3f, - fading = 3f, + fadeThreshold = 0.6f, + fadeThresholdSpread = 0.3f, strokeWidth = 1f, drawPosition = SnowfallDrawPosition.Ahead, snowflakeMinSize = 10.dp, diff --git a/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt b/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt index 954b15a..2f84d3b 100644 --- a/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt +++ b/sample/src/commonMain/kotlin/io/github/skeptick/snowfall/sample/RootView.kt @@ -49,8 +49,8 @@ import io.github.skeptick.snowfall.compose.snowfall fun RootView() { var color by remember { mutableStateOf(Color.White) } var alpha by remember { mutableFloatStateOf(0.5f) } - var fadeThreshold by remember { mutableFloatStateOf(1f) } - var fadeThresholdSpread by remember { mutableFloatStateOf(0f) } + var fadeThreshold by remember { mutableFloatStateOf(0.6f) } + var fadeThresholdSpread by remember { mutableFloatStateOf(0.3f) } var strokeWidth by remember { mutableFloatStateOf(1f) } var drawPosition by remember { mutableStateOf(SnowfallDrawPosition.Ahead) } var snowflakeMinSize by remember { mutableStateOf(10.dp) } From 355f6b8e5d084b4733748d5c21221bdf1e655d0c Mon Sep 17 00:00:00 2001 From: lavafrai Date: Fri, 13 Dec 2024 21:08:16 +0300 Subject: [PATCH 6/9] fix: Suddenly snowflakes transparency changing solved --- .../kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt | 4 ++-- .../skeptick/snowfall/compose/internal/SnowflakeState.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt index 0631555..7a5d80e 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt @@ -259,11 +259,11 @@ private class Snowfall( angle += Random.nextFloat() * AddableAngleRange val yPos = (y / canvasSize.height) - // alpha = yPos.pow(fading) + alpha = when { yPos < fadeThreshold -> 1f yPos > (fadeThreshold + fadeThresholdSpread) -> 0f - else -> 1 - (yPos - fadeThreshold) / (fadeThresholdSpread) - alphaOffset + else -> 1 - (yPos - fadeThreshold) / (fadeThresholdSpread * alphaOffset)// - alphaOffset } if (y == canvasSize.height + flakeSize) recycle(index) } diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt index 90587fd..dd5a91c 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt @@ -38,7 +38,7 @@ internal fun SnowflakeState( return SnowflakeState( x = Random.nextFloat() * canvasSize.width, y = Random.nextFloat() * canvasSize.height * -1f, - alphaOffset = Random.nextFloat() * 0.5f, + alphaOffset = Random.nextFloat() * 0.5f + 0.5f, angle = Random.nextFloat() * SourceAngleRange, scale = scaleRatio * size / pathSize, speed = speedRatio * speed, From 135657e052dd9fafe36c65a1c4992af7bd9f6db7 Mon Sep 17 00:00:00 2001 From: lavafrai Date: Sun, 29 Dec 2024 22:38:24 +0300 Subject: [PATCH 7/9] fix: snowflakes alpha coerced to range from 0 to 1 --- .../kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt index 7a5d80e..19b1e05 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt @@ -263,7 +263,7 @@ private class Snowfall( alpha = when { yPos < fadeThreshold -> 1f yPos > (fadeThreshold + fadeThresholdSpread) -> 0f - else -> 1 - (yPos - fadeThreshold) / (fadeThresholdSpread * alphaOffset)// - alphaOffset + else -> (1 - (yPos - fadeThreshold) / (fadeThresholdSpread * alphaOffset)).coerceIn(0f, 1f) } if (y == canvasSize.height + flakeSize) recycle(index) } From c3ac89b7afb46fb8fe145d24cd77c620d63adefd Mon Sep 17 00:00:00 2001 From: lavafrai Date: Sun, 29 Dec 2024 22:41:44 +0300 Subject: [PATCH 8/9] fix: AlphaOffsetRange isolated as a separate constant --- .../io/github/skeptick/snowfall/compose/internal/Extensions.kt | 1 + .../github/skeptick/snowfall/compose/internal/SnowflakeState.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/Extensions.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/Extensions.kt index 5ba7475..8942041 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/Extensions.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/Extensions.kt @@ -3,6 +3,7 @@ package io.github.skeptick.snowfall.compose.internal import androidx.compose.ui.graphics.Path internal val SourceAngleRange = 1.45f..1.55f +internal val AlphaOffsetRange = 0.5f..1f internal val AddableAngleRange = -0.0025f..0.0025f internal operator fun Float.times(range: ClosedRange) = diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt index dd5a91c..efaa6a0 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/internal/SnowflakeState.kt @@ -38,7 +38,7 @@ internal fun SnowflakeState( return SnowflakeState( x = Random.nextFloat() * canvasSize.width, y = Random.nextFloat() * canvasSize.height * -1f, - alphaOffset = Random.nextFloat() * 0.5f + 0.5f, + alphaOffset = Random.nextFloat() * AlphaOffsetRange, angle = Random.nextFloat() * SourceAngleRange, scale = scaleRatio * size / pathSize, speed = speedRatio * speed, From 77788b9a196c732d189737d86b9e7bfef33e6db0 Mon Sep 17 00:00:00 2001 From: lavafrai Date: Sun, 29 Dec 2024 22:49:40 +0300 Subject: [PATCH 9/9] fix: clipRect applied to clip snowfalls getting out of canvas --- .../io/github/skeptick/snowfall/compose/Snowfall.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt index 19b1e05..32944fc 100644 --- a/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt +++ b/snowfall-compose/src/commonMain/kotlin/io/github/skeptick/snowfall/compose/Snowfall.kt @@ -106,7 +106,8 @@ private data class SnowfallElement( snowflakeSize = snowflakeMinSize..snowflakeMaxSize, snowflakeSpeed = snowflakeMinSpeed..snowflakeMaxSpeed, snowflakeDensity = snowflakeDensity, - snowfallState = snowfallState + snowfallState = snowfallState, + ) } @@ -169,7 +170,7 @@ private class Snowfall( var snowflakeSpeed: ClosedRange, var snowflakeDensity: Float, var snowfallState: SnowfallState, - var pathSizes: FloatArray = snowflakes.pathSizes + var pathSizes: FloatArray = snowflakes.pathSizes, ) : DrawModifierNode, LayoutAwareModifierNode, Modifier.Node() { private var canvasSize = Size.Zero @@ -194,8 +195,11 @@ private class Snowfall( override fun ContentDrawScope.draw() { if (drawPosition == SnowfallDrawPosition.Ahead) drawContent() + val canvasHeight = (fadeThreshold + fadeThresholdSpread).coerceIn(0f, 1f) * size.height - clipRect { + clipRect( + bottom = canvasHeight, + ) { snowfallState.snowflakes.fastForEachIndexed { index, flake -> val scale = flake.scale val path = snowflakes[index % snowflakes.size]