【青训营】- CSS 动画和 JS 动画是如何实现的?

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

动画分类

CSS 动画

transition 动画

CSS 形变主要是由 transform 属性来实现的,常用的函数有以下几种:

  • translate(x, y) 位移
  • scale(x, y) 缩放
  • rotate(x) 旋转
  • skew(x, y) 倾斜

我们可以使用 transition 属性让浏览器实现补间动画(只定义初始和目标形态,由浏览器生成中间形态),看一下 transition 的使用:

 div {
     transition: <property> <duration> <timing-funcation> <delay>;
 }
复制代码
  • <property>:指定那个CSS属性用于过渡
  • <duration>:指定过渡所用的时长
  • <timing-funcation>:指定过渡的属性值的变化函数
  • <delay>:开始距变化的时长

实例 1 :transition 动画 (codepen.io)

animation 动画

实现 animation 动画需要先定义一个 keyframe ,格式如下:

 @keyframes slidein {
   from {
     transform: translateX(0%);
   }
     
   50% {
     transform: scale(1.5);
   }
     
   to {
     transform: translateX(100%);
       transform: scale(1);
   }
 }
复制代码

然后使用:

 div {
     animation: <name> <delay> <duration> <timing-function>;
 }
复制代码

实例2:animation 动画 (codepen.io)

总结

优点:简单、高效、声明式 不依赖主线程,采用硬件加速

缺点:不能动态修改或定义,不同动画不能实现同步

推荐使用:animation.css、shake.css

SVG 动画

SVG 是基于 XML 的矢量图形描述语言,它可以与 CSS 和 JS 较好的配合。

我还不太懂 SVG 动画,所以只能说一下绘制基础的:

  • <path d="..."> 形如此类的是 SVG 图形的基本格式
  • M/m 表示绘制起点
  • L/l 表示绘制线段
  • C/c 表示绘制贝塞尔曲线
  • Z/z 表示将当前点与起始点用直线连接

其中,大写字母表示绝对坐标,小写字母表示相对坐标

JS 动画

JS 动画实现推荐使用 requestAnimationFrame() 函数,该内置方法允许设置回调函数以在浏览器准备重绘时运行。当页面在后台时,根本没有重绘,所以回调不会运行:动画被暂停且不消耗资源。

绘制计时函数应当使用 performance.now() 函数,performance.now() 将会以恒定速度递增,精确到微秒级别,不易被篡改。

我们可以将动画函数进行简易封装:

 function  animate(timing, draw, duration){
     let start = performance.now();
     requestAnimationFrame(function animate(time){
         let timeFraction = (time - start) / duration;
         if (timeFraction > 1) timeFraction = 1;
         
         let progress = timing(timeFraction);
         
         draw(progress);
         
         if (timeFraction < 1){
             requestAnimationFrame(animate);
         }
     });
 }
复制代码
  • timing() 计算动画进度
  • duration 总动画时间
  • draw() 绘画函数

实现一个匀速运动

 const linear = () => {
   const draw = (progress) => {
     train.style.transform = `translate(${progress}px, 0)`;
   }
 ​
   // 沿着x轴匀速运动
   animate({
     duration: 1000,
     timing(timeFraction) {
       return timeFraction * 100;
     },
     draw,
   });
 };
复制代码

实例3:JS 点我让小球动起来 (codepen.io)

就这一种函数封装就可以实现很多实例,有时间的话和大家一起接着分析。

总结

MDN是个好东西

参考资料

  1. animation – CSS: Cascading Style Sheets | MDN (mozilla.org)
  2. transition – CSS: Cascading Style Sheets | MDN (mozilla.org)
  3. transform – CSS: Cascading Style Sheets | MDN (mozilla.org)
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享