css3实践之摩天轮式图片轮播+3D正方体+3D标签云(perspective、transform-style、perspective-origin)
本文主要通过摩天轮式图片轮播的例子来讲解与css3 3D有关的一些属性。
demo预览:
前文回顾
在前面的文章css3实践之图片轮播(Transform,Transition和Animation)中我们简单地了解了css3旗下的transform、transition以及animation。回顾一下,transform主要是对元素进行拉伸、旋转、移动等等操作,transition能使元素从一种样式逐渐改变为另一种的效果,而animation能使元素依次进行n种样式之间的变化。其实对我而言,感兴趣的还是前两者,毕竟做动画不是css的强项。
本文demo主要涉及css3的perspective、transform-style、perspective-origin属性。
perspective、transform-style、perspective-origin
前两个属性是css3下实现3d效果必不可少的,为什么这样讲,我们通过例子来说明。
首先我们根据demo需要写好基本的html文件,其中核心代码截图如下:

html结构主要有三层,#stage->#container->.img。stage表示3d大舞台,里面可以包含很多的3d容器(container),而容器内则是需要向“观众"呈现的拥有3d效果的东西(demo里是图片)。
- perspective
这里隆重推出perspective属性,perspective可以解释成视距,通俗讲perspective值即视点(perspective-origin)到电脑屏幕的距离(z轴方向),值越小,用户与3D空间Z平面距离越近。如果没有设置perspective属性,元素就不会拥有3D效果,仿佛是从很远地方看到的一个视图(可以联想一下三视图)。

perspective有两种书写方式,第一种是写在舞台上,第二种是写在3d元素上,与transform的其他属性写在一起,代码分别如下:
#stage {
width: 805px;
height: 600px;
border: 1px solid;
-webkit-perspective: 500px;
-webkit-perspective-origin: 17% 50%;
}
img {
position: absolute;
top: 110px;
-webkit-transform: perspective(600px) rotateY(45deg);
}
第二种也就是使得每个3d元素都有视点(默认为元素中心),我觉得几乎用不到,毕竟动画特效都需要模拟人眼看到的结果,也就是一个视点。
两种方式对比可以猛戳张鑫旭写的demo:猛戳这里 感谢作者~
- perspective-origin
与perspective关系密切的还有它的好兄弟perspective-origin,perspective解释为视距,那么perspective-origin就是视点。perspective-origin属性可空缺,默认为perspective-origin: 50% 50%,即从舞台(stage)中央看起(如果perspective属性加在stage的话),而perspective-origin和perspective一般同时出现(即加在同一个元素的css下),具体取值方法可参考CSS3 transform-origin 属性
实例代码可参考perspective实例代码
- transform-style
transform-style和perspective一样重要,二者缺一不可。其中flat值为默认值,表示所有子元素在2D平面呈现。preserve-3d表示所有子元素在3D空间中呈现。沿着X轴或Y轴方向旋转该元素将导致位于正或负Z轴位置的子元素显示在该元素的平面上,而不是它的前面或者后面。如果对一个元素设置了transform-style的值为preserve-3d,它表示不执行平展操作,他的所有子元素位于3D空间中。既然我们都说要实现3d效果了,一般取值当然是preserve-3d了!
transform-style属性需要设置在3d动画元素的父元素中,并且高于任何嵌套的变形元素。实例代码:
#container {
position: absolute;
width: 500px;
height: 500px;
-webkit-transform-style: preserve-3d;
-webkit-transition: all 2s ease-in-out;
}
- backface-visibility
顾名思义,就是决定元素旋转背面是否可见。如下分别是有没有将demo里的3d元素的backface-visibility属性设置成hidden的结果:

实例代码(对应第二张图):
img {
position: absolute;
top: 110px;
-webkit-backface-visibility: hidden;
}
小结:所以以后如果要写3d效果的css元素,只要像demo一样在html文件中写好stage和container元素,然后在stage中加上perspective,再在container中加入transform-style:preserve-3d 基本就ok了。
关于摩天轮式图片轮播
先写好#stage->#container->.img形式的html文件,加上perspective和transform-style属性,9张图片分享360度,可使每张图片围绕x轴旋转40*i度角:

然后每张图片再设置translateZ的值,就会使得图片分开来围成圈:
var imgs = document.getElementsByTagName('img');
for(var i = 0; i <= 8; i++) {
var deg = 40 * i;
imgs[i].style.webkitTransform = ''
+ 'rotateX(' + deg + 'deg)'
+ 'translateZ(' + 190 + 'px)'
+ 'scale(0.25,0.25)';
}
最后再加上鼠标滚轮事件,每次滚动使得container元素整体绕x轴转动指定角度就行了,当然转动过程还需要transition的帮助:
var containerDeg = 0;
window.onmousewheel = document.onmousewheel = function(e) {
containerDeg += e.wheelDelta / 15 ;
document.getElementById('container').style.webkitTransform = 'rotateX(' + containerDeg + 'deg)'
}
有一点值得注意,就是原始图片的中心和container的中心要一致,只需设置图片(position:absolute)的left和top值就可以了。
完整源代码可参考:源码请猛戳
关于3D正方体和3D标签云
3D正方体和3D标签云(css3版)实现方式和图片轮播相似,都是在源点绕x轴和y轴旋转一定角度后,利用translateZ这个方法围绕源点分散开去。
- 3D正方体
设置6个长宽一样的div,然后分别绕x和y轴旋转需要的角度后,设置相同的translateZ值(为了方便写在js里了,也可以直接算出值写在css里):
// init
var initAngleX = [0, 180, 90, 270, 0, 0];
var initAngleY = [0, 0, 0, 0, 90, 270];
var angleX = 0;
var angleY = 0;
// container的旋转角度
var totalAngleX = 0;
var totalAngleY = 0;
for(var i = 0; i < 6; i++) {
var d = document.createElement('div');
d.style.backgroundColor = '#' + ('00000' + parseInt(Math.random() * 0xffffff).toString(16)).slice(-6);
d.className = 'face';
d.style.webkitTransform = ''
+ 'rotateX(' + initAngleX[i] + 'deg)'
+ 'rotateY(' + initAngleY[i] + 'deg)'
+ 'translateZ(' + 50 + 'px)';
document.getElementById('container').appendChild(d);
}
然后为了效果添加旋转,这里直接设置setInterval函数改变整个container的旋转角度了:
// addListener
document.getElementById('container').addEventListener("mousemove" , function(event){
var x = event.clientX - 200;
var y = event.clientY - 200;
window.angleY = x / 10 / 1000 * 60;
window.angleX = -y / 10 / 1000 * 60;
});
setInterval(function() {
totalAngleX += angleX;
totalAngleY += angleY;
document.getElementById('container').style.webkitTransform = ''
+ 'rotateX(' + totalAngleX + 'deg)'
+ 'rotateY(' + totalAngleY + 'deg)';
}, 1000 / 60);
你也可以将效果直接写在css上,比如设置个伪类(:hover),里面写好改变的css,然后设置下transition就ok了。
- 3D标签云
做了两个版本的,js版和css3版,不过其实都要用到js,只是后者的核心是css3。
先来回顾一下js版本,或许js版本更适合实际使用,确实如此,现实中类似的3d标签云基本上都是js实现的。js版本的核心是获取平均分配在一个球面上的n个点的3维坐标,然后将z轴扁平化降到二维进行绘制,球体旋转时获得新的坐标进行重绘,demo中则是进行a标签新的位置确定。如需了解更多可参考我以前写的文章《rotate 3d基础》
js版本里扁平化中的“焦距”(focalLength)就是css3里的perspective。
js版z轴扁平化代码:
focalLength = 300;
var scale = focalLength / (focalLength + this.pos3.z);
this.pos2.x = 150 + this.pos3.x * scale;
this.pos2.y = 150 + this.pos3.y * scale;
this.a.style.fontSize = 12 * scale;
this.a.style.color = 'rgba('+this.r+','+this.g+','+this.b+','+ Math.min(1, scale)+')';
pos3是3d空间的位置,而pos2是2d的位置,利用的是三角形相似(近大远小):

屏幕位置和成像位置的距离就是3d物体的z值大小。
而css3版本的则不然,省去了繁琐的3d->2d转换过程,a标签直接能进行3d变化。只是元素在进行旋转过程中,a标签内的文字也无法控制地旋转。
具体就不展开了,有兴趣的可以参考源码:猛戳这里
以前用js写过的3d特效(猛戳demo1demo2demo3),其实也可以用css3实现,核心的函数就是rotate和translate!有兴趣的可以试一试。
总结
总的来说,如果要使dom元素呈现3d效果,perspective和transform-style属性的设置是必不可少的。
因为上面一篇文章有园友反映没做兼容,本文的图片轮播demo我还特地做了兼容(ff下的渲染真是渣...),但是还是没能兼容360,也不知道什么原因,反正做兼容很蛋疼就是了,以后还是有需求的时候再做兼容吧...
楼主对以上理解尚不深入,如有问题欢迎交流指导。
参考文章:
css3实践之摩天轮式图片轮播+3D正方体+3D标签云(perspective、transform-style、perspective-origin)的更多相关文章
- bootstrap中的动态加载出来的图片轮播中的li标签中的class="active"的动态添加移除
//该方法是在slide改变时立即触发该事件, $('#myCarousel').on('slide.bs.carousel', function () { $("#myCarousel o ...
- 纯CSS3代码实现简单的图片轮播
以4张图片为例:1.基本布局:将4张图片左浮动横向并排放入一个div容器内,图片设置统一尺寸,div宽度设置4个图片的总尺寸,然后放入相框容器div,相框设置1个图片的大小并设置溢出隐藏,以保证正确显 ...
- css3实践之图片轮播(Transform,Transition和Animation)
楼主喜欢追求视觉上的享受,虽常以牺牲性能无法兼容为代价却也乐此不疲.本文就通过一个个的demo演示来简单了解下css3下的Transform,Transition和Animation. 本文需要实现效 ...
- jQuery - 广告图片轮播切换
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 原生js+css3实现图片自动切换,图片轮播
运用CSS3transition及opacity属性 制作图片轮播动画 自己这两天根据用js来控制触发CSS3中transition属性,从而写出来的以CSS3动画为基础,js控制过程的图片轮播 运用 ...
- CSS3图片轮播效果
原文:CSS3图片轮播效果 在网页中用到图片轮播效果,单纯的隐藏.显示,那再简单不过了,要有动画效果,如果是自己写的话(不用jquery等),可能要费点时间.css3的出现,让动画变得不再是问题,而且 ...
- 使用纯css3实现图片轮播
<!DOCTYPE html> <html> <head> <title> 飛天网事--纯CSS代码实现图片轮播 </title> < ...
- 个人练习:使用HTML+CSS3制作图片轮播功能(不使用JavaScript)
先上效果图,不要在意用来当素材的图片: 在搜索相关资料的时候,查到有两种实现方式:一是使用JavaScript,二是使用CSS3中的Animation(动画),这里使用的是CSS3中的Animatio ...
- 推荐一款超级漂亮的HTML5 CSS3的图片轮播器
最近在学习HTML5和CSS3,印象最深的是CSS3的动画功能,不仅有浏览器原生支持,执行效率高,而且免去在js中自己管理timer. 本来想写一个图片轮播器练练手,结果在网上发现一个国人写的开源的图 ...
随机推荐
- Windows7 系统 CMD命令行,点阵字体不能改变大小以及中文乱码的问题
之前装了oracle 11g后,发现开机速度竟然奇葩的达到了3分钟.经过旁边大神指点,说是因为oracle某个(具体不清楚)服务,在断网的时候会不断的ping网络,导致速度变慢.然后就关服务呗,然后一 ...
- SQL Server 分隔字符串函数实现
在SQL Server中有时候也会遇到字符串进行分隔的需求.平时工作中常常遇到这样的需求,例如:人员数据表和人员爱好数据表,一条人员记录可以多多人员爱好记录,而往往人员和人员爱好在界面展示层要一并提交 ...
- hash查找
这里使用了编号代替真实的数据,只用来表示算法 #ifndef HASH_DATA_T #define HASH_DATA_T int #endif //HASH_DATA_T typedef stru ...
- shell 面试题
1. 用sed修改test.txt的23行test为tset: sed –i ‘23s/test/tset/g’ test.txt 2. 查看/web.log第25行第三列的内容. ...
- 七、Android学习第六天——SQLite与文件下载(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 七.Android学习第六天——SQLite与文件下载 SQLite SQ ...
- Jquery 的遍历,祖先、后代、同胞以及其过滤
什么是遍历? jQuery 遍历,意为“移动”,用于根据其相对于其他元素的关系来“查找”(或选取)HTML 元素.以某项选择开始,并沿着这个选择移动,直到抵达您期望的元素为止. 下图展示了一个家族树. ...
- shell tips
1.shopt 命令可以设置shell的可选参数 shopt [-psu] [optname...] -s 开启某个选项 -u 关闭某个选项 -p 列出所有可设置的选项 其中开启extglob选项,s ...
- [转载]ExtJs4 笔记(12) Ext.toolbar.Toolbar 工具栏、Ext.toolbar.Paging 分页栏、Ext.ux.statusbar.StatusBar 状态栏
作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)版权声明:本文的版权归作者与博客园共有.转载时须注明本文的详细链接,否则作者将保留追究其法律 ...
- Java中的ReentrantLock和synchronized两种锁定机制的对比
问题:多个访问线程将需要写入到文件中的数据先保存到一个队列里面,然后由专门的 写出线程负责从队列中取出数据并写入到文件中. http://blog.csdn.net/top_code/article/ ...
- C#复习(学生信息输入)
在控制台程序中使用结构体.集合,完成下列要求项目要求:一.连续输入5个学生的信息,每个学生都有以下4个内容:1.序号 - 根据输入的顺序自动生成,不需要手动填写,如输入第一个学生的序号是1,第二个是2 ...