Lottie动画动态文本渲染时字符缺失?可能你没做对这两步

1,242 阅读2分钟

在 Lottie 动画中,Dynamic Property(动态属性)是一种特殊的属性,允许你在运行时修改动画的某些属性,例如颜色、位置、透明度等。它们提供了一种动态控制和交互的方式,使你能够根据应用程序的状态或用户输入来改变动画的外观和行为。

Dynamic Property 是通过 KeyPath(键路径)来标识和操作的。KeyPath 是一个由层级关系和属性名称组成的路径,用于指定要修改的动画属性所在的位置。

比如如下json 文件中的片段:

"layers": [
    {
        "ddd": 0,
        "ind": 1,
        "ty": 5,
        "nm": "blue",
        "parent": 2,
        "sr": 1,
        "ks" : {...},
        "ao": 0,
        "t": {...},
        "ip": 0,
        "op": 100,
        "st": 0,
        "bm": 0
    }
]

其中这个blue就是该层级的key,使用动态属性时确保填入的 key 跟它一致,在代码层面就没有问题了,比如你有一个动态修改文本的需求,如果你AE里使用了自定义字体,它会出现在 json 结构的fonts数组里面,在代码中你应该先设置好字体,再动态修改文本。

// 定义一个函数加载Typeface
@Composable
fun rememberTypeface(path: String): Typeface? {
    var typeface: Typeface? by remember {
        mutableStateOf(null)
    }
    val context = LocalContext.current
    LaunchedEffect(path) {
        typeface = null
        withContext(Dispatchers.IO) {
            typeface = Typeface.createFromAsset(context.assets, path)
        }
    }
    return typeface
}

// 加载自定义字体
val typeface = rememberTypeface("fonts/My-Font.otf")
// 定义动态属性
val dynamicProperties = rememberLottieDynamicProperties(
    LottieDynamicProperty(
        property = LottieProperty.TYPEFACE,
        value = typeface,
        keyPath = KeyPath("blue")
    ),
    LottieDynamicProperty(
        property = LottieProperty.TEXT,
        value = "Narrow \njawline",
        keyPath = KeyPath("blue")
    ),
)

val composition = rememberLottieComposition(
    spec = LottieCompositionSpec.Asset("lottie/data.json"),
    imageAssetsFolder = "lottie/images"
)

LottieAnimation(
    composition = composition.value,
    iterations = 1,
    dynamicProperties = dynamicProperties,
    modifier = Modifier
        .matchParentSize()
)

代码这边就大功告成了,按理来说应该正常展示了,如果事实不然,出现了文本字符(字母)缺失的问题,再检查下你的 json 文件里是不是包含有一个chars数组,如果是,那么问题出在Bodymovin导出这一步,对应的github issue

截屏2024-06-04 19.49.29.png

根据回答者提供的解决方案可以得知,UI导出lottie 的时候默认选中了Glyphs这个选项,会把文本转换成形状写入json里面,所以不用引入自定义的字体,缺点是只有动画中用到的字符才能被渲染。这显然不符合动态文本的需求,因此应该在Bodymovin的设置中取消勾选,这时只有文本会导出,插件也会让你上传自定义字体的文件,选择NONE跳过即可。

参考

1. Dynamic text in compose displays every third letter of the string

2. lottie-web wiki