luma-compose
1.0.0indexedReusable patterned backgrounds and follow-glow visuals for Compose, with immutable styles, runtime states, rich layout and interaction presets, lightweight blur, parallax, and seeded randomness.
Reusable patterned backgrounds and follow-glow visuals for Compose, with immutable styles, runtime states, rich layout and interaction presets, lightweight blur, parallax, and seeded randomness.
luma-compose is a Kotlin Multiplatform multi-module library with reusable visual effects for Jetpack Compose.
The shared API lives in common source sets and currently targets Android, Desktop, iOS, and JS.
Main public composables:
PatternBackground for decorative patterned backgroundsFollowGlow for a soft glow that follows a target pointThe API stays app-agnostic: no product-specific models like compass, tilt, or level are built into the library.
Use the published artifact:
dependencies {
implementation("io.github.nvshink:luma-compose:1.0.0")
}
For Kotlin Multiplatform consumers, use the shared coordinate in commonMain:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.nvshink:luma-compose:1.0.0")
}
}
}
Published target-specific artifacts:
io.github.nvshink:luma-compose - KMP root publicationio.github.nvshink:luma-compose-android - Android artifactModule layout:
:luma KMP library module with shared public API and presets:android-demo Android demo app with catalog screens and live controls:desktop-demo Compose Desktop demo app for trying the same effects on JVM desktopval patternStyle = PatternDefaults.softDots()
val glowStyle = GlowDefaults.softRadial()
Box(Modifier.fillMaxSize()) {
PatternBackground(
state = PatternState(
interactionPoint = OffsetFraction(0.65f, 0.3f),
isAnimated = true,
),
style = patternStyle,
modifier = Modifier.fillMaxSize(),
)
FollowGlow(
state = GlowState(
center = OffsetFraction(0.65f, 0.3f),
isAnimated = true,
),
style = glowStyle,
modifier = Modifier.fillMaxSize(),
)
}
PatternBackground(state, style, modifier) draws a reusable background from dots, shapes, sprites, or custom draw content.
Main settings:
Example:
val style = PatternStyle(
element = PatternElement.Shape(
size = DpSize(18.dp, dp),
shape = RoundedCornerShape(),
color = Color(),
),
layout = PatternLayout.Grid(
spacing = dp,
rowOffset = dp,
density = ,
),
shadow = PatternShadow.Drop(
blurRadius = dp,
useInteractionAsLight = ,
),
blur = PatternBlur.Soft(radius = dp),
rotation = PatternRotation.Distributed(
baseDegreesPerSecond = ,
variation = ,
seed = ,
),
interaction = PatternInteraction.DistanceBasedOffset(
point = OffsetFraction.Center,
maxOffset = dp,
intensity = ,
radius = dp,
falloff = Falloff.Smooth,
),
elementTint = Color(),
shadowTint = Color(),
)
Ready presets:
val dots = PatternDefaults.softDots()
val stripes = PatternDefaults.ferriteStripes()
val sprites = PatternDefaults.floatingSprites()
val field = PatternDefaults.magneticNorthField()
Notes:
PatternDefaults read colors from MaterialTheme.colorSchemePatternState.isAnimated enables internal time-driven animationPatternState.animationTimeMillis lets you drive animation externallyPatternState.interactionPoint can be mapped to drag, cursor, sensor, or app stateCustom sprite example:
val sprite = PatternElement.Sprite(
size = DpSize(24.dp, 24.dp),
painter = rememberVectorPainter(Icons.Rounded.Star),
tint = Color(0xFFFFD166),
)
Custom layout example:
val waveLayout = PatternLayout.Custom(
provider = PatternPositionProvider { scope ->
List(20) { index ->
val x = index / 19f
OffsetFraction(x = x, y = 0.5f)
}
},
)
FollowGlow(state, style, modifier) draws a soft light layer tied to a target point.
Main settings:
Example:
val glowStyle = GlowStyle(
color = Color(0xFF5B8CFF),
alpha = 0.36f,
blurRadius = 120.dp,
size = DpSize(220.dp, 220.dp),
shape = GlowShape.Circle,
trailing = GlowTrailing(steps = 3, alphaDecay = 0.08f),
)
Ready presets:
val softGlow = GlowDefaults.softRadial()
val ellipseGlow = GlowDefaults.strongEllipse()
val blobGlow = GlowDefaults.ambientBlob()
Notes:
GlowState.center is the target position in fractional coordinatesGlowState.isAnimated enables follow smoothingGlowState.intensity scales the visual output without rebuilding the styleGlowShape.CustomdrawWithCachedensity, blurRadius, and sprite size reasonable on large surfacesPatternBlur.Soft is a lightweight approximation, not a full Gaussian blur pipelineThe :android-demo module is a small catalog app for trying the library in isolation.
To use it, clone this repository and run the Android demo app from the local project.
Screens:
Pattern BackgroundGlowCombined DemoWhat it includes:
Run the Android demo:
./gradlew :android-demo:installDebug
The :desktop-demo module is a Compose Desktop app for previewing the library on desktop with the same visual primitives exposed by the shared KMP module.
Run the desktop demo:
./gradlew :desktop-demo:run
io.github.nvshink:luma-compose-desktop - Desktop JVM artifactio.github.nvshink:luma-compose-js - JS artifactio.github.nvshink:luma-compose-iosx64 - iOS X64 artifactio.github.nvshink:luma-compose-iosarm64 - iOS Arm64 artifactio.github.nvshink:luma-compose-iossimulatorarm64 - iOS Simulator Arm64 artifactPatternElement controls what is rendered: Dot, Shape, Sprite, CustomPatternLayout controls placement: Random, Uneven, Grid, Radial, CustomPatternRotation controls motion: None, Uniform, Async, Distributed, Follow, DirectedPatternInteraction controls point-based response: UniformOffset, DistanceBasedOffsetPatternShadow configures shadow and light directionPatternBlur adds a lightweight soft blur layerPatternDepth adds parallax-like offsetPatternStyle groups all visual parameters into one immutable stylePatternState holds runtime inputs like animation and interaction pointseed for reproducibilityGlowShape controls silhouette: Circle, Ellipse, RoundedRect, CustomGlowFalloff controls gradient concentration: Soft, Radial, FocusedGlowTrailing adds a short light trailGlowStyle groups color, alpha, size, blur, shape, and trailGlowState holds runtime inputs like center point, intensity, and follow animationSurfaced from shared tags and platforms — no rankings paid for.