《CSS揭秘》里面发现一个很独特的一个动画,使用纯css3动画让一个元素沿着环形路径运动。听起来有点不可思议,本文将带你一起走进作者的文章中,由复杂到简单,由多个结构到简单结构解剖CSS3语句实现环形运动。
具体动画样式演示:链接内容
其它辅助的CSS代码可以查阅一下演示代码源码。这里就不再写出了。
自身绕圆旋转
首先作者给出了一副头像图片沿着环形路径运动,需求是希望头像顺着头像顺着一个大圆以转圈的方式移动。关键代码如下:
<div class="box box2"><div class="ball">Balldiv>div>
@keyframes spin{
to{transform: rotate(1turn);}
}
.box2 .ball{
animation:spin 3s infinite linear;
transform-origin: 50% 150px;
}
绕圆旋转,内容不转
可以看到图1在球的中心点转圈,而图2则是绕着150px的半径在转圈的同时,自身也在旋转。效果看起来挺好,但有一个缺陷,就是自身也在转动,使得文字颠倒,无法看清,有没有办法做到只是沿着环形进行运动,同时自己保持原来的朝向呢?
需要两个元素的解决方法
作者想到了之前的一个案例“平行四边形”或者“菱形图片”中提到的“嵌套的两层变形会相互抵消”,这样就想到了用内层的变形来抵消外层的变形效果。
<div class="box box3"><div class="ball"><div class="inner">Balldiv>div>div>
@keyframes spin{
to{transform: rotate(1turn);}
}
@keyframes spin-reverse{
from{
transform:rotate(1turn);
}
}
.box3 .ball{
animation:spin 3s infinite linear;
transform-origin: 50% 150px;
}
.box3 .inner{
animation: spin-reverse 3s infinite linear;
}
看上面的代码,作者觉得还有优化的空间,让内层动画继承父元素的所有动画属性,然后把动画名覆盖掉,这样子要是有调整动画的属性只需要改第一个就行。
.box3 .inner{
animation:inherit;/*继承上级的属性*/
animation-name:spin-reverse;
}
从上面可以看到两个动画只是方向相反,那么我们想起了前面提到的animate-direction,使用reverse来得到动画的反向版本。
.box4 .ball{
animation:spin 3s infinite linear;
transform-origin:50% 150px;
}
.box4 .inner{
animation:inherit;
animation-direction: reverse;
}
单个元素绕圆旋转
最后作者又从transform-origin可以由两个translate()模拟出来,优化出了只使用一个HTML元素就实现了自身不转动,同时可以围绕半径运动。
@keyframes spin2{
from{
transform: translate(50%, 150px)
rotate(0turn)
translate(-50%, -150px)
translate(50%,50%)
rotate(1turn)
translate(-50%,-50%)
}
to{
transform: translate(50%, 150px)
rotate(1turn)
translate(-50%, -150px)
translate(50%,50%)
rotate(0turn)
translate(-50%,-50%)
}
}
.box5 .ball{
animation: spin2 3s infinite linear;
}
其实,最关键的一点还是在于坐标的转换,如下所示:
transform: rotate(30deg);
transform-origin: x y; // x, y为元素左上角相对圆心坐标的距离
// 等价于
transform: translate(x, y)
rotate(30deg)
translate(-x, -y);
transform-origin:0 0;
兼容性
不支持IE10以下浏览器,演示代码中只给出最新版的CSS3代码,未对代码进行兼容处理,实际使用中请使用autoprefixer插件兼容。
本文只是希望能给刚入门或迷茫的同学一些建议,合不合适只有自己才是最明白的,欢迎留言。另外新手学习前端开发除了要多动手敲代码最重要的还是经验的交流欢迎有需要的的小伙伴进前端开发交流群624293552来一起交流问题学习经验,我把所有比较适合新手学习的教程资料都放到里了。