animation动画代码参考:css3 animation沿椭圆轨道旋转运动
scss三角函数参考1:sass实现三角函数
scss三角函数参考2:scss中实现三角函数计算
外包公司,项目中有一个页面是大屏可视化,其中有一个功能是6个div围绕一个圆心进行逆时针旋转。我确实不会写,纯新手一个,想过用transform + animation去实现,但结果完全满足不了需求。
方案1:最笨的方案。只通过 css3 animation沿椭圆轨道旋转运动 和 LESS 转 CSS 进行编译,结果就是将动画按照百分比一个点一个点编译出来。
@keyframes ccwRotation {
100% {
transform: translate(400px, 0px);
}
99% {
transform: translate(399.21069137px, 13.1860091px);
}
98% {
transform: translate(396.84588053px, 26.31997905px);
}
97% {
transform: translate(392.91490029px, 39.35007606px);
}
96% {
transform: translate(387.43326445px, 52.2248763px);
}
/* 省略后面所有百分比 */
}
方案2:如果项目使用的就是.less文件,那么就可以直接使用这段代码(完全搬运自css3 animation沿椭圆轨道旋转运动):
@a : 160px; // 椭圆x轴半径(长半径)
@b : 80px; // 椭圆y轴半径(短半径)
@s : 40; // 坐标点的数目(数目越大,动画越精细)
.loop(@index) when (@index < @s+1) {
.loop((@index + 1));
@keyframeSel: @index * 100%/@s; // keyframes断点
@{keyframeSel}{
transform: translate(@a*cos(360deg/@s*@index),@b*sin(360deg/@s*@index));
}
}
@keyframes move{
.loop(0);
}
方案3:我的项目使用的是vue2+scss,将方法2中的这段代码放进去就会报错,因为scss定义变量以及循环的方法和less不同。后面将变量和循环都替换掉以后,还是报错。网上一搜才知道:scss里没有sin/cos/tan等三角函数的方法(如有错误立即纠正),所以又在网上找了三角函数的方法。
以下是三角函数相关(参考链接在文章顶部):
/* 三角函数相关 */
// 阶乘表达式: (2n+1)!和(2n)!需要一个阶乘算法的函数
@function fact($number) {
$value: 1;
@if $number>0 {
@for $i from 1 through $number {
$value: $value * $i;
}
}
@return $value;
}
// 有幂操作、乘方定义
@function pow($number, $exp) {
$value: 1;
@if $exp>0 {
@for $i from 1 through $exp {
$value: $value * $number;
}
}
@else if $exp < 0 {
@for $i from 1 through -$exp {
$value: $value / $number;
}
}
@return $value;
}
// sin,cos函数传入的参数是deg,需要转成(deg / 360 * π)
@function rad($angle) {
$unit: unit($angle);
$unitless: $angle / ($angle * 0 + 1);
@if $unit==deg {
$unitless: $unitless / 180 * pi();
}
@return $unitless;
}
// 圆周率
@function pi() {
@return 3.14159265359;
}
// 正弦函数
@function sin($angle) {
$sin: 0;
$angle: rad($angle);
// 循环,参考地址中是@for $i from 0 through 10,动画会在最右侧时出现波浪形运动而不是匀速上升,增加到20时就没有再出现这类问题
@for $i from 0 through 20 {
$sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1);
}
@return $sin;
}
// 余弦函数
@function cos($angle) {
$cos: 0;
$angle: rad($angle);
// 循环
@for $i from 0 through 10 {
$cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i);
}
@return $cos;
}
以下是定义椭圆轨道大小、定义动画:
/* 定义椭圆轨道大小、执行动画 */
$a: 25rem; // 椭圆x轴半径(长半径),px亦可
$b: -13.125rem; // 椭圆y轴半径(短半径) ,px亦可,因为我需要逆时针旋转所以改为了负数
$s: 100; // 坐标点的数目(数目越大,动画越精细)
// 逆时针动画
@keyframes ccwRotation {
@for $i from 0 through $s {
$keyframeSel: $i * 100% / $s;
#{$keyframeSel} {
transform: translate($a * cos(360deg / $s * $i), $b * sin(360deg / $s * $i));
}
}
}
// 需要执行动画的元素(有N个的时候需要设置delay,根据自行需求去设定)
.round-item:nth-child(1) {
animation: ccwRotation 60s linear 0s infinite normal;
}
最后搞定!400行的代码最后精简成了100行。
补充:我认为还有更好的方案,只是我还没发现。