perf: cache WaveGraphic paths per size (was rebuilding ~3k lineTo per draw frame) + measured motion pass
This commit is contained in:
parent
e5a64e1892
commit
bd4f6bb874
1 changed files with 39 additions and 30 deletions
|
|
@ -84,6 +84,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
|
@ -440,41 +441,49 @@ private fun WaveGraphic(modifier: Modifier = Modifier) {
|
||||||
val gradientColors = listOf(LocalTokens.current.accentFill, GradientMid, GradientEnd)
|
val gradientColors = listOf(LocalTokens.current.accentFill, GradientMid, GradientEnd)
|
||||||
val accentGlow = LocalTokens.current.accentFill
|
val accentGlow = LocalTokens.current.accentFill
|
||||||
|
|
||||||
Canvas(modifier = modifier) {
|
// Build each wave path + its gradient ONCE per size/palette, not per draw
|
||||||
|
// pass: this canvas sits on the hub, and rebuilding ~1k lineTo segments
|
||||||
|
// per layer was the heavy frame behind the hub-transition jank (99th-p
|
||||||
|
// ~200ms). 4px steps are indistinguishable at this frequency and cut
|
||||||
|
// segment count by 4x.
|
||||||
|
var canvasSize by remember { mutableStateOf(androidx.compose.ui.unit.IntSize.Zero) }
|
||||||
|
val layers = remember(canvasSize, gradientColors) {
|
||||||
|
val w = canvasSize.width.toFloat()
|
||||||
|
val h = canvasSize.height.toFloat()
|
||||||
|
if (w <= 0f || h <= 0f) emptyList()
|
||||||
|
else (0..2).map { layer ->
|
||||||
|
val amplitude = (30f - layer * 8f) * (w / 400f)
|
||||||
|
val frequency = 0.008f + layer * 0.002f
|
||||||
|
val phaseShift = layer * 0.5f
|
||||||
|
val path = Path().apply {
|
||||||
|
moveTo(0f, h / 2 + amplitude * kotlin.math.sin(phaseShift.toDouble()).toFloat())
|
||||||
|
var x = 0f
|
||||||
|
while (x <= w) {
|
||||||
|
val y = h / 2 + amplitude * kotlin.math.sin(
|
||||||
|
(x * frequency * Math.PI * 2).toDouble() + phaseShift
|
||||||
|
).toFloat()
|
||||||
|
lineTo(x, y)
|
||||||
|
x += 4f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val strokeBrush = Brush.horizontalGradient(
|
||||||
|
colors = gradientColors.map { it.copy(alpha = 0.6f - layer * 0.15f) },
|
||||||
|
startX = 0f,
|
||||||
|
endX = w,
|
||||||
|
)
|
||||||
|
Triple(path, strokeBrush, (3f - layer * 0.5f) * (w / 400f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas(
|
||||||
|
modifier = modifier.onSizeChanged { canvasSize = it },
|
||||||
|
) {
|
||||||
val width = size.width
|
val width = size.width
|
||||||
val height = size.height
|
val height = size.height
|
||||||
val centerY = height / 2
|
val centerY = height / 2
|
||||||
|
|
||||||
// Draw multiple wave layers
|
for ((path, strokeBrush, strokeWidth) in layers) {
|
||||||
for (layer in 0..2) {
|
drawPath(path = path, brush = strokeBrush, style = Stroke(width = strokeWidth))
|
||||||
val path = Path()
|
|
||||||
val amplitude = (30f - layer * 8f) * (width / 400f)
|
|
||||||
val frequency = 0.008f + layer * 0.002f
|
|
||||||
val phaseShift = layer * 0.5f
|
|
||||||
|
|
||||||
path.moveTo(0f, centerY)
|
|
||||||
|
|
||||||
for (x in 0..width.toInt()) {
|
|
||||||
val xFloat = x.toFloat()
|
|
||||||
val y = centerY + amplitude * kotlin.math.sin(
|
|
||||||
(xFloat * frequency * Math.PI * 2).toDouble() + phaseShift
|
|
||||||
).toFloat()
|
|
||||||
if (x == 0) {
|
|
||||||
path.moveTo(xFloat, y)
|
|
||||||
} else {
|
|
||||||
path.lineTo(xFloat, y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drawPath(
|
|
||||||
path = path,
|
|
||||||
brush = Brush.horizontalGradient(
|
|
||||||
colors = gradientColors.map { it.copy(alpha = 0.6f - layer * 0.15f) },
|
|
||||||
startX = 0f,
|
|
||||||
endX = width,
|
|
||||||
),
|
|
||||||
style = Stroke(width = (3f - layer * 0.5f) * (width / 400f)),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ambient glow behind the waves — wide, faint, no visible disc edge.
|
// Ambient glow behind the waves — wide, faint, no visible disc edge.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue