Heril Muratovic
Heril Muratovic

Reputation: 2018

React Native Lottie View Animation Play/Pause Issue

I'm using React Native Lottie Wrapper to show animation on screen.
I need a functionality to play/pause/resume animation.

Here is my a part of my code:

...

constructor(props) {
  super(props);
  this.state = {
    progress: new Animated.Value(0)
  };
}

static navigationOptions = {
  title: "Details",
  headerStyle: {
    backgroundColor: '#f4511e',
  },
  headerTintColor: '#fff',
  headerTitleStyle: {
    fontWeight: 'bold',
  },
  headerTruncatedBackTitle: 'List'
};

componentDidMount() {
  this.animation.play();
}

playLottie() {
 console.log('play');
}

pauseLottie() {
  console.log('pause');
}

render() {
  return (
    <View>
      <Animation
        ref={animation => { this.animation = animation; }}
        source={require('../../../../assets/anim/balloons.json')}
        style={{height: 300, width: '100%'}}
        loop={false}
        progress={this.state.progress}
      />
      <Text>Course with id: {this.props.navigation.state.params.courseId}</Text>
        <Button 
          onPress={this.playLottie}
          title="Play Lottie"
          color="#841584"
          accessibilityLabel="Play video"
        />
        <Button 
          onPress={this.pauseLottie}
          title="Pause Lottie"
          color="#841584"
          accessibilityLabel="Pause video"
        />
     </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

...

The animation is playing well but I can't pause it and resume it.
Does anyone have a solution for this problem?

P.S. I have tried to use this.animation in pauseLottie() method but it said that is undefined.

Thank you in advance!

Upvotes: 7

Views: 12758

Answers (4)

beee
beee

Reputation: 482

If you use an Lottie animation that contains a loop you can control it all with the LottieView api built in. (if you are using a file that has the animation)

import Lottie from 'lottie-react-native'

const ref = useRef<AnimatedLottieView>()

const pause = () => { 
   ref.current.pause()
}

const resume = () => { 
   ref.current.resume()
}

const reset = () => { 
   ref.current.reset()
}

<Lottie
  ref={ref}
  source={source}
  resizeMode={resizeMode}
  loop={true}
  duration={duration}
  autoPlay={true}
  onAnimationFinish={onFinish}
/>

Upvotes: 0

Heril Muratovic
Heril Muratovic

Reputation: 2018

for me it didn't work well: we have to add setValue(0), then we need to improve pause/restart to maintain the playing speed and change easing function to avoid slow re-start. Let's also add looping:

constructor(props) {
  super(props);
  this.playLottie.bind(this);
  this.pauseLottie.bind(this);
  this.state = {
    progress: new Animated.Value(0),
    pausedProgress: 0
  };
}

playLottie = () => {
  Animated.timing(this.state.progress, {
    toValue: 1,
    duration: (10000 * (1 - this.state.pausedProgress)),
    easing: Easing.linear,
  }).start((value) => { 
    if (value.finished) this.restartAnimation();
  });
}

restartAnimation = () => {
  this.state.progress.setValue(0);
  this.setState({ pausedProgress: 0 });
  this.playAnimation();
}

pauseLottie = () => {
  this.state.progress.stopAnimation(this.realProgress);
}

realProgress = (value) => {
  console.log(value);
  this.setState({ pausedProgress: value });
};
...

(Now) For me, it's working fine! Play and pause option work as expected.

Upvotes: 1

pedrosimao
pedrosimao

Reputation: 397

You can pause and play Lottie animation by changing the speed prop, where speed={0} puts LottieView component in pause and speed={1} plays it at normal speed.

Here is an example:

playAnimation = () => {
    this.setState({speed: 1})
}

pauseAnimation = () => {
    this.setState({speed: 0})
}

<LottieView
    source={this.state.sourceAnimation}
    speed={this.state.speed} />

Upvotes: 9

parohy
parohy

Reputation: 2180

You have to set the state from the play/pause functions. In order to access the state of the Component, you have to bind the function to the component class:

First option in your constructor:

constructor(props) {
  super(props);
  this.playLottie.bind(this);
  this.pauseLottie.bind(this);
}

or second option when declaring inside class use the es6 function syntax:

playLottie = () => {
 ...
}

pauseLottie = () => {
 ...
}

Inside those function call setState and add the value you want to set it to. In your case I would:

playLottie = () => {
  this.setState({ progress: true })
}

pauseLottie = () => {
  this.setState({ progress: false })
}

It is important you bind those two functions to your class component, because you will not be able to access component props. Thats why it is throwing you an error setState is not a function

Your render looks good ;)

Upvotes: 1

Related Questions