4

I am using the react-bodymovin package (https://www.npmjs.com/package/react-bodymovin) to embed a Bodymovin animation, but I wanted to loop a section of the animation after it has played through once.

I can see is simple using the HTML version of Bodymovin, as you simply use the relevant methods to do this, for example, (assuming the div has ID bodymovin:

const params = {
    container: document.getElementById('bodymovin'),
    renderer: 'svg',
    loop: false,
    autoplay: false,
    animationData: animationData,
}

const anim = bodymovin.loadAnimation(params)

anim.playSegments([[0, 65]], true)

However, I am not sure how to access these same methods when using the React component. Here is my component:

import React from 'react'
import ReactBodymovin from 'react-bodymovin'
import animation from './animation.json'

const App = () => {
  const bodymovinOptions = {
    loop: true,
    autoplay: true,
    prerender: true,
    animationData: animation
  }

  return (
    <div>
      <ReactBodymovin options={bodymovinOptions} />
    </div>
  )
}

I have a feeling that due to the nature of the way this React wrapper works with Bodymovin, it may not be possible to access the methods within the file, but if anyone knows a way to do this, i would love to hear it. Thanks.

Oli C
  • 1,120
  • 13
  • 36
  • this looks interesting, can you have the stackblitz of the HTML ONLY not react, never used bodymovin so I don't really know what you looking for – Renaldo Balaj Nov 29 '19 at 14:32

1 Answers1

3

Why don't you try react-lottie package instead? It has way more npm-downloads than react-bodymovin and you can achieve what you want and play segments like so:

import React from 'react'
import animation from './animation.json'

import Lottie from 'react-lottie';

const App = () => {
  const options= {
    loop: true,
    autoplay: true,
    prerender: true,
    animationData: animation
  }

  return (
    <div>
      <Lottie options={options} segments={[0, 65]} />
    </div>
  )
}

However, with both packges you won't have full control over the lottie object and thus can't call methods like loadAnimation or loadSegments manually. However you could use the lottie-web package like you would do in normal javascript, just as you have shown. Here is an example how you should do it in react with hooks:

import React, { useEffect, useRef } from "react";
import lottie from "lottie-web";
import animation from "./animation.json";

const App = () => {
 const animContainer = useRef<HTMLDivElement>(null);

 useEffect(() => {
    if (ref.current) {
      const anim = lottie.loadAnimation({
        container: animContainer.current,
        renderer: "svg",
        loop: true,
        autoplay: true,
        animationData: animation
      });

     anim.playSegments([[0, 65]], true);
    }
  });

  return <div ref={animContainer}></div>;
}
oemera
  • 3,223
  • 1
  • 19
  • 33
  • 1
    Thanks for the response, I actually did move to the Lottie plugin, but even with the segments attribute set as in your example, the animation plays from start to finish rather than looping a certain section. – Oli C Dec 01 '19 at 14:23
  • 1
    Hmm thats unfortunate, does the other example with `lottie-web` only work? There is an issue that is somewhat related to that already: https://github.com/chenqingspring/react-lottie/issues/82 If you want you can create a new issue to address this problem. – oemera Dec 01 '19 at 14:41
  • 1
    No, that also didn't work, so I will try and make sure the Lottie team know. Thanks for the help oemera. – Oli C Dec 02 '19 at 12:34