Is it possible to recolor a lottie animation programmatically?

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.)

3 Answers

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.

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 if (itemsToTint == null) { //un-tint addValueCallback(KeyPath("**"), LottieProperty.COLOR_FILTER) { null } return } addValueCallback( KeyPath(*itemsToTint,"**" ), LottieProperty.COLOR_FILTER ) { PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP) }
}

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.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like