如何在 Lottie 中为动画添加颜色叠加层?

25

我正在使用Lottie for Android在应用程序中添加一些动画。在此应用中,可以通过设置选择主要和强调颜色。我正在使用具有透明背景的动画。为了使动画适应所选择的颜色,我想添加一个颜色叠加到动画中,这样我就可以使用一个动画文件,但可以通过编程方式设置颜色。

是否有人知道如何通过添加颜色叠加来操作动画?

7个回答

54

现在要应用颜色滤镜,您需要以下三个要素:

  1. KeyPath(您想要编辑的内容的名称)
  2. LottieProperty(您想要编辑的属性的名称)
  3. LottieValueCallback(每次动画重新渲染时调用的回调函数)

图层名称可以在动画的JSON中通过标记“nm”找到。

添加完整的颜色叠加层:

LottieAnimationView animationView = findViewById(R.id.animation_view);
animationView.addValueCallback(
        new KeyPath("**"),
        LottieProperty.COLOR_FILTER,
        new SimpleLottieValueCallback<ColorFilter>() {
            @Override
            public ColorFilter getValue(LottieFrameInfo<ColorFilter> frameInfo) {
                return new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP);
            }
        }
);

添加单个图层颜色叠加效果(名为“checkmark”的图层):

LottieAnimationView animationView = findViewById(R.id.animation_view);
animationView.addValueCallback(
        new KeyPath("checkmark", "**"),
        LottieProperty.COLOR_FILTER,
        new SimpleLottieValueCallback<ColorFilter>() {
            @Override
            public ColorFilter getValue(LottieFrameInfo<ColorFilter> frameInfo) {
                return new PorterDuffColorFilter(Color.CYAN, PorterDuff.Mode.SRC_ATOP);
            }
        }
);

移除任何颜色覆盖层:

LottieAnimationView animationView = findViewById(R.id.animation_view);
animationView.addValueCallback(new KeyPath("**"), LottieProperty.COLOR_FILTER,
        new SimpleLottieValueCallback<ColorFilter>() {
            @Override
            public ColorFilter getValue(LottieFrameInfo<ColorFilter> frameInfo) {
                return null;
            }
        }
);

你可以在官方文档中阅读有关此的所有信息。

同时,你也可以查看这个样例代码库

以下是代码片段结果的可视化演示:

Example


13
如果您希望通过xml访问,请使用"app:lottie_colorFilter="@color/colorAccent""。 - Shubham AgaRwal
1
addColorFilter在Lottie中未定义。请检查。 - Rasoul Miri
1
能否覆盖渐变而不是纯色? - Allan Jiang
1
“官方文档”的链接已失效。这是其存档版本:https://web.archive.org/web/20180731092340/http://airbnb.io:80/lottie/android/dynamic.html 。也许有更新的链接? - android developer
1
@androiddeveloper 我特意创建了一个示例存储库,展示了Lottie 3.0.0的实现。我还更新了答案。这是链接:https://github.com/SolveSoul/lottie-android-colorfilter-sample - SolveSoul
显示剩余5条评论

17

基于主要答案(感谢 @SolveSoul ),在 Lottie 的源代码中找到。

Java

首先,获取您的颜色,例如:

int yourColor = ContextCompat.getColor(getContext(),R.color.colorPrimary);

然后像这样设置颜色过滤器:

SimpleColorFilter filter = new SimpleColorFilter(yourColor);
KeyPath keyPath = new KeyPath("**");
LottieValueCallback<ColorFilter> callback = new LottieValueCallback<ColorFilter>(filter);
animationView.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback);

Kotlin

首先,获取您想要的颜色,例如:

val yourColor = ContextCompat.getColor(context, R.color.colorPrimary)

然后像这样设置颜色过滤器:

val filter = SimpleColorFilter(yourColor)
val keyPath = KeyPath("**")
val callback: LottieValueCallback<ColorFilter> = LottieValueCallback(filter)

animationView.addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback)

Kotlin扩展

fun LottieAnimationView.changeLayersColor(
    @ColorRes colorRes: Int
) {
    val color = ContextCompat.getColor(context, colorRes)
    val filter = SimpleColorFilter(color)
    val keyPath = KeyPath("**")
    val callback: LottieValueCallback<ColorFilter> = LottieValueCallback(filter)

    addValueCallback(keyPath, LottieProperty.COLOR_FILTER, callback)
}


5

Compose + Lottie

@Composable
fun LottieAnimation(isPlaying: Boolean = false) {
    val composition by rememberLottieComposition(LottieCompositionSpec.Asset(LOTTIE_FILE_NAME))
    val progress by animateLottieCompositionAsState(
        composition,
        iterations = LottieConstants.IterateForever,
        isPlaying = isPlaying,
    )
    val dynamicProperties = rememberLottieDynamicProperties(
        rememberLottieDynamicProperty(
            property = LottieProperty.COLOR_FILTER,
            value = SimpleColorFilter(MaterialTheme.colors.primary.toArgb()),
            keyPath = arrayOf("**")
        ),
    )
    LottieAnimation(
        composition = composition,
        progress = { progress },
        dynamicProperties = dynamicProperties,
    )
}

4

由于您在设置动画时传递了包含所有绘图数据的JSONObject,因此您可以在设置之前将一些颜色值替换为所需值。

如果您查找颜色关键字c,您可能会找到类似以下内容:

...,“c”:{“k”:[1,0.7,0,1]},“fillEnabled”:true,...

更改该JSONArray中的那些浮点数值将更改动画中的颜色。

当然,我并不是说找到/替换正确的值会太简单,但这至少应该指向您的方向。

作为一个附注:一旦找到它,您可以将该值设置为某种好的占位符,例如"k":[ BG_COLOR_REPLACEMENT_1 ],然后在加载资产时,在创建JSONObject并将其传递给Lottie之前,只需运行.replace("BG_COLOR_REPLACEMENT_1","1,0.7,1,1")即可。


3
我看到了Guardanis的回答,并进一步阐述了一种安全的方法来查找包含Lottie动画的JSON中的颜色:
搜索-"c":{"a"-,您将为每个图像层找到类似于以下片段的片段:{"ty":"fl","c":{"a":0,"k":[0.4,0.4,0.4,0.4]}}
在片段中,您会注意到"c"表示颜色,"a"表示Alpha,"k"是图层颜色的CMYK。只需将其更改为所需的颜色即可。

请注意,JSONObject 是一个无序映射概念,那些 ak 键可能不会按字典顺序出现在您的搜索中。空格和换行符也可能是漂亮打印的结果,因此您可能需要在搜索和使用正则表达式之前对其进行规范化。 - Cruceo
实际上对我来说似乎是HSV颜色代码,不确定第四个值的作用,但在预览中玩耍似乎没有改变任何东西。 - hmac

2
在 Kotlin(v1.4.32) 中,要在所有图层中设置完整的动画,只需执行以下操作:
YOURS_LottieAnimationView.addValueCallback(
            KeyPath("**"),
            LottieProperty.COLOR_FILTER,
            { PorterDuffColorFilter(Color.parseColor("#b70101"), PorterDuff.Mode.SRC_ATOP) }
        )

-3
如果你的JSON有一个sc:字段,那么你应该能够直接设置十六进制颜色,例如:
"sc": "#6664e7"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接