这个博客已经过去了很久……

不过,你可以通过以下方式找到我

现在的位置: 首页 > 谈前端 > CSS > 正文
CSS3D变换介绍(An Introduction to CSS 3D Transforms)[2]
2014年01月09日 CSS ⁄ 共 3256字 等你评论
续……CSS3D变换介绍(An Introduction to CSS 3D Transforms)[1]

转盘(Carousel,或者叫走马灯效果)

前端开发者有很多内容转盘可以选择。既然我们的浏览器支持3D,为什么不尝试创建一个真正的3D转盘呢?

HTML标记仍然和上面的demo差不多。我们可以为了趣味性来创建一个有9个面板的转盘。

<div>
   <div id="carousel">
     <figure>1</figure>
     <figure>2</figure>
     <figure>3</figure>
     <figure>4</figure>
     <figure>5</figure>
     <figure>6</figure>
     <figure>7</figure>
     <figure>8</figure>
     <figure>9</figure>
   </div>
 </div>

接着是页面结构的样式。为#carousel的每个面板留20像素的空隙,在这里使用样式left:10px和top: 10px。每个面板的有效宽度为210像素。

.container {
  width: 210px;
  height: 140px;
  position: relative;
  -webkit-perspective: 1000;
}
#carousel {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transform-style: preserve-3d;
}
#carousel figure {
  display: block;
  position: absolute;
  width: 186px;
  height: 116px;
  left: 10px;
  top: 10px;
  border: 2px solid black;
}

接着进行旋转。#carousel有九个面。平均分配的话,每个面板应该旋转(360/9=40deg)。

#carousel figure:nth-child(1) { -webkit-transform: rotateY(0deg); }
#carousel figure:nth-child(2) { -webkit-transform: rotateY(40deg); }
#carousel figure:nth-child(3) { -webkit-transform: rotateY(80deg); }
#carousel figure:nth-child(4) { -webkit-transform: rotateY(120deg); }
#carousel figure:nth-child(5) { -webkit-transform: rotateY(160deg); }
#carousel figure:nth-child(6) { -webkit-transform: rotateY(200deg); }
#carousel figure:nth-child(7) { -webkit-transform: rotateY(240deg); }
#carousel figure:nth-child(8) { -webkit-transform: rotateY(280deg); }
#carousel figure:nth-child(9) { -webkit-transform: rotateY(320deg); }

现在我们需要计算移动值。在创建立方体和盒子的demo里,计算translate值非常简单,因为它等于3D对象宽度、高度或者深度的一半。对于转盘来说,我们需要按照下图所示的方法来计算移动距离。

diagram

 

画一个转盘图,我们看到已知两个变量:每个转盘面板的宽度为210像素,以及每个面板每次的转动角度。我们将其中一个转盘面板沿着它的中心线切开,会得到一个直角三角形,这样就非常适合使用三角形法来计算了。

我们可以使用一个基本的正切公式来计算图中r的长度:

calc

 

译者注:正切=对边/邻边

得出每个面板的移动距离为288像素。

#carousel figure:nth-child(1) { -webkit-transform: rotateY(0deg) translateZ(288px); }
#carousel figure:nth-child(2) { -webkit-transform: rotateY(40deg) translateZ(288px); }
#carousel figure:nth-child(3) { -webkit-transform: rotateY(80deg) translateZ(288px); }
#carousel figure:nth-child(4) { -webkit-transform: rotateY(120deg) translateZ(288px); }
#carousel figure:nth-child(5) { -webkit-transform: rotateY(160deg) translateZ(288px); }
#carousel figure:nth-child(6) { -webkit-transform: rotateY(200deg) translateZ(288px); }
#carousel figure:nth-child(7) { -webkit-transform: rotateY(240deg) translateZ(288px); }
#carousel figure:nth-child(8) { -webkit-transform: rotateY(280deg) translateZ(288px); }
#carousel figure:nth-child(9) { -webkit-transform: rotateY(320deg) translateZ(288px); }

如果要修改面板的宽度或者数量,我们只需要在方程中修改这两个值就能得到合适的translateZ值。用javascript表示这个方程如下所示:

var tz = Math.round((panelSize / 2) / Math.tan((( Math.PI * 2 ) / numberOfPanels ) /2 ));
// 或者简化为
var tz = Math.round((panelSize / 2) / Math.tan( Math.PI / numberOfPanels));

和上面的demo一样,要显示某个面板,我们只需要在转盘上应用相反的transform。例如第五个面板:

-webkit-transform: translateZ(-288px) rotateY(-160deg);

参考示例:Carousel1

carousel01

 

现在你可能会有两个想法:

  1. 为每个面板重写transform样式看上去很繁琐;
  2. 为什么需要高中数学知识呢?不应该自动帮我算好吗?

你的想法绝对是对的!3D对象的重复特性可以使用脚本来处理。我们可以把上面庞大的transform样式改写到动态脚本里。这样做比硬编码到样式里具有更大的灵活性。

请参考示例:Carousel2

总结

这篇文章由浅入深详细介绍了CSS3中的3D transform。内容很丰富,如果时间紧张,可以先体验demo,相信你一定会有收获!

参考资料

  1. 英文原文
  2. caniuse css 3d transform
  3. w3 css3-transforms
  4. w3scholl.com.cn perspective
  5. http://www.zhangxinxu.com/wordpress/2012/09/css3-3d-transform-perspective-animate-transition/
  6. http://www.alloyteam.com/2012/10/the-css3-transform-perspective-property/
  7. http://css-tricks.com/almanac/properties/p/perspective/
  8. http://desandro.github.io/3dtransforms/
  9. http://www.w3cplus.com/content/css3-transform
  10. 维基百科--正切

 

友荐云推荐
×