简体   繁体   English

如何制作基于 Lottie 动画进度更新的 Slider(React-Native)

[英]How to make a Slider that updates based on Lottie animation progress (React-Native)

I'm trying to get a Slider to update its position based upon the Progress value of a Lottie animation.我正在尝试让 Slider 根据 Lottie 动画的 Progress 值更新其位置。 The Slider can control the Lottie's Progress, but it doesn't update its position if I press the "Play Lottie" Button. Slider 可以控制 Lottie 的进度,但如果我按下“Play Lottie”按钮,它不会更新其位置。 How can I have components access the Lottie's Progress value and update based on what the Progress value is?如何让组件访问 Lottie 的 Progress 值并根据 Progress 值进行更新? I want this value to be public or accessible from other components.我希望这个值是公开的或者可以从其他组件访问。 It seems like the Progress value isn't accessible by outside components.外部组件似乎无法访问 Progress 值。 I tried "addListener," but it doesn't do anything.我试过“addListener”,但它没有做任何事情。

I'm new to react-native and coding in general.我是本机反应和一般编码的新手。 I've looked around StackOverflow for many days and couldn't find anything.我已经环顾 StackOverflow 很多天了,但找不到任何东西。

export default class HomeScreen extends React.Component {
    constructor(props) {
        super(props);
        this.playLottie.bind(this);
        this.playLottie.bind(this);
        this.pauseLottie.bind(this);
        this.state = {
            progress: new Animated.Value(0),
            pausedProgress: 0
        };
        this.state.progress.addListener(({ value }) => this._value = value); // I tried to use a Listener so that components can Listen to the Progress of the lottie animation...
    }

    playLottie = () => {
        Animated.timing(this.state.progress, {
            toValue: 1,
            easing: Easing.linear,

        }).start;
    }

    //Shows real-time value of the Slider. Console output works too, updates when I use slider in realtime.
    realProgress = (value) => {
        console.log("realProgress", value);
        this.setState({ pausedProgress: value });
    };

    //Used by Slider, sets Progress of Lottie
    setProgress = (value) => {
        this.state.progress.setValue(value);
        console.log("setProgress", value)
    };

    render() {
        return (

            <View style={styles.container}>
                <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
                //The Lottie Animation:
                <LottieView
                        ref={animation => { this.animation = animation; }}
                        source={require('../assets/lottie-animations/animation.json')}
                        style={{ height: 400, width: '100%' }}
                        loop={false}
                        progress={this.state.progress}
                />

                <Button
                    onPress={this.playLottie}
                    title="Play Lottie"
                />
                <Button
                    onPress={this.pauseLottie}
                    title="Pause Lottie"
                    />

                //The slider that controls the progress of the Lottie Animation:
                <Slider
                    style={{ width: '100%', height: 40 }}
                    minimumValue={0}
                    maximumValue={1}
                    onValueChange={(value) => this.setProgress(value)}
                />

                //Tried using Text to display the real-time value of the Lottie animation progress. Doesn't display any numbers.
                <Text>{'Slider Position: '}{Slider.onValueChange}</Text>

                </ScrollView>
            </View>

        );
    }
}

Relevant dependencies:相关依赖:

"dependencies": {
    "expo": "~36.0.0",
    "lottie-react-native": "^3.3.2",
    "react": "~16.9.0",
    "react-lottie": "^1.2.3",
    "react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz",
  },

Expo Version: 3.13.8世博版:3.13.8
Windows 10视窗 10

Use imperative API it is much simpler.使用命令式 API 就简单多了。

Constructor构造函数

  constructor(props) {
    super(props);

    this.state = {
      progress: 0,
    }
  }

Use the componentDidMount for testing.使用 componentDidMount 进行测试。 play(startFrame, EndFrame). You will need to find out the animations end frame number to use with the slider.您需要找出与滑块一起使用的动画结束帧编号。 Keep changing the endframe until it plays until the end --that's your number.不断改变结束帧,直到它播放到最后——这就是你的号码。

  componentDidMount() {
    // Or set a specific startFrame and endFrame with:
    // this.animation.play(0, 100);
  }

An arrow function that returns the value and changes the state of progress.返回值并更改进度状态的箭头函数。 You can set the animation frame rate to start and stop on the same frame.您可以将动画帧速率设置为在同一帧上开始和停止。

  animateIt = (value) => {
    //this.animation.reset();
    this.setState({progress: value})
    this.animation.play(value, value);
  }

Your lottie component你的乐透组件

  <LottieView
    ref={animation => {
      this.animation = animation;
    }}
    style={{ height: 400, width: '100%' }}
    source={require('../assets/lottie-animations/animation.json')}
  />

Your slider set the maximum value to equal the last frame of the animation.您的滑块将最大值设置为等于动画的最后一帧。 In my case it was 40. Also the slider calls the arrow function and returns the value.在我的例子中它是 40。滑块也调用箭头函数并返回值。

  <Slider
      style={{ width: '100%', height: 40 }}
      minimumValue={0}
      maximumValue={40}
      onValueChange={(value) => this.animateIt(value)}
  />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM