Updated on 2026-08-14
This commit is contained in:
parent
44622fd338
commit
79bfe8a57a
2 changed files with 45 additions and 38 deletions
|
|
@ -20,13 +20,14 @@ data class BladeAnimation(
|
|||
|
||||
@Composable
|
||||
fun rememberBladeAnimation(): BladeAnimation {
|
||||
val infiniteTransition = rememberInfiniteTransition()
|
||||
val infiniteTransition = rememberInfiniteTransition(label = "BladeAnimation")
|
||||
val offsetState = infiniteTransition.animateFloat(
|
||||
initialValue = 0f,
|
||||
targetValue = 1f,
|
||||
animationSpec = infiniteRepeatable(
|
||||
animation = tween(durationMillis = 1500, easing = LinearEasing),
|
||||
),
|
||||
label = "BladeOffset",
|
||||
)
|
||||
|
||||
return remember(offsetState) {
|
||||
|
|
@ -37,51 +38,56 @@ fun rememberBladeAnimation(): BladeAnimation {
|
|||
@Suppress("MagicNumber")
|
||||
@Composable
|
||||
fun TextStyle.applyBladeBrush(isEnabled: Boolean, textColor: Color): TextStyle {
|
||||
return if (isEnabled) {
|
||||
val offset by LocalBladeAnimation.current.offsetState
|
||||
val offsetState = LocalBladeAnimation.current.offsetState
|
||||
val offset = if (isEnabled) offsetState.value else 0f
|
||||
|
||||
val brush = remember(offset, textColor) {
|
||||
object : ShaderBrush() {
|
||||
override fun createShader(size: Size): Shader {
|
||||
val center = Offset(size.width / 2f, size.height / 2f)
|
||||
val diagonal = sqrt(size.width * size.width + size.height * size.height)
|
||||
// Subtle diagonal angle, similar to iOS shimmer
|
||||
val direction = Offset(x = 1f, y = 0.3f)
|
||||
|
||||
// Half-width of the blob (80% of diagonal total — wide, soft sweep)
|
||||
val bandHalf = diagonal * 0.40f
|
||||
|
||||
// Sweep the highlight center from left-of-element to right-of-element.
|
||||
// offset 0..1 maps to a full pass including off-screen padding on both sides.
|
||||
val shift = direction * ((offset - 0.5f) * diagonal * 1.5f)
|
||||
val highlightCenter = center + shift
|
||||
|
||||
// Full color text with a wide, gradual low-alpha dip sweeping left → right
|
||||
val brush = remember(offset, textColor, isEnabled) {
|
||||
object : ShaderBrush() {
|
||||
override fun createShader(size: Size): Shader {
|
||||
if (!isEnabled) {
|
||||
// Solid color via the same shader path (LinearGradientShader needs >= 2 colors).
|
||||
return LinearGradientShader(
|
||||
colors = listOf(
|
||||
textColor,
|
||||
textColor.copy(alpha = 0.75f),
|
||||
textColor.copy(alpha = 0.45f),
|
||||
textColor.copy(alpha = 0.3f),
|
||||
textColor.copy(alpha = 0.45f),
|
||||
textColor.copy(alpha = 0.75f),
|
||||
textColor,
|
||||
),
|
||||
from = highlightCenter - direction * bandHalf,
|
||||
to = highlightCenter + direction * bandHalf,
|
||||
colorStops = listOf(0f, 0.15f, 0.35f, 0.5f, 0.65f, 0.85f, 1f),
|
||||
colors = listOf(textColor, textColor),
|
||||
from = Offset.Zero,
|
||||
to = Offset(size.width, size.height),
|
||||
tileMode = TileMode.Clamp,
|
||||
)
|
||||
}
|
||||
|
||||
val center = Offset(size.width / 2f, size.height / 2f)
|
||||
val diagonal = sqrt(size.width * size.width + size.height * size.height)
|
||||
// Subtle diagonal angle, similar to iOS shimmer
|
||||
val direction = Offset(x = 1f, y = 0.3f)
|
||||
|
||||
// Half-width of the blob (80% of diagonal total — wide, soft sweep)
|
||||
val bandHalf = diagonal * 0.40f
|
||||
|
||||
// Sweep the highlight center from left-of-element to right-of-element.
|
||||
// offset 0..1 maps to a full pass including off-screen padding on both sides.
|
||||
val shift = direction * ((offset - 0.5f) * diagonal * 1.5f)
|
||||
val highlightCenter = center + shift
|
||||
|
||||
// Full color text with a wide, gradual low-alpha dip sweeping left → right
|
||||
return LinearGradientShader(
|
||||
colors = listOf(
|
||||
textColor,
|
||||
textColor.copy(alpha = 0.75f),
|
||||
textColor.copy(alpha = 0.45f),
|
||||
textColor.copy(alpha = 0.3f),
|
||||
textColor.copy(alpha = 0.45f),
|
||||
textColor.copy(alpha = 0.75f),
|
||||
textColor,
|
||||
),
|
||||
from = highlightCenter - direction * bandHalf,
|
||||
to = highlightCenter + direction * bandHalf,
|
||||
colorStops = listOf(0f, 0.15f, 0.35f, 0.5f, 0.65f, 0.85f, 1f),
|
||||
tileMode = TileMode.Clamp,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
this.copy(brush = brush)
|
||||
} else {
|
||||
this.copy(
|
||||
color = textColor,
|
||||
)
|
||||
}
|
||||
|
||||
return this.copy(brush = brush)
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue