旋轉3D立方體封筆之作——疊加路徑拼接動畫(文末曬掘金福利)

泱泱發表於2017-10-18

寫在前面:
差不多最近三個月就在忙忙忙,大概年中的緣故,為了不打破“美工絕不加班”這一優良傳統,每天時間安排滿滿當當,終於在這周完成了手頭上的所有緊急/加急/急急如律令的工作,然後,我又回來更新專欄啦!
期間收到了掘金小編承諾的福利,杯子和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的簡潔時尚國際範兒以及杯子的閃亮描金效果。

相關文章