Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This library is no longer maintained. Making your own simple wrapper isn't difficult... #139

Open
funwithtriangles opened this issue Jan 26, 2022 · 12 comments

Comments

@funwithtriangles
Copy link

funwithtriangles commented Jan 26, 2022

If you need something complex, then react-lottie-player looks good. Otherwise the code below is all you need to display a lottie animation on your page. There is no play/pause logic here but that wouldn't be too tricky to add. Just thought I'd post this in case anyone is wondering how much work it will be to get something working themselves.

import { useEffect, useRef } from "react"

import lottie from "lottie-web"

interface LottieProps {
  animationData: any
  width: number
  height: number
}

export const Lottie = ({ animationData, width, height }: LottieProps) => {
  const element = useRef<HTMLDivElement>(null)
  const lottieInstance = useRef<any>()

  useEffect(() => {
    if (element.current) {
      lottieInstance.current = lottie.loadAnimation({
        animationData,
        container: element.current,
      })
    }
    return () => {
      lottieInstance.current?.destroy()
    }
  }, [animationData])

  return <div style={{ width, height }} ref={element}></div>
}
@granolocks
Copy link

I was getting this vibe too. Sad to see since it worked fairly well but this is a nice base for a shim. Thank you @funwithtriangles

@adrian-burkhart
Copy link

Thanks a lot, this works great for most use-cases and is much cleaner.

@lclarkg18
Copy link

I'm getting a weird error with this code whereby the animations load twice, any ideas? All I can think of is it's related to the usage of the dependancy array in the useEffct but no idea. Thanks btw!

@SwTan98
Copy link

SwTan98 commented Jun 15, 2022

I'm getting a weird error with this code whereby the animations load twice, any ideas? All I can think of is it's related to the usage of the dependancy array in the useEffct but no idea. Thanks btw!

I tried updating the useEffect a little bit, seems to work fine now.

useEffect(() => {
    if (element.current) {
      lottie.loadAnimation({
        animationData,
        container: element.current,
      });
    }
  }, [animationData]);

@evertjr
Copy link

evertjr commented Jun 15, 2022

I'm getting a weird error with this code whereby the animations load twice, any ideas? All I can think of is it's related to the usage of the dependancy array in the useEffct but no idea. Thanks btw!

If you're using React 18, useEffect runs twice on mount to make sure the code is idempotent. (only happens in development) And since we are using it to render an animation to the DOM, it explains why this happens.

A workaround is using useRef like this:

const element = useRef(null);
  const lottieInstance = useRef();
  const executeRef = useRef(false);

  useEffect(() => {
    if (executeRef.current) return;
    if (element.current) {
      lottieInstance.current = lottie.loadAnimation({
        animationData,
        loop,
        autoplay,
        container: element.current,
      });
    }
    executeRef.current = true;
  }, []);

@chrisnojima
Copy link

hi,

just a heads up this will leak your instances as it's not actually calling destroy on lottieInstance.current. I'd add something like

  React.useEffect(() => {
    if (element.current) {
      lottieInstance.current?.destroy()
      lottieInstance.current = lottie.loadAnimation({
        animationData,
        container: element.current,
      })
    }
    return () => {
      lottieInstance.current?.destroy()
      lottieInstance.current = null
    }
  }, [animationData])

@funwithtriangles
Copy link
Author

hi,

just a heads up this will leak your instances as it's not actually calling destroy on lottieInstance.current. I'd add something like

  React.useEffect(() => {
    if (element.current) {
      lottieInstance.current?.destroy()
      lottieInstance.current = lottie.loadAnimation({
        animationData,
        container: element.current,
      })
    }
    return () => {
      lottieInstance.current?.destroy()
      lottieInstance.current = null
    }
  }, [animationData])

Good point! I updated my example above. Pretty sure you don't need to have the destroy twice though, the clean up return function will happen before the effect runs every time.

@jordanlambrecht
Copy link

@funwithtriangles Could you help me get segments to work with this? I can't seem to figure it out. I'm trying to get it to play all frames on the first loop, and then only frames 24-95 on every loop thereafter.

Currently, I have:
segments: {[ [0, 23],[24, 95]], true},

@funwithtriangles
Copy link
Author

funwithtriangles commented Aug 9, 2022

@funwithtriangles Could you help me get segments to work with this? I can't seem to figure it out. I'm trying to get it to play all frames on the first loop, and then only frames 24-95 on every loop thereafter.

Currently, I have: segments: {[ [0, 23],[24, 95]], true},

Sorry, I don't know the API very well! I was just posting a simple example that I thought might help others with similar simple needs. If you need anything more complex, then maybe react-lottie-player is more suitable.

@itayperry
Copy link

Hi @funwithtriangles,
I looked into lottie-web and sadly it is not really seriously maintained either.. the dependencies are mostly extremely old 😔
It seems that everything lottie-related is being a bit neglected.
Is there anything that could replace lottie?

@funwithtriangles
Copy link
Author

Hi @funwithtriangles, I looked into lottie-web and sadly it is not really seriously maintained either.. the dependencies are mostly extremely old 😔 It seems that everything lottie-related is being a bit neglected. Is there anything that could replace lottie?

I'd just be googling the same as you, sorry. Haven't touched anything lottie in quite a while and was never an expert 😅. Good luck! And feel free to tag me here if you find a good solution, I can update my top comment for others in the future.

@itayperry
Copy link

I'd just be googling the same as you, sorry. Haven't touched anything lottie in quite a while and was never an expert 😅. Good luck! And feel free to tag me here if you find a good solution, I can update my top comment for others in the future.

Oh I see, thank you for replying so fast! I hope to find something someday.

I currently use Rive Editor that creates riv files. You can install
@rive-app/react-canvas to use these files.
You can also drag and drop JSON animations in the editor and sometimes it'll convert them perfectly.. but only sometimes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants