【问题标题】:How to render an animation in and then render it out after it is done playing?如何渲染动画,然后在播放完成后将其渲染出来?
【发布时间】:2020-11-05 08:47:57
【问题描述】:

我的 react 应用有任务供用户完成。用户每完成一项任务,状态就会更新并播放动画。

我希望动画仅在任务完成时出现,并在动画结束后立即消失。我该怎么做?我正在考虑将状态(即playAnimation)设置为false,直到任务完成,然后将其设置为true。然后在 return() 里面我会有一个条件语句,只在状态为真时渲染动画。我会使用 setTimeOut 在动画结束时将状态更改回 false。但是我发现这个解决方案效率很低。

还有其他方法可以做到这一点吗?

function onTaskComplete() {
  //render in animation and then render it out once it finishes playing
}

【问题讨论】:

  • 你是如何制作/显示动画的?
  • 我正在使用 react-lottie 组件,抱歉我应该指定。

标签: javascript html css reactjs jsx


【解决方案1】:

这是您可以实现的。如果不查看更多代码,您将很难准确地提供您想要的。

首先,这是一个发出事件的简单动画函数。您可以使用这些事件从动画代码与 React UI 代码进行通信。

function animate(from, to, duration) {
  const events = {};

  // Basic event emitter, used to communicate from this function to React
  const emitter = {
    on(event, fn) {
      if (!events.hasOwnProperty(event)) {
        events[event] = [];
      }
      events[event].push(fn);
      let index = events.length - 1;
      return () => events[event].splice(index, 1);
    },
    emit(event, data) {
      (events[event] || []).forEach((fn) => fn(data));
    },
  };

  const startTime = Date.now();
  const map = (n, x1, y1, x2, y2) => Math.min(Math.max(((n - x1) * (y2 - x2)) / (y1 - x1) + x2, x2), y2);

  let frame;
  (function update() {
    frame = requestAnimationFrame(update);
    const delta = Date.now() - startTime;
    const value = map(delta, 0, duration, from, to);
    emitter.emit("tick", value);
  })();

  return emitter;
}

以下是在 React 中实现此功能的方法。

function Task(props) {
  const [complete, setComplete] = useState(false);

  useEffect(() => {
    if (!complete) {
      return;
    }

    // Start the animation when this task is complete
    const animation = animate(0, 100, 2000);
    const tickListener = animation.on("tick", (value) => {
      // Animation has updated, do something with the value
      console.log(value);
    });
    const endListener = animation.on("end", () => {
      // Animation has now ended, do something else.
      console.log("Animation ended.");
    });
    // Remove events
    return () => {
      tickListener();
      endListener();
    };
  }, [complete]);

  return null; // Render UI
}

这将在任务标记为completed 时启动动画,并在动画值更改时触发tick(使用它来更新某些内容)。动画结束后,它将发出end,您可以使用它来执行任何附加代码,例如反转动画。

【讨论】:

  • 稍作调整以匹配我的原始代码,效果很好!谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2019-02-03
  • 2018-11-20
  • 2016-04-17
  • 1970-01-01
  • 2022-01-14
  • 2021-07-14
相关资源
最近更新 更多