Web Animations API 教程

06-01 1015阅读

Web Animations API 教程

简介

Web Animations API (WAAPI) 是一个提供给 JavaScript 开发者用于创建和控制网页动画的接口。它结合了 CSS 动画和 JavaScript 动画的优点,提供了一个高性能且易于使用的动画解决方案。

主要优势

  • 性能优化:直接使用浏览器的动画引擎,与 CSS 动画性能相当
  • 精确控制:提供比 CSS 更精细的动画控制能力
  • 动态性:可以根据用户交互或其他条件动态生成和调整动画
  • 统一标准:提供一个标准化的 API,减少对第三方库的依赖

    基本概念

    Web Animations API 主要由以下几个核心概念组成:

    1. Element.animate() - 创建动画的主要方法
    2. KeyframeEffect - 定义动画变化的关键帧
    3. Animation - 提供控制动画播放的接口
    4. AnimationTimeline - 控制动画的时间线

    创建简单动画

    使用 Element.animate() 方法可以快速创建一个基本动画:

    const element = document.querySelector('.box');
    // 创建一个简单的移动动画
    const animation = element.animate(
      [
        // 关键帧
        { transform: 'translateX(0px)' },
        { transform: 'translateX(300px)' }
      ],
      {
        // 动画配置
        duration: 1000,     // 持续时间(毫秒)
        easing: 'ease-in-out', // 动画缓动函数
        delay: 0,           // 延迟时间
        iterations: Infinity, // 重复次数(无限循环)
        direction: 'alternate', // 方向(交替)
        fill: 'forwards'    // 填充模式(保持最终状态)
      }
    );
    

    控制动画

    Animation 对象提供了多种方法来控制动画的播放状态:

    // 暂停动画
    animation.pause();
    // 继续播放
    animation.play();
    // 反向播放
    animation.reverse();
    // 取消动画
    animation.cancel();
    // 完成动画(跳到结束)
    animation.finish();
    // 设置动画速度
    animation.playbackRate = 2; // 2倍速播放
    

    你还可以获取动画的各种状态:

    // 获取当前播放状态
    console.log(animation.playState); // 'running', 'paused', 'finished', 'idle'
    // 检查动画是否正在播放
    console.log(animation.pending);
    // 获取当前播放时间
    console.log(animation.currentTime);
    

    动画时间轴

    时间轴控制动画的时间流向:

    // 获取当前动画时间
    const currentTime = animation.currentTime;
    // 设置动画时间(跳转到特定位置)
    animation.currentTime = 500; // 跳转到500毫秒处
    

    关键帧格式

    关键帧可以通过多种方式定义:

    数组对象格式

    element.animate([
      { opacity: 0, transform: 'scale(0.5)' },  // 起始帧
      { opacity: 0.5, transform: 'scale(0.75)' }, // 中间帧
      { opacity: 1, transform: 'scale(1)' }     // 结束帧
    ], 1000);
    

    带偏移量的对象

    element.animate({
      opacity: [0, 0.5, 1],
      transform: ['scale(0.5)', 'scale(0.75)', 'scale(1)'],
      offset: [0, 0.7, 1] // 指定每个关键帧的时间点
    }, 1000);
    

    使用 KeyframeEffect

    const keyframes = new KeyframeEffect(
      element,
      [
        { transform: 'translateX(0)' },
        { transform: 'translateX(100px)' }
      ],
      { duration: 1000, fill: 'forwards' }
    );
    const animation = new Animation(keyframes, document.timeline);
    animation.play();
    

    动画事件

    你可以监听动画的各种事件:

    // 动画开始
    animation.onfinish = () => {
      console.log('动画结束了!');
    };
    // 使用 Promise 方式
    animation.finished.then(() => {
      console.log('动画完成!');
    }).catch(() => {
      console.log('动画被取消');
    });
    // 监听动画取消
    animation.oncancel = () => {
      console.log('动画被取消');
    };
    

    高级应用

    时序组合

    使用 GroupEffect 可以组合多个动画:

    // 注意:GroupEffect 仍处于实验阶段,可能需要使用 polyfill
    const moveEffect = new KeyframeEffect(
      boxElement,
      { transform: ['translateX(0)', 'translateX(300px)'] },
      { duration: 1000, fill: 'forwards' }
    );
    const fadeEffect = new KeyframeEffect(
      boxElement,
      { opacity: [1, 0] },
      { duration: 1000, fill: 'forwards' }
    );
    // 创建组效果
    const groupEffect = new GroupEffect([moveEffect, fadeEffect]);
    const animation = new Animation(groupEffect, document.timeline);
    animation.play();
    

    创建可复用的动画模板

    function createFadeAnimation(element, duration = 1000) {
      return element.animate(
        [
          { opacity: 0 },
          { opacity: 1 }
        ],
        {
          duration: duration,
          fill: 'forwards'
        }
      );
    }
    // 使用模板创建多个动画
    const elements = document.querySelectorAll('.item');
    elements.forEach((el, index) => {
      const anim = createFadeAnimation(el);
      // 延迟开始
      anim.startTime = document.timeline.currentTime + (index * 100);
    });
    

    浏览器兼容性

    Web Animations API 现已在大多数现代浏览器中得到支持。对于旧版浏览器,可以使用 web-animations-js polyfill。

    // 检测浏览器支持
    if (!Element.prototype.animate) {
      console.log('浏览器不支持 Web Animations API,需要使用 polyfill');
    }
    

    与CSS动画对比

    特性Web Animations APICSS 动画
    性能非常好(与CSS相当)非常好
    控制能力强大,可编程控制有限,需通过JS间接控制
    动态生成方便,原生JS支持需要生成或修改CSS
    复杂度中等简单
    兼容性需要polyfill广泛支持

    性能优化

    使用 Web Animations API 时的性能最佳实践:

    1. 尽量只动画 transform 和 opacity 属性

      这些属性可以在合成器线程上执行,不会触发布局和绘制。

    2. 避免频繁修改动画参数

      频繁修改动画参数可能导致主线程阻塞。

      Web Animations API 教程
      (图片来源网络,侵删)
    3. 使用 will-change 提前告知浏览器

      .animated-element {
        will-change: transform, opacity;
      }
      
    4. 在必要时取消不可见元素的动画

      Web Animations API 教程
      (图片来源网络,侵删)
      if (!elementIsVisible) {
        animation.cancel();
      }
      

    实例项目

    示例1:图片轮播

    const slides = document.querySelectorAll('.slide');
    let currentSlide = 0;
    function rotateSlides() {
      // 当前幻灯片退出
      slides[currentSlide].animate(
        [
          { opacity: 1, transform: 'translateX(0)' },
          { opacity: 0, transform: 'translateX(-100px)' }
        ],
        { duration: 500, fill: 'forwards' }
      );
      
      // 更新当前幻灯片索引
      currentSlide = (currentSlide + 1) % slides.length;
      
      // 新幻灯片进入
      slides[currentSlide].animate(
        [
          { opacity: 0, transform: 'translateX(100px)' },
          { opacity: 1, transform: 'translateX(0)' }
        ],
        { duration: 500, fill: 'forwards' }
      );
    }
    // 每3秒切换一次
    setInterval(rotateSlides, 3000);
    

    示例2:自定义路径动画

    // 定义一个复杂的运动路径
    function animateAlongPath(element, duration = 2000) {
      return element.animate([
        { offset: 0, transform: 'translate(0, 0)' },
        { offset: 0.25, transform: 'translate(100px, 0)' },
        { offset: 0.5, transform: 'translate(100px, 100px)' },
        { offset: 0.75, transform: 'translate(0, 100px)' },
        { offset: 1, transform: 'translate(0, 0)' }
      ], {
        duration: duration,
        easing: 'ease-in-out',
        iterations: Infinity
      });
    }
    const box = document.querySelector('.moving-box');
    const pathAnimation = animateAlongPath(box);
    // 用户控制
    document.querySelector('#speed-control').addEventListener('input', (e) => {
      pathAnimation.playbackRate = e.target.value;
    });
    

    示例3:顺序动画

    async function sequentialAnimation() {
      const element = document.querySelector('.animated-element');
      
      // 第一个动画:旋转
      const rotate = element.animate(
        [
          { transform: 'rotate(0deg)' },
          { transform: 'rotate(360deg)' }
        ],
        { duration: 1000, fill: 'forwards' }
      );
      
      // 等待第一个动画完成
      await rotate.finished;
      
      // 第二个动画:缩放
      const scale = element.animate(
        [
          { transform: 'scale(1)' },
          { transform: 'scale(1.5)' },
          { transform: 'scale(1)' }
        ],
        { duration: 1000, fill: 'forwards' }
      );
      
      // 等待第二个动画完成
      await scale.finished;
      
      // 第三个动画:移动
      return element.animate(
        [
          { transform: 'translateY(0)' },
          { transform: 'translateY(100px)' },
          { transform: 'translateY(0)' }
        ],
        { duration: 1000, fill: 'forwards' }
      );
    }
    // 启动顺序动画
    sequentialAnimation().then(() => {
      console.log('所有动画序列完成!');
    });
    

    总结

    Web Animations API 为开发者提供了一个标准化、高性能且灵活的动画创建方式。它结合了 CSS 动画的性能和 JavaScript 动画的可编程性,特别适合需要精确控制或复杂动画逻辑的场景。

    随着浏览器支持度的提高,Web Animations API 正在成为前端动画开发的重要工具。在合适的项目中使用它,可以帮助我们创建流畅、高效的网页动画效果,提升用户体验。

    Web Animations API 教程
    (图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码