Reputation: 371
If I have a lottie animation in the form of a json file, is there a way to recolor it in code or even within the json itself?
(To be clear, I hope there's a way to do it without involving After Effects. For instance if I decide to change my app's primary color, the whole app will change except the animation unless there's a way to do that.)
Upvotes: 6
Views: 11203
Reputation: 116010
Here's a Kotlin solution for all cases you might want:
/**sets tint for the animation.
* @itemsToTint the items elements ("nm" inside "layers") the animation to tint.
* null will reset all tinting. Empty will set tint for all. */
fun LottieAnimationView.setAnimationTint(itemsToTint: Array<String>?, @ColorInt color: Int) {
//based on https://stackoverflow.com/a/45607292/878126 https://airbnb.io/lottie/#/android?id=dynamic-properties https://github.com/SolveSoul/lottie-android-colorfilter-sample
if (itemsToTint == null) {
//un-tint
addValueCallback(KeyPath("**"), LottieProperty.COLOR_FILTER) { null }
return
}
addValueCallback(
KeyPath(*itemsToTint,"**" ),
LottieProperty.COLOR_FILTER
) { PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP) }
}
Upvotes: 3
Reputation: 751
There is another thread on this topic with the same approach but a bit simplified: How to add a color overlay to an animation in Lottie?
Here's directly an example (Kotlin):
yourLottieAnimation.addValueCallback(
KeyPath("whatever_keypath", "**"),
LottieProperty.COLOR_FILTER
) {
PorterDuffColorFilter(
Color.CYAN,
PorterDuff.Mode.SRC_ATOP
)
}
You can find the names of the keypaths also in the Lottie editor.
Upvotes: 0
Reputation: 371
I figured it out. For this example, let's say I want to recolor a specific layer to Color.RED.
You'll need your LottieAnimationView, a KeyPath, and a LottieValueCallback
private LottieAnimationView lottieAnimationVIew;
private KeyPath mKeyPath;
private LottieValueCallback<Integer> mCallback;
Then in your onCreate (or onViewCreated for a fragment) you'll get the animation with findViewById, as well as "addLottieOnCompositionLoadedListener" to the lottieAnimationView, in which you will setup the "mKeyPath" and "mCallback":
lottieAnimationVIew = findViewById(R.id.animationView);
lottieAnimationView.addLottieOnCompositionLoadedListener(new LottieOnCompositionLoadedListener() {
@Override
public void onCompositionLoaded(LottieComposition composition) {
mKeyPath = getKeyPath(); // This is your own method for getting the KeyPath you desire. More on that below.
mCallback = new LottieValueCallback<>();
mCallback.setValue(Color.RED);
checkBox.addValueCallback(mKeyPath, LottieProperty.COLOR, mCallback);
}
});
The argument "LottieProperty.COLOR" specifies which property I am changing.
There's probably a better way to do this, but here's my "getKeyPath" method for finding the specific thing I want to change. It will log every KeyPath so you can see which one you want. Then it returns it once you've supplied the correct index. I saw that the one I want is the 5th in the list, hence the hard-coded index of 4.
private KeyPath getKeyPath() {
List<KeyPath> keyPaths = lottieAnimationView.resolveKeyPath(new KeyPath("Fill", "Ellipse 1", "Fill 1"));
for (int i = 0; i < keyPaths.size(); i++) {
Log.i("KeyPath", keyPaths.get(i).toString());
}
if (keyPaths.size() == 5) {
return keyPaths.get(4);
}
else {
return null;
}
}
Note that the "Fill", "Ellipse 1", "Fill 1" are strings I supplied to narrow the list down to just the ones that have those keys, because I know that the layer I want will be among those. There's likely a better way to do this as well.
Upvotes: 5