web前端开发【连载8】-CSS3 2D/3D转换
2017-04-13 本文已影响41人
Iris_mao
今天天气好晴朗处处好风光伴随着好天气的到来心情都更加明朗了呢是不是该学点烧脑的内容了呢傻球也要出来晒晒太阳咯~
CSS3 3D transform变换
- rotateX, rotateY, rotateZ和perspective
rotate旋转的意思,rotateX旋转X轴,rotateY旋转Y轴,rotateZ旋转Z轴……
perspective的中文意思是:透视,视角!说的简单一点就是距离屏幕的距离,值越大说明距离屏幕越远看到的旋转角度幅度就比较小,值越小说明距离屏幕比较近看到的旋转角的幅度就比较大。。。解释的比较苍白,还是用代码来说话吧。。。大家可以随意改变值看看变化基本就能意会是个什么意思了,perspective对于Z轴是不起作用的。
<!DOCTYPE html5>
<meta charset="utf-8">
<html>
<title>css3 3d transform</title>
<style type="text/css">
.container {
display: inline-block;
width: 200px;
height: 200px;
margin: 50px;
border: 1px solid #bbb;
}
.container span{
color:#000;
font-weight:bold;
}
.box {
width: 100%;
height: 100%;
opacity: .75;
}
#darkred .box {
background-color: darkred;
transform: perspective(600px) rotateX(45deg);
}
#darkred1 .box {
background-color: darkred;
transform: perspective(200px) rotateX(45deg);
}
#orange .box {
background-color: orange;
transform:perspective(600px) rotateY(45deg);
}
#green .box {
background-color: green;
transform:perspective(200px) rotateZ(45deg);
}
</style>
<body>
<section id="darkred" class="container">
<div class="box"><span>rotateX</span></div>
</section>
<section id="darkred1" class="container">
<div class="box"><span>rotateX perspective(200px)</span></div>
</section>
<section id="orange" class="container">
<div class="box"><span>rotateY</span></div>
</section>
<section id="green" class="container">
<div class="box"><span>rotateZ</span></div>
</section>
</body>
</html>
结果图.png
- translateZ
我们都知道近大远小的道理,对于没有rotateX以及rotateY的元素,translateZ的功能就是让元素在自己的眼前或近或远。就是设置translateZ属性将元素沿着所在的方向向前(水平)移动多少距离。就是比如将几张图片做成旋转木马的效果,当它们放在那里的时候肯定是重叠的,第一步就是将它们沿着中心点分别旋转不同的角度,这时候它们会像扇子一样张开,第二步就是将它们分别往外拉一段距离,这个操作就是设置translateZ属性。。。不知道这样解释有没有明白,在后面做旋转图片的例子中会有具体体现。 - transform-style
transform-style属性也是3D效果中经常使用的,其两个参数,flat|preserve-3d. 前者flat为默认值,表示平面的;后者preserve-3d表示3D透视。 - 图片做成旋转木马效果实例
建议在足够新版本的FireFox浏览器或Safari浏览器下观看,Chrome可能需要居中定位查看,下图为效果缩略图:
旋转木马图片效果.png
原理:那些看上去很酷酷的CSS3 3D效果其实就颠来倒去那几个属性(本文提到的这几个),折腾来折腾去,这里这个效果显然也是如此。
首先HTML结构,如下:舞台里放容器,容器里面放图片 图片 图片 ...
对于舞台,很简单,加个视距,比方说800像素:
perspective: 800px;
对于容器,很简单,加个3D视图声明,如下:
transform-style: preserve-3d;
然后就是图片们了。为了不至于产生类似DNA的螺旋状效果,我们让所有图片position:absolute
,公用同一个中心点。
显然,图片旋转木马是类似钢管舞旋转的运动,因此,我们关心的是rotateY
的大小。因为要正好绕成一个圈,因此,图片rotateY值正好0~360等分,于是,如果有9张图片,则每个图片的旋转角度累加40(360 / 9 = 40)度即可。因此有:
img:nth-child(1) { transform: rotateY( 0deg ); }
img:nth-child(2) { transform: rotateY( 40deg ); }
img:nth-child(3) { transform: rotateY( 80deg ); }
img:nth-child(4) { transform: rotateY( 120deg ); }
img:nth-child(5) { transform: rotateY( 160deg ); }
img:nth-child(6) { transform: rotateY( 200deg ); }
img:nth-child(7) { transform: rotateY( 240deg ); }
img:nth-child(8) { transform: rotateY( 280deg ); }
img:nth-child(9) { transform: rotateY( 320deg ); }
这样就好了吗?
No, No, No!!!
想想看那,虽然9个绝色美女每个人的方位不一样,但都站在同一个点上,早就挤作一团,显然是不行的(见下图只设置rotateY)!我们需要拉开空间~~
如何拉开空间,很简单。
想想看那:9个美女,分别面朝东南西北共9个不同方位,她们只要每个人向前走个45步,美女们之间的空间不久拉开了,呈现圆形了!这里的向前走45步,聪明的人应该已经知道了,就是本文提到的translateZ, 当translateZ为正值的时候,元素会向其面对的方向走去;如果元素无旋转,就会朝显示器走来!!
现在只剩下一个问题了,美女们要向前走多远呢??
这个距离是有计算公式滴!
拿本demo距离,每张美女图片的宽度是128像素,因此,有如下理想方位效果图:
上图中红色标注的r就是的demo页面中图片要translateZ的理想值(该值可以让所有图片无缝围成一个圆)!r的计算很简单,有初中数学水平的人应该都会:
r = 64 / Math.tan(20 / 180 * Math.PI) ≈ 175.8
demo页面为了好看,图片之间留了点间距,使用的translateZ的值为175.8 + 20 = 195.8。
最后的最后,要让木马旋转起来,只要让容器每次旋转40度就可以了。
节省篇幅,具体的JavaScript操作代码的注释都在代码中体现了,静态html中的img可以不写直接在js中动态生成,跟着鑫神的整理3D的基本原理很好理解,就看自己能不能驾驭咯~
<!DOCTYPE html5>
<meta charset="utf-8">
<html>
<title>css3 3d transform</title>
<style type="text/css">
.container {
width: 128px;
height: 100px;
-webkit-transition: -webkit-transform 1s; /*设置transform的变换持续1s*/
-moz-transition: -moz-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
position: absolute;
left: 20%;
top:8%;
}
.piece {
width: 128px;
box-shadow: 0 1px 3px rgba(0,0,0,.5);
-webkit-transition: opacity 1s, -webkit-transform 1s; /*设置不透明度持续1s,trnasform变换持续1s*/
-moz-transition: opacity 1s, -moz-transform 1s;
transition: opacity 1s, transform 1s;
position: absolute; /*为了使图片围绕同一个点进行旋转*/
bottom: 0;
}
.remind {
position: absolute;
left: 1em;
top: 1em;
}
</style>
<body>
<div id="stage" class="stage_area" style="top: 0px;">
<strong class="remind">点击任意图片浏览:</strong>
<div id="container" class="container" style="transform: rotateY(-200deg);">
![](http:https://img.haomeiwen.com/i3810529/24e0600c31dabd2a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <!--控制图片旋转的角度和图片往所在方向正前方移动的距离-->
![](http:https://img.haomeiwen.com/i3810529/6e70740c9487e717.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http:https://img.haomeiwen.com/i3810529/408dd1a3f33e835a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http:https://img.haomeiwen.com/i3810529/7835bc415d14138d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http:https://img.haomeiwen.com/i3810529/de7980354c7bfb11.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http:https://img.haomeiwen.com/i3810529/c287ff54e0583c68.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http://image.zhangxinxu.com/image/study/s/s128/mm10.jpg)
![](http:https://img.haomeiwen.com/i3810529/b34f9284c31e6fa7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http:https://img.haomeiwen.com/i3810529/7be11d31c4e16314.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</div>
</body>
<script>
(function() {
if (typeof window.screenX === "number") {
// CSS transform变换应用
var transform = function(element, value, key) {
key = key || "Transform";
["Moz", "O", "Ms", "Webkit", ""].forEach(function(prefix) {
element.style[prefix + key] = value;
});
return element;
}
// 浏览器选择器API
, $ = function(selector) {
return document.querySelector(selector);
}, $$ = function(selector) {
return document.querySelectorAll(selector);
};
// 显示图片
var htmlPic = '', arrayPic = [1, 8, 3, 4, 6, 7, 10, 13, 15], rotate = 360 / arrayPic.length;
arrayPic.forEach(function(i) {
htmlPic = htmlPic + '![](http://image.zhangxinxu.com/image/study/s/s128/mm'+ i +'.jpg)';
});
// 元素
var eleStage = $("#stage"), eleContainer = $("#container"), indexPiece = 0; //获取舞台和容器元素,indexPiece为每次旋转增加的角度
// 元素
var elePics = $$(".piece"), transZ = 64 / Math.tan((rotate / 2 / 180) * Math.PI); //获取所有图片元素,transZ为图片透视的位置
eleContainer.innerHTML = htmlPic; //将图片元素添加到容器中,所以在静态html中不用先将img元素加进去
eleContainer.addEventListener("click", function() { //舞台的单机事件:点击舞台,舞台就沿着Y轴旋转一个图片的角度
transform(this, "rotateY("+ (-1 * rotate * ++indexPiece) +"deg)");
});
arrayPic.forEach(function(i, j) { //将每个图片旋转对应的角度,沿z轴移动相应的距离,所以在静态html中不用单个设置
transform($("#piece" + i), "rotateY("+ j * rotate +"deg) translateZ("+ (transZ + 20) +"px)");
});
// 垂直位置居中 - Chrome浏览器
var funStageValign = function(element) {
var scrollTop = document.documentElement.scrollTop, clientHeight = document.documentElement.clientHeight;
offsetTop = element.getBoundingClientRect().top;
if (parseInt(window.getComputedStyle(element).top) === 0) {
element.style.top = scrollTop + (window.innerHeight - 300) / 2 - offsetTop;
} else {
element.style.top = "0px";
}
};
}
})();
</script>
</html>
最后献上鑫神神一般的讲解:好吧,CSS3 3D transform变换,不过如此!