Skip to content
Kapow
Esc
↑↓navigate↵open⌘Jpreview
On this page

Hinge effects

Drive a shine, glow or iris from the hinge angle of a foldable with kapow-crease.

On a foldable, the hinge angle is a natural progress value: 0 degrees when closed, 180 when flat. The kapow-crease artifact turns it into the input of a progress effect. The angle comes from Crease.

// shared/build.gradle.kts
kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("io.github.jantursky:kapow-crease:1.3.0")
        }
    }
}

Modifier.hingeEffect

Modifier.hingeEffect(effect, angleRange) maps the angle linearly onto 0 to 1 and draws the effect at that progress. The effect is not animated over time: it follows the hinge, so folding back reverses it.

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.jantursky.kapow.ProgressEffect
import com.jantursky.kapow.crease.hingeEffect

@Composable
fun FoldingCard() {
    Box(
        Modifier
            .size(240.dp)
            .hingeEffect(ProgressEffect.shine(), angleRange = 30f..150f),
    )
}

The default range is 0f..180f. Outside the range the progress is clamped, so with 30f..150f an angle of 10 degrees draws at progress 0 and 170 draws at 1. At 90 degrees with the default range, progress is 0.5.

No hinge, no change

On a device or platform without a hinge reading, hingeEffect returns the modifier unchanged and the element is drawn as it would be without it. That covers phones, tablets, JVM desktop and wasmJs. You can leave the modifier in shared code.

Previews and tests

Crease’s ProvideFoldState feeds a fixed state into the subtree. Use it to see the effect without a foldable.

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.unit.dp
import com.jantursky.crease.FoldState
import com.jantursky.crease.ProvideFoldState
import com.jantursky.kapow.ProgressEffect
import com.jantursky.kapow.crease.hingeEffect

@Composable
fun HalfOpenPreview() {
    ProvideFoldState(FoldState.book(Size(800f, 600f), angle = 90f)) {
        Box(Modifier.size(240.dp).hingeEffect(ProgressEffect.glow()))
    }
}

The demo has a slider that simulates the angle the same way.

Which effects

ProgressEffect.shine() moves a band across the element as the device opens. ProgressEffect.glow() strengthens a halo. ProgressEffect.iris() grows a circular reveal.

Not verified on a device yet: behaviour on real foldables. The mapping is covered by tests with simulated angles.

Was this page helpful?