高阶函数应用之封装动画函数

70 阅读2分钟

动画原理

js 动画函数

动画的本质是什么?

动画的本质就是在一段时间之内,从一个数字变成另一个数字。

比如元素的宽高、颜色(RGB)

封装一个动画函数

function animation(duration, from, to) {
  const dis = to - from; // 变化的距离
  const speed = dis / duration // 变化的速度
  const startTime = Date.now(); // 记录开始的时间
  let value = from; // 记录当前的值

  function _run() { // 根据当前的值算出一个新的值
    const now = Date.now(); // 当前的时间
    const time = now - startTime; // 从起始时间算起,到现在流逝的时间
    if(time >= duration) { // 如果运行的时间 >= 设置的时间
      value = to;
      return;
    }
    const d = time * speed; // 计算变化的距离
    value = from + d; // 起始值 + 距离 = 当前的值

    requestAnimationFrame(_run);
  }

  requestAnimationFrame(_run); // 在下次渲染的时候调用这个值
}

实际上还有很多需要注意的点,比如只在整数时触发,如果不是匀速变化就需要用到贝塞尔曲线函数

传入一个函数来告诉如何处理当前的值

到这里,这个函数还不能使用,需要传入一个运算(函数)来告诉如何处理值。这样既保证了通用性,也能适应未来需求的变化。

function animation(duration, from, to, onProgress) {
  const dis = to - from; // 变化的距离
  const speed = dis / duration // 变化的速度
  const startTime = Date.now(); // 记录开始的时间
  let value = from; // 记录当前的值

  onProgress(value);

  function _run() { // 根据当前的值算出一个新的值
    const now = Date.now(); // 当前的时间
    const time = now - startTime; // 从起始时间算起,到现在流逝的时间
    if(time >= duration) { // 如果运行的时间 >= 设置的时间
      value = to;
      onProgress(value);
      return;
    }
    const d = time * speed; // 计算变化的距离
    value = from + d; // 起始值 + 距离 = 当前的值
    
  	onProgress(value);
    
    requestAnimationFrame(_run);
  }

  requestAnimationFrame(_run); // 在下次渲染的时候调用这个值
}

实际运行效果如下: