又到周末,来弄点HTML5的特效玩玩,今天要折腾的是HTML5 3D图片特效,图片在垂直方向上被分割成一条条小矩形,在图片上拖动鼠标即可让每一个小矩形旋转,从而让图片形成3D立体的效果,来看看效果图:
大家也可以在这里看到具体的DEMO演示。
下面我们来分析一下实现这款HTML5 3D图片旋转特效的源代码,这里我们引用了知名的JS动画框架TweenMax.js。
先来看看HTML代码:
<ul id="level0" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level1" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level2" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level3" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level4" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level5" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level6" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level7" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level8" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level9" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level10" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level11" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul> <ul id="level12" class='cube'> <li class='face'></li> <li class='face'></li> <li class='face'></li> <li class='face'></li> </ul>
这里我们看到,我们用了n个ul来实现将图片分割成n个小长方形,为了之后js调用的方便,我们将这些ul标识成level-n。
然后我们再来看看CSS代码,这里主要是引入了这张美女图片,哈哈。
.cube { position: relative; margin: 0em auto 0; padding: 0px; width: 20em; height: 3.0em; list-style: none; transform-style: preserve-3d; /*animation: ani 8s infinite linear;*/ } .face { box-sizing: border-box; position: absolute; top: 180px; left: 50%; /*border: 1px solid #f0f0f0;*/ margin: -8em; padding: 1.6em; width: 20em; height: 2em; opacity: .85; background: lightblue; /*Creative Commons image from http://www.flickr.com/photos/37825670@N07/3562600154/sizes/z/in/photostream/ */ background: url(k6dbiLv.jpg) -115px -900px; background-repeat: no-repeat; backface-visibility: hidden; } .face:nth-child(1) { transform: translateZ(10em); } .face:nth-child(2) { transform: rotateY(180deg) translateZ(10em); } .face:nth-child(3) { transform: rotateY(90deg) translateZ(10em); } .face:nth-child(4) { transform: rotateY(-90deg) translateZ(10em); }
最后是Javascript代码,这里我们引入了jQuery和动画引擎TweenMax.js:
<script src='js/jquery.js'></script> <script src='js/TweenMax.min.js'></script>
下面是实现旋转动画的js代码:
var gaps=[]; var gapscnt=0; var currentLevel=0; var px=[0,0,0,0,0,0,0,0,0,0,0,0,0]; var vx=[0,0,0,0,0,0,0,0,0,0,0,0,0]; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; init() function tickHandler() { //run your logic here... if(md){ gap=averageGaps(mouseX-oldMouseX); } gap*=.9; vx[currentLevel]+=gap; oldMouseX = mouseX; var i; for ( i = currentLevel; i < numLevels; i++) { vx[i+1]+=((vx[i]-vx[i+1])/slow); } for ( i = currentLevel; i > 0; i--) { vx[i-1]+=(vx[i]-vx[i-1])/slow; } for ( i = 0; i <numLevels; i++) { px[i]+=(vx[i]-px[i]); // trying tweenmax duration 0 method of setting rotationY TweenMax.to($('#level'+i), 0, {rotationY:px[i]}); } } // functions function init(){ // code for cube var d=0.12;var p=3; for(var i=0;i<numLevels;i++){ var posString="-115px "+(-48*i)+ "px"; TweenMax.to($('#level'+i+' li'), 1, {css:{backgroundPosition: posString}, delay:(d*i)});} TweenLite.ticker.addEventListener("tick", tickHandler); $('.cube').mouseover(function(){ TweenMax.to($('.face'),1,{opacity:1}); }); $('.cube').mouseout(function(){ TweenMax.to($('.face'),1,{opacity:.85}); }); $(document).on('mousedown', function(event) { event.preventDefault(); oldMouseX = mouseX; gaps.length = 0; md=true; }).on('mouseup', function(event) { md=false; }).on('mousemove', function(event) { mouseX = event.clientX - windowHalfX; mouseY = event.clientY - windowHalfY; }); $('#level0').mousedown(function(){currentLevel=0; }); $('#level1').mousedown(function(){currentLevel=1; }); $('#level2').mousedown(function(){currentLevel=2; }); $('#level3').mousedown(function(){currentLevel=3; }); $('#level4').mousedown(function(){currentLevel=4; }); $('#level5').mousedown(function(){currentLevel=5; }); $('#level6').mousedown(function(){currentLevel=6; }); $('#level7').mousedown(function(){currentLevel=7; }); $('#level8').mousedown(function(){currentLevel=8; }); $('#level9').mousedown(function(){currentLevel=9; }); $('#level10').mousedown(function(){currentLevel=10; }); $('#level11').mousedown(function(){currentLevel=11; }); $('#level12').mousedown(function(){currentLevel=12; }); var touchEnabled = 'ontouchstart' in window || navigator.msMaxTouchPoints; if (touchEnabled == true) { console.log("touchEnabled"); document.addEventListener('touchmove', onTouchMove, false); document.addEventListener('touchstart', onTouchStart, false); document.addEventListener('touchend', onTouchEnd, false); } } function onTouchMove(event) { event.preventDefault(); var touch = event.touches[0]; mouseX = touch.pageX - windowHalfX; mouseY = touch.pageY - windowHalfY; } function onTouchStart(event) { event.preventDefault(); oldMouseX = mouseX; gaps.length = 0; md=true; } function onTouchEnd(event) { event.preventDefault(); md = false; } function averageGaps(n){ if(isNaN(n)){ return 0; } var gl=gaps.length; gaps[gapscnt]=n; var ave =0; for (var i = 0; i < gl; i++) { ave+=gaps[i]; }; gapscnt=(gapscnt+1)%10; var tmp=ave/gl; if(isNaN(tmp)){tmp=0; } return tmp; }
在TweenMax的帮助下,动画实现简单了不少。
最后附上我们可爱的源代码,下载地址>>