最近公司项目要求做一个图片3d立体旋转的效果,领导给了我一个参考文件,链接稍后附上,今天主要讲实现效果关键的几点:perspective+transform-style+transform-origin。
先贴一张效果图:
一、需了解的知识点:
1、如何让一个2d平面的图呈现3d效果?
答:此时需要使用css3的一个透视属性:perspective属性,这个属性需要在父级元素设置,其子元素才会用透视效果,且其子元素必须在Z轴上有位移,元素本身不会有透视效果,目前主流浏览器都支持,ie9及以下不支持,为了兼容不出错,chrome和Safari加前缀-webkit-,ie加前缀-ms-,其实我没加也没有出错,建议加上。
2、如何让图片在旋转时也呈现3d效果?
答:此时需要css3的transform-style属性,属性值一定要选择preserve-3d,这个属性给需要转换(变形)的父元素设置以及需要转换的子元素设置,一定都要加。此时有一个注意点:此处的父元素必须是设置了perspective属性的元素的子级。但是ie不支持这个属性,所以ie的3d转换效果很丑,Chrome、Safari 和 Opera 加前缀 -webkit-,Firefox直接用,Chrome我没加也没有出错,还是建议加上。
ie效果图:
二、代码实现:
1、html结构:
<div class="carousel"> <div class="content"> <img src="img/other/1.jpg" /> <img src="img/other/2.jpg" /> <img src="img/other/3.jpg" /> <img src="img/other/4.jpg" /> <img src="img/other/5.jpg" /> <img src="img/other/1.jpg" /> <img src="img/other/2.jpg" /> <img src="img/other/3.jpg" /> <img src="img/other/4.jpg" /> <img src="img/other/5.jpg" /> </div> <div class="nav"> <button class="prev"></button> <button class="next"></button> </div> </div>
2、css样式
.carousel { height: 488px; width: 1300px; margin:0 auto; -webkit-perspective: 500px; -ms-perspective: 500px; perspective: 500px; position: relative; overflow: hidden; } .carousel > * { -webkit-box-flex: 0; -ms-flex: 0 0 auto; flex: 0 0 auto; } .carousel .content{ width: 78%; position: absolute; left: 11%; top:0; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; -webkit-transition: -webkit-transform 0.5s; transition: -webkit-transform 0.5s; transition: transform 0.5s; transition: transform 0.5s, -webkit-transform 0.5s; } .carousel .content img:not(:first-of-type) { position: absolute; left: 0; top: 0; } .carousel .content img { display: block; width: 100%; height:488px; margin:0 auto; box-sizing: border-box; } .carousel .nav { width:83.6%; height: 100%; position: absolute; display: block; left: 8.4%; top:0; } .carousel .nav button { width: 38px; height: 70px; border:none; position: absolute; top:50%; margin-top:-30px; outline: none; cursor: pointer; } .carousel .nav .prev { background: url(../img/other/ly-oas7Prev.png) no-repeat; left: 33px; } .carousel .nav .next { background: url(../img/other/ly-oas7Next.png) no-repeat; right:36px; }
3、js代码
var content=$('.ly-oaSection7 .carousel .content')[0], images=$(content).find('img'), num=images.length, nav=$('.ly-oaSection7 .carousel button'); rotateRad= 2 * Math.PI / images.length,//旋转角度 currImage=0;//当前img function setupCarousel(n, s){ var ztfOrigin=s / (2 * Math.tan(Math.PI / n)); content.style.transformOrigin = '50% 50% ' + -ztfOrigin + 'px'; for (var i = 0; i < n; i++) { images[i].style.padding = 20+'px'; } for (i = 1; i < num; i++) { images[i].style.transformOrigin = '50% 50% ' + -ztfOrigin + 'px'; images[i].style.transform = 'rotateY(' + i * rotateRad + 'rad)'; } for (i = 0; i < num; i++) { images[i].style.backfaceVisibility = 'hidden'; } rotateCarousel(currImage); } function rotateCarousel(imageIndex) { content.style.transform = 'rotateY(' + imageIndex * -rotateRad + 'rad)'; } function setupNavigation() { $(nav).off('click').on('click',function(e){ e.stopPropagation(); var t = e.target; if (t.tagName.toUpperCase() != 'BUTTON') return; if($(this).hasClass('prev')){ currImage--; } else{ currImage++; } rotateCarousel(currImage); }); } setupCarousel(num,$(images[0]).width()); setupNavigation();
代码重点剖析:1、上面提到的子元素必须拥有z轴上的位移,这点是在js代码中实现的,通过transform-origin属性设置的,如下:
content.style.transformOrigin = '50% 50% ' + -ztfOrigin + 'px';
关于Z轴位移计算方法是参考网上的计算方法,如下:var ztfOrigin=s / (2 * Math.tan(Math.PI / n)),其中n代表旋转子元素数量,s代表旋转子元素的width。
通过transform-origin设置是方便设置元素旋转时的旋转中心点。
另设置Z轴位移也可通过translateZ设置,目前暂未实践。
2、元素每次旋转角度,rotateRad= 2 * Math.PI / images.length,其中images.length代表旋转子元素数量。
3、for (i = 0; i < num; i++) {
images[i].style.backfaceVisibility = 'hidden';
},其中.backface-visibility属性:元素不面向屏幕时是否可见。hidden即为背面不可见,visible即为背面可见。若取消:效果如下:
大致就是以上内容,文章不足之处也请指出,谢谢。
参考文章的链接:文章链接