CSS揭秘之沿着环形路径运动的动画

《CSS揭秘》里面发现一个很独特的一个动画,使用纯CSS3动画让一个元素沿着环形路径运动。听起来有点不可思议,本文将带你一起走进作者的文章中,由复杂到简单,由多个结构到简单结构解剖CSS3语句实现环形运动。

自身绕圆旋转

首先作者给出了一副头像图片沿着环形路径运动,需求是希望头像顺着头像顺着一个大圆以转圈的方式移动。关键代码如下:

<div class="box box2">
	<div class="ball">Ball</div>
</div>
@keyframes spin{
	to{transform: rotate(1turn);}
}
.box2 .ball{
	animation:spin 3s infinite linear;
	transform-origin: 50% 150px;
}

效果如下图:animate

演示:demo1

其它辅助的CSS代码可以查阅一下演示代码源码。这里就不再写出了。

绕圆旋转,内容不转

可以看到图1在球的中心点转圈,而图2则是绕着150px的半径在转圈的同时,自身也在旋转。效果看起来挺好,但有一个缺陷,就是自身也在转动,使得文字颠倒,无法看清,有没有办法做到只是沿着环形进行运动,同时自己保持原来的朝向呢?

需要两个元素的解决方法

作者想到了之前的一个案例“平行四边形”或者“菱形图片”中提到的“嵌套的两层变形会相互抵消”,这样就想到了用内层的变形来抵消外层的变形效果。

<div class="box box3">
	<div class="ball">
		<div class="inner">Ball</div>
	</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;
}

效果图:

aimate2

演示:demo2

单个元素绕圆旋转

最后作者又从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;
}

演示:demo3

其实,最关键的一点还是在于坐标的转换,如下所示:


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插件兼容。


关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流