cover
2022年10月27日 - 2023年7月31日

好玩又难搞的多重阴影动画 - 几经波折,终于搞懂了多重阴影动画间歇失效的原因

事情是这样的:之前写的像素转换器,其实我一直想给他加上像素动画,但是却屡战屡败,今天终于解决了这个问题,这里记录一下。

picture 1

前情提要

先前排上两个 demo 吧。

https://code.juejin.cn/pen/7156931751187578910

https://code.juejin.cn/pen/7158427948473647118

怎么样,是不是觉得只需要使用"几行" css 就能完成这么复杂的动画效果十分帅气。然而这样子的动画却一直难以稳定实现,直到今天,我才终于知道之前偶现失败的原因。

box-shadow 动画

先说下 box-shadow 的动画处理:位置移动、颜色变化、模糊变动。

https://code.juejin.cn/pen/7158804021451423781

可以看出 box-shadow 中包含几个属性都可以平滑过渡。

不过这个现象在多重阴影的场景下会变的稍显复杂。

https://code.juejin.cn/pen/7158806099854901251

在拆解分析写了几个小 demo 之后,终于搞清了规律:

  • 阴影会被拆分为几个个体分别做动画
  • 个体的拆分按照阴影的索引来做
  • 在阴影数量新增时,新增的阴影会从原点处出发做动画,可以认为是 0 0 transparent 0 到当前阴影做动画。
  • 阴影数量减少时,则消失的阴影也会往原点处做消失动画。

然而在前几天晚上我想给编辑器增加一个生成随机动画的效果时,却一直失败,并且完全随机。网上也搜索不到关于多重阴影动画的相关资料。直到刚刚,我拆解 demo 时终于找到了原因:

https://code.juejin.cn/pen/7158820294671466526

比如如上的两个动画,都是阴影的过度,但是却一个可以生效,一个不能生效,你找到原因了吗?

答案就是 box-shadow 中唯一一个不能平滑过渡的属性:inset。之前在像素转换器文章中也写过,为了解决第一个像素块被遮挡的问题,可以采用 inset 或者背景色来处理。而在像素转换器中我所采用的便是 inset 的方案,然而在我为了生成动画效果将像素转换器生成的多重阴影进行了打乱,这样才能生成本文开头那样炫酷的效果。但是 0 0 位置的 inset 阴影却也因此被打乱。而刚刚也讲过了,多重阴影个体拆分使用的是位置索引,这就导致只要 inset 在动画前后的索引不一致便会导致动画失效。😂 而且还不是这一个个体的动画失效,是整体动画全部失效。困扰我的疑问终于在这里得到了解答。前期排查时因为阴影过多没能好好 diff,拆解之后其实还是挺容易发现的。注意 inset 在新增和去除的时候并不影响动画的效果。

结语

最后附上像素转换器的地址和 GitHub 地址,不过目前动画还没上,敬请期待。😂