一、先看效果
您可以狠狠地點選這裡:基於clip-path的元素碎片飛入動效demo
二、實現原理
效果本質上是CSS3動畫,就是旋轉(transform:rotate
)和位移(transform:translate
),只是旋轉和位移的部件是三角碎片而已。
那三角從何而來,本質上是使用CSS3 clip-path剪裁出來的。
關於CSS3 clip-path可以參見我之前的文章:“CSS3 clip-path polygon圖形構建與動畫變換二三事”。
剪裁一個三角並不難,但是,如果把任意的元素剪裁成一個一個的三角呢?
這就需要藉助JS來實現了。
JS把元素剪裁成一個一個的等腰直角三角形,然後隨機分佈在四周,然後,通過CSS3 animation動畫,讓所有的在四周的元素歸為就可以。因為CSS3 animation動畫關鍵幀中的CSS樣式權重似乎要比style
大。
於是,我們有如下核心CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.clip[style] { opacity: 0; } .active .clip[style] { will-change: transform; animation: noTransform .5s both; } @keyframes noTransform { to { opacity: 1; transform: translate3d(0, 0, 0) rotate(0); } } |
其中,will-change
作用是讓動畫更流暢,可參見我之前文章:“使用CSS3 will-change提高頁面滾動、動畫等渲染效能”。
.active .clip[style]
這段CSS表示的意思是,只要被剪裁的三角們的父級有了類名active
, 所有的三角的位置就不是隨機分佈,而是會以動畫形式歸位到其原本的位置。沒錯,是所有,我們沒有必要對每一個剪裁的三角碎片做動畫,只要歸位就可以。
通過toggle類名active
, 碎片的動效就可以不停地呈現,經測試,在移動端效果也是不錯的。
目前,除了IE瀏覽器和Android4.3-都支援了clip-path
,不過還需要-webkit-
私有字首。
三、我也想使用
我花了點功夫封裝了一個方法,1K出頭一點,程式碼如下(大家可以直接放到專案JS中或獨立個JS檔案):
1 2 3 4 5 6 7 |
/** * @description 任意元素碎片化,配合CSS可以有碎片拼接特效 更多內容參見 http://www.zhangxinxu.com/wordpress/?p=5426 * @author zhangxinxu(.com) * @license MIT [保留此段註釋資訊署名] */ var clipPath=function(t){if(!t){return false}t.removeAttribute("id");var r={height:t.clientHeight,width:t.clientWidth,distance:60,html:t.outerHTML};if(window.getComputedStyle(document.body).webkitClipPath){var a=r.distance,n=r.width,e=r.height;var o="";for(var i=0;i','" style="'+e+v+'">')})}}t.parentNode.innerHTML=r.html+o;return true}else{t.className+=" no-clipath";return false}}; |
語法如下:
1 |
clipPath(ele); |
其中,ele
為DOM元素,clipPath
方法基於原生JS書寫,不依賴其他JS框架,對於不支援clip-path
的瀏覽器沒有效果。返回值是布林值true
或false
, 返回true
表示瀏覽器支援clip-path
,false
為不支援。
程式碼中的distance:60
表示碎片的大小,越小碎片越多,對效能的考驗就越大。
例如,demo中文字和圖片的使用:
1 2 3 4 5 6 |
var eleText = document.getElementById('text'), eleImage = document.getElementById('image'); // 碎片特效初始化 clipPath(eleText); clipPath(eleImage); |
需要注意的是:
- 應用動效的務必是absolute絕對定位元素。一來效果必須,二來效能考量;
- 應用動效的元素不要太複雜,可能對效能會有考驗;
- 原始被用來粉碎的元素一直都在的,這樣,碎片拼接處的間隙就看不出來啦!
四、結束語
我寫的第一版JS中的碎片分佈是為隨機分佈,基本上根據自身方位隨機分佈在4個角的方向上;這裡給大家展示的是真隨機,也就是最左邊的碎片可能是從最右側飛過來的,所以效果要更爆裂一點。
好了,其他就沒什麼了,一個小特效而已。
其實說穿了,並沒有多大的難度,一點JS+一點CSS。關鍵是想到好的解決思路。如何才能有好的解決思路呢,需要對前端是真愛,這樣你會一直把前端放在腦中,自然而然就會是不是迸出很多很好的思路,創意和解決方案了!否則,永遠都只能拾人牙慧。