IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    CSS animation-composition可以让动画效果累加

    张 鑫旭发表于 2025-05-12 15:58:01
    love 0

    by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11689
    本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。

    一、前言

    CSS animation-composition属性其实出来有一段时间了,2年多,见下面的附图,之前有见人分享过,最近有人在上一篇文章评论区提过,才想起了他,决定写篇文章简单记录下。

    animation-composition兼容性

    这个属性可以设置CSS动画效果再执行的时候,相关的CSS属性值是替换、直接相加还是计算累积。

    二、animation-composition语法和案例

    其语法如下所示:

    /* 三个动画值 */
    animation-composition: replace;
    animation-composition: add;
    animation-composition: accumulate;
    
    /* 多个动画 */
    animation-composition: replace, add;
    animation-composition: add, accumulate;
    animation-composition: replace, add, accumulate;

    这里出现了3个值replace, add, accumulate就是animation-composition支持的几个关键字值,其含义分别如下:

    replace
    这是默认值。动画也就是@keyframes{}声明的CSS属性会替换默认设置的CSS属性值。
    add
    属性值直接相加。
    accumulate
    属性值计算叠加。accumulate和add比较类似,很多同学会搞不清楚,下面会有案例示意。

    add和accumulate的区别

    • add是纯粹的属性值相加。
    • accumulate则是累加计算后的值。

    在大绝多数情况下,add和accumulate两个值的表现是没有区别的,只有当CSS属性值相连和叠加的渲染效果不一样的时候才会有区别。

    所以:

    1. 普通CSS属性两者无区别

    <canvas id="ball1" class="ball"></canvas>
    <canvas id="ball2" class="ball"></canvas>
    <p>
      <button 
        onclick="ball1.classList.toggle('active');ball2.classList.toggle('active')"
      >运动</button>
    </p>
    .ball {
      width: 120px; height: 120px;
      background: deepskyblue;
      border-radius: 50%;
      position: relative;
      left: 100px;
    }
    #ball1.active {
      animation: 2s move infinite;
      animation-composition: add;
    }
    #ball2.active {
      animation: 2s move infinite;
      animation-composition: accumulate;
    }
    @keyframes move {
      from { left: 50px }
      to { left: 150px }
    }

    此时,两个球的运动轨迹是一模一样的(动画都是从150px位置~250px)。实际效果如下所示(点击“运动”按钮):


    2. transform属性没区别

    transform属性支持多值相加,但是值前后相连和直接合并计算的渲染效果是一样的,例如,还是上面的例子,我们将位移改为transform属性实现,会看到并无区别:

    .ball {
      /* 相同代码略 */
      transform: translateX(100px);
    }
    #ball1.active {
      animation: 2s move;
      animation-composition: add;
    }
    #ball2.active {
      animation: 2s move;
      animation-composition: accumulate;
    }
    
    @keyframes move {
      from { transform: translateX(50px); }
      to { transform: translateX(150px); }
    }


    原因很简单,add关键字生效的时候,动画的计算表现其实是这样的:

    from {
      transform: translateX(100px) translateX(50px);
    }
    to {
      transform: translateX(100px) translateX(150px);
    }

    accumulate关键字的计算表现则是(直接累加计算):

    from {
      transform: translateX(150px);
    }
    to {
      transform: translateX(250px);
    }

    transform连续位移和一次性位移的效果是一样的,因此,大家看不出两者的区别。

    但如果是filter属性的某些值,那就会有所区别。

    3. filter属性的模糊函数的区别可见

    我们先看静态效果,比方说有张图片,我们应用下面两段CSS代码的效果是不一样的:

    img {
      filter: blur(2px) blur(2px);
    }
    img {
      filter: blur(4px);
    }

    前者还是2px模糊,后者是4px。

    我们可以看一下下面的实际渲染效果(实时渲染):

    张含韵
    张含韵

    所以,当我们的动画是模糊变化的时候,大家就可以看到add和accumulate两个值的区别了。

    对此,我专门做了个演示页面,您可以狠狠地点击这里:add和accumulate渲染效果区别演示demo

    鼠标悬停目标图形,就可以看到不同的模糊动画效果了。

    例如,悬停右图(移动端是下图),明显可以感觉到要更加模糊一点:

    更加模糊的图片示意

    相关测试代码如下所示:

    <img src="1.jpg" class="img1">
    <img src="1.jpg" class="img2">
    img:hover {
      filter: blur(2px);
      animation: 1s pulse both;
    }
    .img1 {
        animation-composition: add;
    }
    .img2 {
        animation-composition: accumulate;
    }
    
    @keyframes pulse {
      0% {
        filter: blur(0px);
      }
      100% {
        filter: blur(2px);
      }
    }

    三、实际应用场景和结语

    animation-composition属性最具代表性的应用场景当属transform动画了。

    例如一个水平居中的toast在出现的时候需要有个轻微的上移动画,此时就不要担心translateX()函数和translateY()函数冲突的问题了。

    <div id="toast" class="toast">操作成功!</div>
    .toast {
      position: fixed;
      left: 50%;
      transform: translateX(-50%);
      background: green;
      padding: 4px 8px;
      color: #fff;
      animation-composition: add;
      display: none;
    }
    .toast.active {
      display: block;
      animation: tinyUp 350ms both;
    }
    @keyframes tinyUp {
      0% { transform: translateY(20px); }
      100% { transform: translateY(0px); }
    }

    实时渲染效果如下,点击按钮体验:

    操作成功!

    ——

    好,以上就是本文的全部内容,相信大家对animation-composition属性的理解一定更加全面了,感谢阅读,欢迎分享。

    🦺👔👕👖🧣

    本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
    本文地址:https://www.zhangxinxu.com/wordpress/?p=11689

    (本篇完)



沪ICP备19023445号-2号
友情链接