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

这篇文章发布于 2025年05月12日,星期一,23:58,归类于 CSS相关。 阅读 226 次, 今日 226 次 没有评论

 

一、前言

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
属性值计算叠加。accumulateadd比较类似,很多同学会搞不清楚,下面会有案例示意。

add和accumulate的区别

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

在大绝多数情况下,addaccumulate两个值的表现是没有区别的,只有当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。

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

张含韵
张含韵

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

对此,我专门做了个演示页面,您可以狠狠地点击这里: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属性的理解一定更加全面了,感谢阅读,欢迎分享。

🦺👔👕👖🧣

(本篇完)

分享到:


发表评论(目前没有评论)