一, 不是所有 CSS 属性都能动画
经常和 CSS 打交道的人肯定都知道, 不是所有的 CSS 属性都能使用 animation 属性实现动画效果, 最典型的例子就是 background-image 渐变.
一个典型的线性渐变是由角度, 颜色和位置组成, 例如:
- .gradient {
- background-image: linear-gradient(45deg, red 50%, blue 50%);
- }
其中无论是角度 (45deg), 颜色(red, blue) 还是位置 (50%) 单独作为属性者都是可以动画过渡的, 但是合在一起作为渐变背景的时候是无法产生过渡效果的, 因为 background-image 的语义是图片.
那有没有什么办法可以让背景图片也能实现动画过渡呢, 至少 CSS 渐变可以实现?[图片上传失败...(image-e6ee4e-1558437352811)]
经过我的研究和探索, 找到了一种解决方案, 虽称不上百分百完美, 但足够应用于项目中, 能让以前很多不支持 CSS 动画的属性, 也支持原生的动画效果.
二, 变量种子计数器
Chrome 等浏览器 (不包括 Safari) 有个特性, 就是当我们使用 @keyframes 定义关键帧的时候, 关键帧里面设置的属性也是会运行的(几年前改变的, 原先不是), 典型的案例就是 content 属性与内容变化.
例如实现一个 "正在加载中..." 打点效果可以下面 CSS 和 html:
- dot::before {
- content: '...';
- position: absolute;
- animation: dot 3s infinite step-start both;
- }
- dot:after {
- content: '...';
- color: transparent;
- }
- @keyframes dot {
- 33% { content: '.'; }
- 66% { content: '..'; }
- }
- <button > 正在加载中 < dot></dot></button>
实时效果如下:
正在加载中
根据我的测试发现, 不仅普通的 CSS 属性可以在 CSS 动画关键帧中运行, CSS 自定义属性 (CSS 变量) 也可以在 CSS 动画关键帧中运行. 例如:
- @keyframes var {
- 33% { --someVar: 33%; }
- 66% { --someVar: 66%; }
- }
这种特性就非常有启发, 如果我们某一个 CSS 属性值是基于这个 --someVar 变量构成的, 那岂不是就算这个属性值不支持 CSS 动画, 我只要让每一个百分比值的间隙足够的小, 不也能够实现一个平滑的动画效果?
具体做法就是, 把 CSS 动画关键帧从 0%-100% 分成 101 份, 然后每一份从 0 开始依次计数, 就像是个计数器一样, 然后把这个计数器分配给一个特定的 CSS 变量. 最终我们可以得到一个如下所示的 CSS 动画 "变量种子计数器".
- @keyframes seed {
- 0%{--seed:0}1%{--seed:1}2%{--seed:2}3%{--seed:3}4%{--seed:4}5%{--seed:5}6%{--seed:6}7%{--seed:7}8%{--seed:8}9%{--seed:9}10%{--seed:10}11%{--seed:11}12%{--seed:12}13%{--seed:13}14%{--seed:14}15%{--seed:15}16%{--seed:16}17%{--seed:17}18%{--seed:18}19%{--seed:19}20%{--seed:20}21%{--seed:21}22%{--seed:22}23%{--seed:23}24%{--seed:24}25%{--seed:25}26%{--seed:26}27%{--seed:27}28%{--seed:28}29%{--seed:29}30%{--seed:30}31%{--seed:31}32%{--seed:32}33%{--seed:33}34%{--seed:34}35%{--seed:35}36%{--seed:36}37%{--seed:37}38%{--seed:38}39%{--seed:39}40%{--seed:40}41%{--seed:41}42%{--seed:42}43%{--seed:43}44%{--seed:44}45%{--seed:45}46%{--seed:46}47%{--seed:47}48%{--seed:48}49%{--seed:49}50%{--seed:50}51%{--seed:51}52%{--seed:52}53%{--seed:53}54%{--seed:54}55%{--seed:55}56%{--seed:56}57%{--seed:57}58%{--seed:58}59%{--seed:59}60%{--seed:60}61%{--seed:61}62%{--seed:62}63%{--seed:63}64%{--seed:64}65%{--seed:65}66%{--seed:66}67%{--seed:67}68%{--seed:68}69%{--seed:69}70%{--seed:70}71%{--seed:71}72%{--seed:72}73%{--seed:73}74%{--seed:74}75%{--seed:75}76%{--seed:76}77%{--seed:77}78%{--seed:78}79%{--seed:79}80%{--seed:80}81%{--seed:81}82%{--seed:82}83%{--seed:83}84%{--seed:84}85%{--seed:85}86%{--seed:86}87%{--seed:87}88%{--seed:88}89%{--seed:89}90%{--seed:90}91%{--seed:91}92%{--seed:92}93%{--seed:93}94%{--seed:94}95%{--seed:95}96%{--seed:96}97%{--seed:97}98%{--seed:98}99%{--seed:99}100%{--seed:100}
- }
上面这段 @keyframes seed{}相关 CSS 代码就是一个可以无限使用的 "动画种子", 无论是那些原本支持 CSS 动画的属性, 还是不支持 CSS 动画的属性, 只要它的属性值是与数值相关的, 都能够借助这个 "动画种子" 实现动画效果.
举个渐变旋转的例子
例如一开始那个线性渐变的例子, 我们可以让渐变旋转角度和我们 "动画种子" 中的 --seed 变量相关联, 配合 animation 属性就能实现渐变旋转的效果了:
- .gradient {
- width: 150px; height: 150px;
- background-image: linear-gradient(calc(3.6deg * var(--seed)), red 50%, blue 50%);
- animation: seed 1s linear infinite;
- }
- <div class="gradient"></div>
三, 更进一步的动画效果
配合 "变量种子计数器", 我们最实现过去很难实现的密集型背景图形动画效果, 例如下面这张平铺的圈圈放大效果:
CSS 和 HTML 代码如下:
- .radial-gradient {
- padding: 50%;
- background-image: radial-gradient(#cd0000 calc(2% * var(--seed)), transparent calc(2% * var(--seed)));
- background-size: 80px 80px;
- animation: seed 1s linear infinite;
- }
- div class="radial-gradient"></div>
只要把我们的径向渐变的边缘使用 var(--seed)种子变量表示就可以了. 使用 2% 计算而不是使用 1% 是为了红色铺满之后有一定的延时, 否则效果体验的时候眼睛会闪瞎.
四, 兼容性及结语
"变量种子计数器" 实现动画技术的兼容性如下:
Chrome 浏览器和 Android 设备上完全无障碍使用的;
Firefox 浏览器也是支持动画帧里面设置 CSS 变量的, 但是需要应用动画的属性也写在其中, 也就是每一帧中都要把 background-image 也写上, 但这样就完全没有重用性, 成本较高, 所以价值有限;
IE 浏览器和 Safari 浏览器则完全不支持;
由于 Safari 不支持, 导致 iOS 手机上是没有效果的, 大大制约了实用价值.
但是放在特殊场合, 也不是不能使用, 我们可以使用增强实现某些特殊的效果, 例如这篇文章介绍的新颖的交互动效
自己是一个五年的前端工程师, 希望本文对你有帮助!
这里推荐一下我的前端学习交流扣 qun:731771211 , 里面都是学习前端的, 如果你想制作酷炫的网页, 想学习编程. 自己整理了一份 2019 最全面前端学习资料, 从最基础的 HTML+CSS+JS[炫酷特效, 游戏, 插件封装, 设计模式] 到移动端 HTML5 的项目实战的学习资料都有整理, 送给每一位前端小伙伴, 每天分享技术
点击: 加入
来源: http://www.jianshu.com/p/73e25780cb91