用CSS3做3D動畫的那些事


年會做了個3D變換的抽獎系統,在這里分享下通過CSS3制作3D效果的心得。抽獎系統雖然夠炫酷,可惜抽的時候出了點bug,好幾百人啊我的小心臟啊。雖然這個鍋后面甩給會場的老爺電腦了(手動白眼)。

 

首先介紹幾個實現3D效果的CSS3屬性:

rotateY、translateZ

這兩個transform屬性值是實現3D效果比較常用的,首先要記清楚變換的坐標軸,X-水平、Y-豎直、Z垂直屏幕。

效果:

從左到右依次為:正常,translateZ(-200px),rotateY(45deg)。不過有點奇怪的是綠色的卡片有點變形,因為在父容器上添加了透視距離的屬性,見下。

 

perspective

該屬性為定義3D變換的元素與視圖的距離,也就是透視距離。該屬性不是添加在變換的元素上,而是添加到視圖元素(變換元素的父元素)上。

在未定義該屬性的情況下,translateZ 並不會生效,因為沒有透視距離。若你的元素沿Z軸的移動值並不是基於百分比的情況下,只需保證 prespective 值大於 translateZ 值即可。

使用perspective屬性需要謹慎,添加了透視距離有可能導致如上例中綠色卡片的效果。

兼容性:-webkit-perspective | perspective (以下CSS屬性存在的兼容性寫法均參考自W3CSchool)。

 

transform-style: flat | preserve-3d

定義變換方式

flat:子元素將不保留其 3D 位置

preserve-3d:子元素將保留其 3D 位置。

在做3D變換時,我們通常將該屬性添加在變換元素上,並將值設為preserve-3d。

兼容性:-webkit-transform-style | transform-style

 

backface-visibility: visible | hidden

是否隱藏元素背面

效果:

上面五張卡片從左到右,rotate值依次為45deg、60deg、135deg、180deg、300deg,很直觀的展示了該屬性的效果。

兼容性:-webkit-backface-visibility | -moz-backface-visibility | -ms-backface-visibility | backface-visibility

 

有關性能

眾所周知CSS3動畫性能要比JS動畫好,那在CSS3動畫中要做哪些來提升性能呢?

1. 使用3D變換開啟GPU加速:變換元素上添加屬性: transform: translate3d(0,0,0);

2. 使用translate代替left或者marginLeft;

3. 使變換元素脫離文檔流;

4. 減少陰影和圓角的使用。

 

事件

有人說JS動畫相比CSS3動畫的優點是可以監聽到動畫的結束,但其實CSS3動畫一樣有監聽各個階段的方法:

動畫開始 animationstart

動畫結束 animationend

動畫重復 animationiteration

監聽:

原生 & jQuery

obj.addEventListener('animationend', function() { obj.removeEventListener('animationend', function(){}, false); }, false);
$obj.on('animationend', function() { $obj.off('animationend'); });

對於需要多次監聽的,每次最好取消事件綁定。

兼容性:

動畫開始 webkitAnimationStart | oAnimationStart | MSAnimationStart | animationstart

動畫結束 webkitAnimationEnd | oAnimationEnd | MSAnimationEnd | animationend

動畫重復 webkitAnimationIteration | oAnimationIteration | MSAnimationIteration | animationiteration

同樣的,transition也有相應的監聽事件,需要的朋友可以上一下度娘。

 

對於不同瀏覽器怎么判斷如何選取相應的事件名稱:

這里推薦一個處理H5&CSS3對瀏覽器兼容問題很方便的第三方庫——modernizr.js,引入該庫后直接上寫法,內容細節這里不探討了,有興趣的朋友可以百度詳細了解。

var animationEventNames = {     'WebkitAnimation': 'webkitAnimationEnd',
    'OAnimation': 'oAnimationEnd',     'msAnimation' : 'MSAnimationEnd',     'animation' : 'animationend'   },
  animationEventName
= animationEventNames[Modernizr.prefixed('animation')];
$obj.on(animationEventName,
function() { $obj.off(animationEventName); });

 

最后貼出自己做的DEMO,模仿自博客園“夢想天空”里的一個特效(盡量用chrome,ff等對CSS3支持比較好的瀏覽器打開哈)。

DEMO     源碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM