web前端开发【连载8】-CSS3 2D/3D转换

今天天气好晴朗处处好风光伴随着好天气的到来心情都更加明朗了呢是不是该学点烧脑的内容了呢傻球也要出来晒晒太阳咯~

傻球晒太阳咯

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://upload-images.jianshu.io/upload_images/3810529-24e0600c31dabd2a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  <!--控制图片旋转的角度和图片往所在方向正前方移动的距离-->
                    ![](http://upload-images.jianshu.io/upload_images/3810529-6e70740c9487e717.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
                    ![](http://upload-images.jianshu.io/upload_images/3810529-408dd1a3f33e835a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
                    ![](http://upload-images.jianshu.io/upload_images/3810529-7835bc415d14138d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
                    ![](http://upload-images.jianshu.io/upload_images/3810529-de7980354c7bfb11.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
                    ![](http://upload-images.jianshu.io/upload_images/3810529-c287ff54e0583c68.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
                    ![](http://image.zhangxinxu.com/image/study/s/s128/mm10.jpg)
                    ![](http://upload-images.jianshu.io/upload_images/3810529-b34f9284c31e6fa7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
                    ![](http://upload-images.jianshu.io/upload_images/3810529-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变换,不过如此!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 一、写在前面的秋裤 早在去年的去年,我就大肆介绍了2D transform相关内容。看过海贼王的都知道,带D的家伙...
    MrZengB阅读 1,336评论 2 9
  • 当我看到下面这张基本图的时候,我的右侧的浓眉毛不由自主抖动了两下,呵,呵呵~~ rotateY( angle ) ...
    追風逸少丶阅读 1,486评论 0 3
  • 关于css3变形 CSS3变形是一些效果的集合,比如平移、旋转、缩放和倾斜效果,每个效果都被称作为变形函数(Tra...
    hopevow阅读 6,317评论 2 13
  • 1、属性选择器:id选择器 # 通过id 来选择类名选择器 . 通过类名来选择属性选择器 ...
    Yuann阅读 1,619评论 0 7
  • CSS里transform变形这个属性有点学习难度,尤其在CSS3里加上了3D效果之后,2维变3维学习成本更是成倍...
    张歆琳阅读 27,693评论 5 81