Last active
June 26, 2025 16:50
-
-
Save bitspittle/7e506898549cef62e8c9eb5878a4f218 to your computer and use it in GitHub Desktop.
Animating in a 4x4 grid of squares in Kobweb (in BFS order)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Drafted as part of a conversation in https://www.linkedin.com/posts/shubhamsinghshubham777_kotlin-compose-jetpackcompose-activity-7343659024954925059-QS39 | |
| // To repro yourself, you can run `kobweb create app/empty` and overwrite `pages/Index.kt` with this code: | |
| import androidx.compose.runtime.Composable | |
| import androidx.compose.runtime.remember | |
| import com.varabyte.kobweb.compose.css.CSSTimeNumericValue | |
| import com.varabyte.kobweb.compose.css.StyleVariable | |
| import com.varabyte.kobweb.compose.foundation.layout.Box | |
| import com.varabyte.kobweb.compose.foundation.layout.Column | |
| import com.varabyte.kobweb.compose.foundation.layout.Row | |
| import com.varabyte.kobweb.compose.ui.Alignment | |
| import com.varabyte.kobweb.compose.ui.Modifier | |
| import com.varabyte.kobweb.compose.ui.graphics.Colors | |
| import com.varabyte.kobweb.compose.ui.modifiers.* | |
| import com.varabyte.kobweb.core.Page | |
| import com.varabyte.kobweb.silk.style.CssStyle | |
| import com.varabyte.kobweb.silk.style.animation.Keyframes | |
| import com.varabyte.kobweb.silk.style.base | |
| import com.varabyte.kobweb.silk.style.toModifier | |
| import org.jetbrains.compose.web.css.AnimationFillMode | |
| import org.jetbrains.compose.web.css.percent | |
| import org.jetbrains.compose.web.css.px | |
| import org.jetbrains.compose.web.css.s | |
| import org.jetbrains.compose.web.dom.Text | |
| val AnimDelay by StyleVariable<CSSTimeNumericValue>() | |
| val GrowInKeyframes = Keyframes { | |
| 0.percent { Modifier.scale(0) } | |
| 100.percent { Modifier.scale(1) } | |
| } | |
| val SquareStyle = CssStyle.base { | |
| Modifier | |
| .size(100.px) | |
| .fontSize(20.px) | |
| .backgroundColor(Colors.Cyan) | |
| .color(Colors.Black) | |
| .scale(0) | |
| .animation(GrowInKeyframes.toAnimation(duration = 1.s, delay = AnimDelay.value(), fillMode = AnimationFillMode.Forwards)) | |
| } | |
| @Composable | |
| fun Square(label: String, delay: CSSTimeNumericValue) { | |
| Box(SquareStyle.toModifier().setVariable(AnimDelay, delay), contentAlignment = Alignment.Center) { | |
| Text(label) | |
| } | |
| } | |
| @Page | |
| @Composable | |
| fun HomePage() { | |
| // We render a 4x4 grid of squares labeled left-to-right, top-to-bottom, | |
| // but we animate them in in a breadth-first manner, starting from the top left. | |
| // The example here is easy enough to just hardcode this order for now. | |
| val animInIndex = remember { | |
| arrayOf( | |
| intArrayOf(0, 2, 5, 9), | |
| intArrayOf(1, 4, 8, 12), | |
| intArrayOf(3, 7, 11, 14), | |
| intArrayOf(6, 10, 13, 15), | |
| ) | |
| } | |
| Column { | |
| for (y in 0 until 4) { | |
| Row { | |
| for (x in 0 until 4) { | |
| val orderIndex = y * 4 + x | |
| Square(label = orderIndex.toString(), delay = (animInIndex[y][x] * 0.1).s) | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment