JavaScript 详解缓动动画的封装与使用

2023-12-09前端开发
16

JavaScript 详解缓动动画的封装与使用

概述

缓动动画是一种常见的动画效果,它在动画运行初期速度较快,在结束时速度逐渐减慢,运动距离也逐渐减小,这种动画效果更符合人眼的视觉特性,所以受到广泛的应用。

在 JavaScript 中,我们可以通过封装函数来实现缓动动画,下面我们就来详细讲解一下。

实现思路

首先,我们需要知道缓动动画的原理,即在动画过程中,物体运动的距离和时间之间并不具有线性关系,而是一个缓动函数的结果,比如说我们常用的 ease-in-out 函数。因此,我们需要封装一个可以接受运行时间、起始位置、结束位置、缓动函数等参数的缓动动画函数。

具体实现思路如下:

  1. 获取当前时间与起始时间
  2. 计算时间差,计算当前位置
  3. 判断动画是否结束,如果未结束,继续运动,并在下一帧继续执行缓动函数
  4. 如果动画已结束,则清除定时器

示例

下面给出两个示例,一个是缓动函数的实现,一个是缓动动画的封装。

缓动函数的实现

/**
 * 缓动函数
 * @param {number} t 当前时间
 * @param {number} b 初始值
 * @param {number} c 变化量
 * @param {number} d 持续时间
 * @return {number} 当前值
 */
function easeInOutQuad(t, b, c, d) {
  t /= d/2;
  if (t < 1) return c/2*t*t + b;
  t--;
  return -c/2 * (t*(t-2) - 1) + b;
}

上面的代码中,我们实现了一个缓动函数 easeInOutQuad,它接受当前时间 t,初始值 b,变化量 c 和持续时间 d 作为参数,并返回当前值。

缓动动画的封装

/**
 * 缓动动画函数
 * @param {HTMLElement} ele 动画元素
 * @param {object} target 动画目标值
 * @param {number} duration 动画持续时间
 * @param {function} easing 缓动函数
 */
function animate(ele, target, duration, easing) {
  // 记录动画起始时间
  const startTime = new Date().getTime();
  // 记录动画初始值
  const startStyle = {};

  for (const key in target) {
    startStyle[key] = parseInt(getComputedStyle(ele)[key]);
  }

  const tick = () => {
    // 计算时间差和当前值
    const elapsed = new Date().getTime() - startTime;
    const ratio = elapsed / duration;
    const progress = easing(ratio, 0, 1, 1);

    for (const key in target) {
      const value = startStyle[key] + (target[key] - startStyle[key]) * progress;
      ele.style[key] = value + 'px';
    }

    if (elapsed < duration) {
      // 动画未结束,继续运动
      requestAnimationFrame(tick);
    } else {
      // 动画结束,清除定时器
      for (const key in target) {
        ele.style[key] = target[key] + 'px';
      }
    }
  };

  tick();
}

上面的代码中,我们实现了一个 animate 函数,它接受动画元素 ele、动画目标值 target、动画持续时间 duration 和缓动函数 easing 作为参数,并实现了缓动动画的封装。

其中,我们首先记录动画起始时间和元素的初始值,在每一帧计算当前值,并根据缓动函数获取当前进度,最后根据计算得到的目标值判断动画是否结束,如果未结束,则继续使用 requestAnimationFrame 函数继续执行缓动函数。

总结

缓动动画的实现需要封装缓动函数和缓动动画函数。实现缓动函数需要了解缓动动画的计算原理,而实现缓动动画函数则需要对缓动函数进行合理的调用和适当的封装,以实现复杂的动画效果。

The End

相关推荐

layui实现图片上传成功后回显点击放大图片功能
layui实现图片上传成功后回显点击放大图片功能,html代码部分: !-- html代码--div class="layui-form-item" label class="layui-form-label"上传图片/label div class="layui-input-block" button type="button" class="layui-btn" id="license-auth-letter-...
2025-09-06 前端开发
202

Layui实现数据表格中鼠标悬停图片放大离开时恢复原图
Layui实现数据表格中鼠标悬停图片放大离开时恢复原图的效果,最终效果如下图所示: 实现代码如下,在done函数中调用hoverOpenImg方法 var tableIns = window.demoTable = table .render({ elem : '#idTest', id : 'idTest', url : '/postData', //width : 150...
2025-09-04 前端开发
112

layui点击文本输入框调起弹出选择框并选择内容的两种方法参考
我们在用到layui时候,需要点击文本输入框调起弹出选择框并选择内容,这个要怎么操作呢?以下两种方法可以参考: 1、点击名称,弹出信息弹框,选择表格中的某一行,实现效果如下: html页面代码 !--计量器具弹出层-- div id="equipment" lay-filter="equipmen...
2025-09-02 前端开发
167

网站部署https后百度地图不显示问题
https的网站如果引用百度地图,会出现加载不了的问题,这是因为涉及到跨域问题,网站是https的,但是引用百度地图的是http的,这个要怎么操作呢? 比如我引用的地址:http://api.map.baidu.com/api?v=2.0ak=AK显示 后来看了一下,少了一个s=1字段,加一下s=1...
2025-07-28 前端开发
139

微信小程序实现点击复制功能和手机拨打电话功能
做小程序项目的时候,客户提了一个功能需求优化,就是长按文字需要复制全部内容,因为有的手机支持全选复制,有的手机不支持全选复制。 通过设置系统剪贴板的内容和获取系统剪贴板的内容实现复制功能 html相关代码: van-field value="{{form.contactPhone}}"...
2025-07-02 前端开发
78

js拖拽排序插件Sortable.js如何使用
由于项目功能需要,要实现对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好的满足这个需求,而且它还是开源的,于是乎就开始学习使用Sortable.js 特点 轻量级但功能强大 移动列表项时有动画 支持触屏设备和大多数浏览器(IE9及以下除外) 支持...
2025-06-12 前端开发
161