AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77671536
Accepted
Oleksandr Myronchuk
Oleksandr Myronchuk
Asked: 2023-12-16 23:45:30 +0800 CST2023-12-16 23:45:30 +0800 CST 2023-12-16 23:45:30 +0800 CST

在 Jetpack Compose 中单独为每个字母设置动画时将画笔效果应用于整个单词

  • 772

我正在尝试在 Jetpack Compose 中创建文本效果,其中文本使用画笔,看起来像是一组沿对角线平滑变化的颜色。文本中的各个字母应该上下移动,以及半圈。

我遇到了两个问题:

  1. 如果我尝试将画笔应用于整个单词,我不知道如何为移动和旋转的字母设置动画。这是我尝试过的代码:
        Text(
        text = word,
        fontSize = fontSize,
        style = LocalTextStyle.current.copy(brush = gradientBrush),
        modifier = modifier
    )
  1. 如果我将动画单独应用于每个字母,我可以通过动画实现所需的结果,但画笔也会单独应用于每个字母,从而产生不吸引人的效果。我需要将画笔应用于整个单词。这是我尝试过的代码:
    Row {
        word.forEachIndexed { index, char ->
            val angle by rotationAngles[index]
            val offset by letterOffsets[index]
            Text(
                text = char.toString(),
                fontSize = fontSize,
                style = LocalTextStyle.current.copy(brush = gradientBrush),
                modifier = Modifier
                    .rotate(angle)
                    .offset(y = offset.dp)
            )
        }
    }

这里有两个演示:

在此输入图像描述

  1. 将画笔应用于整个单词的预期结果,但我不知道如何为字母设置动画。
  2. 应用动画的预期结果,但我无法将画笔应用于整个单词(画笔单独应用于每个字母)。

如何在 Jetpack Compose 中将画笔应用到整个单词时,为每个字母单独创建向上、向下和半转动的动画?

这是完整的代码:

@Preview(showBackground = true)
@Composable
fun RotatingLettersPreview() {
    RotatingLetters("Medium")
}

@OptIn(ExperimentalTextApi::class)
@Composable
fun RotatingLetters(word: String,
                    fontSize: TextUnit = TextUnit.Unspecified,
                    modifier: Modifier = Modifier) {

    val colorGradient = listOf(
        Color(0xFFC0EFFF), // Light blue
        Color(0xFF9BDBFB), // Medium blue
        Color(0xFF75C2F9), // Dark blue
        Color(0xFFF7D7C4), // Light pink
        Color(0xFFF5B2C7), // Medium pink
        Color(0xFFF28BAE), // Dark pink
        Color(0xFFF7F2D4), // Light beige
        Color(0xFFF5E0C3), // Medium beige
    )

    val fontSizeInPx = with(LocalDensity.current) { 30.sp.toPx() }
    val doubleFontSizeInPx = fontSizeInPx * 2

    val infiniteTransitionForOffset = rememberInfiniteTransition(label = "")
    val offsetAnimation by infiniteTransitionForOffset.animateFloat(
        initialValue = 0f,
        targetValue = doubleFontSizeInPx,
        animationSpec = infiniteRepeatable(tween(200000, easing = LinearEasing)), label = ""
    )

    val gradientBrush = remember(offsetAnimation) {
        object : ShaderBrush() {
            override fun createShader(size: Size): Shader {
                val widthOffset = size.width * offsetAnimation
                val heightOffset = size.height * offsetAnimation
                return LinearGradientShader(
                    colors = colorGradient,
                    from = Offset(widthOffset, heightOffset),
                    to = Offset(widthOffset + size.width, heightOffset + size.height),
                    tileMode = TileMode.Mirror
                )
            }
        }
    }

    val infiniteTransitionForRotation = rememberInfiniteTransition(label = "")
    val rotationDirection = remember { mutableStateOf(1) }

    val rotationAngles = List(word.length) { index ->
        infiniteTransitionForRotation.animateFloat(
            initialValue = 0f,
            targetValue =
            if (index % 2 == 0) 5f * rotationDirection.value else -5f * rotationDirection.value,
            animationSpec = infiniteRepeatable(
                animation = tween(250, easing = LinearEasing),
                repeatMode = RepeatMode.Restart
            ), label = ""
        )
    }

    LaunchedEffect(key1 = Unit) {
        while (true) {
            delay(250)
            rotationDirection.value *= -1
        }
    }

    val letterOffsets = List(word.length) { index ->
        infiniteTransitionForRotation.animateFloat(
            initialValue = 0f,
            targetValue = if (index % 2 == 0) 2f else -2f,
            animationSpec = infiniteRepeatable(
                animation = tween(250, easing = LinearEasing),
                repeatMode = RepeatMode.Reverse
            ), label = ""
        )
    }

    Text(
        text = word,
        fontSize = fontSize,
        style = LocalTextStyle.current.copy(brush = gradientBrush),
        modifier = modifier
    )

/*
    Row {
        word.forEachIndexed { index, char ->
            val angle by rotationAngles[index]
            val offset by letterOffsets[index]
            Text(
                text = char.toString(),
                fontSize = fontSize,
                style = LocalTextStyle.current.copy(brush = gradientBrush),
                modifier = Modifier
                    .rotate(angle)
                    .offset(y = offset.dp)
            )
        }
    }
*/
}
android-jetpack-compose
  • 1 1 个回答
  • 34 Views

1 个回答

  • Voted
  1. Best Answer
    Yazan
    2023-12-17T17:23:26+08:002023-12-17T17:23:26+08:00

    您可以通过使用drawWithContent和剪切每个字母的组合来实现类似的效果,以在所有字母上创建单个连续渐变。这是一个概念性的解决方案:

    创建一个使用 Canvas 手动绘制文本的自定义可组合项,允许您在整个单词上应用单个渐变画笔。在绘制字符时,使用drawWithContent将绘图区域剪切到每个字符的边界,这样它们就可以独立地制作动画,同时仍然共享相同的画笔。以下是如何实现它的示例:

    @Composable
    fun AnimatedGradientText(word: String, gradientBrush: Brush, fontSize: TextUnit, modifier: Modifier = Modifier) {
        // Calculate text size, character positions, etc.
        val textPaint = remember {
            Paint().asFrameworkPaint().apply {
            isAntiAlias = true
            style = android.graphics.Paint.Style.FILL
        }
    }
    
    // For each letter, create a rotation and offset animation.
    val rotationAngles = remember { /* ... Your rotation animations ... */ }
    val letterOffsets = remember { /* ... Your offset animations ... */ }
    
    Canvas(modifier = modifier) {
        // Calculate text size and positions
        val textLayoutResult = remember(word, fontSize) { /* ... Measure text ... */ }
    
        word.forEachIndexed { index, char ->
            // Get animation values
            val angle: Float by rotationAngles[index]
            val offset: Float by letterOffsets[index]
    
            // Save the current canvas state
            save()
    
            // Position the canvas for this character
            translate(left + characterPositions[index], top)
    
            // Apply the rotation transformation
            rotate(angle)
    
            // Set the shader to the paint
            textPaint.shader = gradientBrush.asAndroidShader()
    
            // Draw this character
            drawContext.canvas.nativeCanvas.drawText(
                char.toString(),
                0f,
                0f + offset,
                textPaint
            )
    
            // Restore the canvas to avoid affecting subsequent characters
            restore()
        }
    }
    }
    
    • 1

相关问题

  • 将 StateFlow 设置为 null 时,Jetpack Compose 中的 Canvas 不清除绘制内容的问题

  • 如何在 Jetpack Compose 中制作钢琴音符?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve