阅读 858

旋转3D立方体封笔之作——叠加路径拼接动画(文末晒掘金福利)

写在前面:
差不多最近三个月就在忙忙忙,大概年中的缘故,为了不打破“美工绝不加班”这一优良传统,每天时间安排满满当当,终于在这周完成了手头上的所有紧急/加急/急急如律令的工作,然后,我又回来更新专栏啦!
期间收到了掘金小编承诺的福利,杯子和T,文末会晒。
言归正传,开头草稿存了三月有余,终于重见天日!

最近对3D立方体的动画有点着魔,越玩越嗨,此状态不好,需警惕,那就告诫自己,最后一篇,然后立方体相关的就此封笔。<svg>有一个特有的动画属性是CSS3无可取代的,就是<animateMotion>,路径移动动画。也曾经特意写了一篇文章《UI设计师福利之零基础入门SVG路径动画》
juejin.im/post/590941…
来说明各个属性的设置。那既然我是用<SVG>来组的立方体,所以就很想试试六个面拼接的路径动画的效果。说来就来。

1.立方体路径动画——拆解

关于二维平面的路径动画做法,不再赘述(貌似最近几次都是这副德行,一股子入门教程自己看的架势),就是上面的路径动画的链接。这次,我拿飞机(没办法,就是需要一个俯视角度辨识度高的)作为移动的物体,然后准备做飞机在立方体各个面进行路径移动的动效。
由简入难,既然我们的立方体是六个平面拼接起来的,那立方体路径动画也可以对应为六个平面的路径动画组合衔接起来。
运动轨迹的平铺图如下

为了看上去直观,我用了几对不同颜色的圆来表示相交点。
组合成立方体之后的效果如下图:

经过拆解之后,动画思路就比较清晰了,我们需要做六段路径,获得对应的<path>值,这里唯一要注意的是移动相邻的两个面终点与起点要重合。哎呀呀,做到这里,感觉像是在玩拼图游戏一样。

2.与基础立方体——合体

我们上篇一直以一个旋转的立方体作为模板来叠加各种动效,描边or位移or旋转,这次还是拿那个立方体继续叠加吧,省事省心。为了确保路径拼接的正确性,先把运动的路径显示出来,看一下立方体旋转效果

路径的旋转效果
路径的旋转效果

虽然眼花缭乱,但起码证明路径的拼接是成功的。这里唯一需要注意的是,关于3D方向rotateX和rotateY的方向,来,伸出左右手,还记得高中学电磁感应时,线圈电流生成的磁极的方向,是右手四指弯曲和拇指方向对应的,这里复杂一点,我们来左右开弓,为了弄清楚方向,我们用大拇指指向X轴或Y轴的方向,左正右负,也就是说,左手四指弯曲的方向为正向旋转,同理,右手四指弯曲的方向为负向旋转。为什么这里特别强调了一下,是因为前面的立方体实现时,以顶面为例transform:rotateX(-90deg),旋转前和旋转后的效果如下图


这里之所以颜色变成的黑色,是想用来表示旋转之后是顶面的底面被展示出来。所以这里我又把立方体的组成的CSS按照我们路径要求的折方盒子的方向重新定义了一下如下:

#cubic2{transform:rotateY(180deg) translateZ(100px);}
#cubic3{transform:rotateX(90deg) translateZ(100px)  }
#cubic4{transform:rotateY(90deg) translateZ(100px)}
#cubic5{transform:rotateX(-90deg)translateZ(100px);}
#cubic6{transform: rotateY(-90deg) translateZ(100px);}复制代码

3.动起来吧

小飞机稍等片刻出场,这里先用一个基础的圆形<circle>来把轨迹走一遍。轨迹动画并不复杂,因为是六个方形拼接,只需要控制延迟开始时间就可以了,根据运动的顺序,1→3→4→6→2→5,<animateMotion path="" dur="2s"/>定义在每个面的运动时间为2s,那延迟开始的时间,cubic3定义为begin="2s",cubic4定义为begin="4s",…依次类推,整个立方体的轨迹动画一共需要12s。
看一下效果如何

沿路径运动的圆形
沿路径运动的圆形

路径运动拼接的还比较完美,自动忽略掉角角上的那几个黑点点,因为设置的延迟开始的小圆圈会乖乖的在各自坐标系的原点待着等待开始的召唤,这里可以优化,加个蒙版什么的先遮住,因为太繁琐,我选择放弃。

好了,圆形只是测试,小飞机准备登场。有了基础的图形和运动轨迹,只要用飞机对应的代码去替换<circle>就可以了。这里比较麻烦的是飞机的朝向,因为定义了路径动画中rotate="auto"属性,飞机会根据曲线的曲率自动旋转调整,所以初始飞机的朝向比较重要,六个面中,有上下进入的有水平进入的,多尝试一下,体力活而已。

飞机沿轨迹运动
飞机沿轨迹运动

做到这里,基本就算完成了,想象中的路径拼接立方体动画达到了八分满意度。我也是在做的过程中突然有了一个好玩的想法,当我把立方体的边框去掉,也就是去掉每个面矩形<rect>的描边,只保留路径,得到下面这种效果,没有想象的那么好,主要原因在于这毕竟是用2D去模拟3D效果,不具备应用场景。另外角角里的小飞机也干扰了效果。

去掉立方框
去掉立方框

这是样式部分:

.stage {
    width: 1000px;
    height: 1000px;
    background:#e5fffb;
    perspective:1000px; 
    perspective-origin:50% 50%;
    }
@keyframes content{
to{
transform:rotateX(-360deg) rotateY(360deg);}}
.content{transform-style: preserve-3d; animation:content 20s linear both  infinite ;position: absolute;top:400px; left:400px;width:200px; height:200px; transform-origin:50% 50%}/*以上是关于旋转立方体的样式部分*/
#cubic1{transform:translateZ(100px);}
#cubic2{transform:rotateY(180deg) translateZ(100px);}
#cubic3{transform:rotateX(90deg) translateZ(100px)  }
#cubic4{transform:rotateY(90deg) translateZ(100px)}
#cubic5{transform:rotateX(-90deg)translateZ(100px);}
#cubic6{transform: rotateY(-90deg) translateZ(100px);}
rect{fill:none; stroke-width:3; stroke:#f29a76; width:200px; height:200px}
SVG {position: absolute;width:200px; height:200px}
SVG .road{fill:none; stroke:#8492b6; stroke-width:2px;opacity:0.5}/*以上是关于各个面的样式*/复制代码

这是DOM结构:

<div class="stage">
<div class="content">
<svg   id="cubic1" xmlns="http://www.w3.org/2000/svg" >
<rect />
<g>
…
省略号为飞机部分组成
<animateMotion path=""  dur="2s"  rotate="auto"  calcMode="spline" keyTimes="0;1" keySplines="0,0,1,1"  /> <!--path=""为如下路径值-->
</g>
<path class="road" d=""/><!--d值为路径-->
 </svg>
<svg   id="cubic2" xmlns="http://www.w3.org/2000/svg" >
<rect />
<g>
…
<animateMotion path=""    begin="6s"  dur="2s"  rotate="auto"  calcMode="spline" keyTimes="0;1" keySplines="0,0,1,1"  /> <!--根据运动的顺序1→3→4→2→6→5,对应begin值依次+2s-->
</g>
<path class="road" d=""/>
 </svg>
 <svg   id="cubic3" xmlns="http://www.w3.org/2000/svg" >
<rect />
<g>
…
<animateMotion path=""    begin="2s"  dur="2s"  rotate="auto"  calcMode="spline" keyTimes="0;1" keySplines="0,0,1,1"  /> 
</g>
<path class="road" d=""/>
 </svg>
 <svg   id="cubic4" xmlns="http://www.w3.org/2000/svg" >
<rect />
<g>
…
<animateMotion path=""    begin="4s"  dur="2s"  rotate="auto"  calcMode="spline" keyTimes="0;1" keySplines="0,0,1,1"  /> 
</g>
<path class="road" d=""/>
 </svg>
 <svg   id="cubic5" xmlns="http://www.w3.org/2000/svg" >
<rect />
<g>
…
<animateMotion path=""    begin="10s"  dur="2s"  rotate="auto"  calcMode="spline" keyTimes="0;1" keySplines="0,0,1,1"  /> 
</g>
<path class="road" d=""/>
 </svg>
 <svg   id="cubic6" xmlns="http://www.w3.org/2000/svg" >
<rect />
<g>
…
<animateMotion path=""    begin="8s"  dur="2s"  rotate="auto"  calcMode="spline" keyTimes="0;1" keySplines="0,0,1,1"  /> 
</g>
<path class="road" d=""/>
 </svg>
</div>
</div>复制代码

做到这里不禁感慨,动效有时候真是件出力不讨好的事情,可能简简单单的CSS3动画属性用一下,能有吊炸天的效果,也有可能像我这样,闷头做了好久,鬼,什么东西,被自己所嫌弃。后面准备更新几篇文章,关于一些基础动画属性应用做出魔性效果的。
好了,开始晒福利了。
这个,手机像素渣渣也就罢了,难得照相水平更渣。木有照出T的简洁时尚国际范儿以及杯子的闪亮描金效果。

关注下面的标签,发现更多相似文章
评论