Harry Feld
Harry Feld

Reputation: 73

How do I use ColorFilter with React-Native-Lottie?

I cannot seem to get the colorFilter prop working with my .json file. There are no errors but the colours are clearly not changing.

<LottieView
     style={{
         width: 90,
         height: 90,
     }}
     colorFilters={
       [
         {
         keypath: "asdf",
         color: "#abcdef",
         }
       ]
     }
     source={badge.icon}
     loop={false}
/>

I'm importing the .json from After Effects using BodyMovin but am I changing the layer name correctly? If not why on earth is this not working? enter image description here

Upvotes: 5

Views: 8008

Answers (4)

Just try with react native, and it's work fine for me

keypaths are extracted from nm keys (in my experience within the layers key) in the .json lottie file.

    <LottieView
                style={style.heartLootie}
                source={require("../../assets/animations/favorite_animation.json")}
                progress={animationProgress}
                colorFilters={[
                    { keypath: "Red Heart", color: themeColors.PRIMARY },
                    { keypath: "Grey Heart", color: themeColors.SECONDARY },
                ]}
            />

Upvotes: 7

mmorosavljevic
mmorosavljevic

Reputation: 1

After some research I've found out that there are few ways of changing color of Lottie AnimationObject.

You can directly modify animtions JSON content as someone already described here: https://stackoverflow.com/a/62790537/19275701.

But I think the easiest way would be to use color filters. I created a function that takes AnimationObject or array of them and returns keypath names so you can check if you named your keypath correctly. I tested it with animations that I made in Figma. Some of them are only vectors some of them are groups of rectangles, vectors etc. And it seems to be working for every icon I tested. Just wanted to share since it made my coding lot easier.

import { AnimationObject } from "lottie-react-native";

export const getAnimationKeypaths = (animations: AnimationObject[] | AnimationObject) => {
let keypaths: Set<string> = new Set();

if(!Array.isArray(animations)) {
    animations.layers.map((l , i) => keypaths.add(l.nm));
} else {
    animations.map((a, i) => {
        a.layers.map((l , i) => keypaths.add(l.nm));
    })
}

return Array.from(keypaths);
}

And then in LottieView component use it like this:

import HomeAnimation from "../../../assets/lottie/bottomTabs/home.json";

const source = HomeAnimation;

<LottieView
        ref={ref}
        source={source}
        style={{
          // your styles
        }}
        colorFilters={getAnimationKeypaths(source).map(
          (keypath, i) => ({
            keypath,
            color: theme.colors.primary
          })
        )}
        autoPlay={false}
        loop={false}
      />

Upvotes: 0

r018u
r018u

Reputation: 61

This is an outstanding issue, I have opened an issue here and will work with the devs to hopefully resolve this issue. It is probably the biggest bottleneck for React Native adoption right now.

Upvotes: 2

red
red

Reputation: 1619

I can't get colorFilters to work but you can try doing the following:


import myAnimation from "./../img/myAnimation.json";

in the render part use LottieView with the import and not with the require inline

<LottieView        
  //source={require("./../img/radius.json")}
  source={myAnimation}
/>

Now you can manipulate the properties directly from the json object, just for example here I manipulate the color based on the actual color (from black to white or from white to black)

myAnimation.layers[1].shapes[0].it[1].c.k = myAnimation.layers[1].shapes[0].it[1].c.k[0] == 0 ?  [1,1,1,1] : [0,0,0,1];

To find out what is the property you need, check the json, it is not very clear but with some trial and error you can understand the structure.

Upvotes: 6

Related Questions