3D transform (學習筆記)

原文: 張鑫旭老師的 好吧,CSS3 3D transform變換陶贼,不過如此!待秃。

參考資料:w3school ||
CSS 3D Panorama - 淘寶造物節(jié)技術剖析
|| transform-function
|| 《css揭秘》

先來介紹以下transform 有哪些值:

  • none 定義不進行轉換
  • martix(n,n,n,n,n,n) 定義2D轉換拜秧,使用六個值的矩陣
  • martix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n) 定義3D轉換,使用16個值的4*4矩陣
  • translate(x, y) 定義2D轉換
  • translate3d(x, y, z) 定義3D轉換
  • translateX(x) 定義轉換章郁,只用 X 軸的值
  • translateY(y) 定義轉換枉氮,只用 y 軸的值
  • translateZ(z) 定義3D轉換,只用 z 軸的值
  • scale(x,y) 定義2D縮放轉換
  • scale3d(x, y, z) 定義3D縮放轉換
  • scaleX(x) 設置 x 軸的值來定義縮放轉換
  • scaleY(y) 設置 y 軸的值來定義縮放轉換
  • scaleZ(z) 設置 z 軸的值來定義縮放轉換
  • rotate(angle) 定義2D轉換暖庄,在參數(shù)中規(guī)定角度
  • rotate3d(x, y, z, angle) 定義3D轉換
  • rotateX(angle) 沿著 x 軸的3D旋轉
  • rotateY(angle) 沿著 y 軸的3D旋轉
  • rotateZ(angle) 沿著 z 軸的3D旋轉
  • skew(x-angle, y-angle) 沿著x和y軸的2D傾斜轉換
  • skewX(angle) 沿著 x 軸的2D傾斜轉換
  • skewY(angle) 沿著 y 軸的2D傾斜轉換
  • perspective(n) 為3D 轉換元素定義透視視圖

如果以電腦屏幕為參考物的話聊替,x軸就是電腦屏幕的長, y軸就是電腦屏幕的寬培廓,z軸就是眼睛直視電腦屏幕的距離惹悄,那么就會得到下面一張側視圖:

perspective

在開始之前先解釋一下幾個值:

  • perspective: 指定觀察者與 z = 0 平面的距離,使具有三維位置變換的元素產生透視效果肩钠。(默認值:none泣港,值只能是絕對長度)

  • transform-style:用于指定其子元素提供2D還是3D的場景。 值: flat | preserve-3d

  • backface-visiblity: 確定當面對用戶時元素背面是否可見 值: visible | hidden

  • perspective-origin: 決定觀察者正在查找的位置价匠,該位置就會消失

  • transform-box:transform-box屬性定義了transform和transform-origin屬性所關聯(lián)的布局框当纱。值: border-box | fill-box | view-box

  • transform-origin: 修改元素的變換原點 值: x-offset-keyword | y-offset-keyword | z-offset

我們都知道物體離的越近物體就越大,離的越遠物體就越小即: 當translateZ的值小于perspective的值時踩窖,物體就越大坡氯,當translateZ的值大于perspective的值時,物體消失。

實例: 圖片的旋轉木馬效果

原理: 讓圖片共用公共點箫柳,利用rotateY決定圖片朝向手形。

關鍵點: 使用translateZ 遠離原點

translateZ 計算:

diagram.png
calc.png

代碼:

html

<div class="stage">
    <div class="container">
        ![](img.jpg)
        ![](img1.jpg)
        ![](img2.jpg)
        ![](img.jpg)
        ![](img1.jpg)
        ![](img2.jpg)
        ![](img.jpg)
        ![](img1.jpg)
        ![](img2.jpg)
        ![](img.jpg)
    </div>
</div>

css

    * {
        padding: 0;
        margin: 0;
        font-size: 14px;
    }
    .stage {
        perspective: 800px;
        width: 80%;
        margin: 20% auto;

    }
    .container {
        position: relative;
        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        transform-style: preserve-3d;

        -webkit-transition:  -webkit-transform 1s;
        -moz-transition:  -moz-transform 1s;
        -ms-transition:  -ms-transform 1s;
        -o-transition:  -o-transform 1s;
        transition:  transform 1s;
    }
    img {
        width: 128px;
        height: 100px;
        position: absolute;
        left: 50%;
        margin: 0 0 0 -64px;
    }
    .pic {
        position: absolute;
        bottom: 0;
        border-radius: 2px;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
        -webkit-transition: opacity 1s, -webkit-transform 1s;
        -moz-transition: opacity 1s, -moz-transform 1s;
        -ms-transition: opacity 1s, -ms-transform 1s;
        -o-transition: opacity 1s, -o-transform 1s;
        transition: opacity 1s, transform 1s;
        backface-visibility:hidden;
    }
    img:nth-child(1){  transform: rotateY(0deg) translateZ(195.839px);  }
    img:nth-child(2){  transform: rotateY(40deg) translateZ(195.839px);  }
    img:nth-child(3){  transform: rotateY(80deg) translateZ(195.839px);  }
    img:nth-child(4){  transform: rotateY(120deg) translateZ(195.839px);  }
    img:nth-child(5){  transform: rotateY(160deg) translateZ(195.839px);  }
    img:nth-child(6){  transform: rotateY(200deg) translateZ(195.839px);  }
    img:nth-child(7){  transform: rotateY(240deg) translateZ(195.839px);  }
    img:nth-child(8){  transform: rotateY(280deg) translateZ(195.839px);  }
    img:nth-child(9){  transform: rotateY(320deg) translateZ(195.839px);  }
    img:nth-child(10){  transform: rotateY(360deg) translateZ(195.839px);  }

js

// CSS transform 變換應用
    (function() {
        var transform = function(el, val, key) {
            key = key || 'Transform';
            ['Moz', 'Ms', 'Webkit', 'o', ''].forEach(function(prefix) {
                el.style[prefix + key] = val;
            });
            return el;
        },
          // 瀏覽器選擇器API
        $ = function(selector) {
          return document.querySelector(selector);
        },
        $$ = function(selector) {
          return document.querySelectorAll(selector);
        }

        var imgArr = document.getElementsByClassName('pic');
        var eleStage = $('.stage'), eleContent = $('.container'), indexPic = 0,
            elePic = $$('pic'), transZ = 64 / Math.tan((2 / 180) * Math.PI);
        var rotate = 400 / imgArr.length;

        eleContent.addEventListener('click', function() {
          transform(this, 'rotateY(' + (- 1 * rotate * ++indexPic) + 'deg)');
        });

        imgArr.forEach(function(j) {
            transform($('.pic' ), 'rotateY(' + j * rotate + 'deg) translateZ(' + (transZ + 20) + 'px)');
        })

    })()

拓展實例:

模擬開門特效(反方向)

突然來了靈感,當然以前也看過同樣的效果滞时,當時很不解叁幢,不知道怎么實現(xiàn),現(xiàn)在終于可以實現(xiàn)相類似的效果了坪稽。

使用到的屬性:

  • transform-style
  • rotateY
  • transform-origin
  • animation-timing-function
  • cubic-bezier
  • animation

效果圖:

gif.gif

代碼:

html

<form action="#" class="form">
    <label for="username">
        <i>用戶名:</i><input type="text" class="username" name="username"></label>
    <label for="password">
        <i>密碼:</i><input type="password"  class="username" name="password"></label>
    <button class="login-text" type="button">登錄</button>
</form>
<div class="login">
    <button class="login-text" type="button">登錄</button>
</div>

css

* {
        margin: 0;
        padding: 0;
    }
    body {
        perspective: 500px;
    }
    .form {
        position: relative;
        display: block;
        width: 450px;
        height: 450px;
        margin: 10% auto;
        background: #3B445B;
        border-radius: 4px;
        transform-style: preserve-3d;
        transform: rotateY(0deg);
        transform-origin: 0 0;
        color: #f0f0f0;
        animation: login-rotate 3s;
    }
    label {
        float: left;
        margin: 70px 0 0 70px;
    }

    .login {
        position: absolute;
        top: 50%;
        left: 50%;
        width: 400px;
        height: 400px;
        margin:  -200px 0 0 -200px;
        transform: scale(0);
        background: #3B445B;
        border-radius: 4px;
        transform-origin: center;
        animation: login-show 3s;
    }
    .username {
        margin: 0 20px;
        padding: 3px 0;
        width: 200px;
        font-size: 18px;
    }
    .login-text {
        position: absolute;
        bottom: 40px;
        left: 70px;
        width: 300px;
        height: 40px;
        border-radius: 4px;
        background: #49D292;
        border: none;
        color: #f0f0f0;
        font-size: 16px;
    }
    i {
        width: 70px;
        float: left;
        font-style: normal;
    }
    @keyframes login-show {
        from {
            transform: scale(0);
            /*opacity: 0;*/
        }
        10% {
            opacity: 0.8;
        }
        80% {
            transform: scale(1.1);
            /*opacity: 1;*/
            animation-timing-function: cubic-bezier(.1, .25, .3, 1.5);
        }
        90% {
            /*opacity: 0;*/
        }
    }
    @keyframes login-rotate {
        from {
            transform: rotateY(0deg);
            opacity: 1;
        }
        10% {
            opacity: 1;
        }
        80% {
            transform: rotateY(90deg);
            opacity: 0;
        }
    }

Ps: 這只是單純的實現(xiàn)了特效還未與js相結合曼玩、后端數(shù)據(jù)結合。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末窒百,一起剝皮案震驚了整個濱河市黍判,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌篙梢,老刑警劉巖顷帖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渤滞,居然都是意外死亡贬墩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門妄呕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陶舞,“玉大人,你說我怎么就攤上這事绪励≈追酰” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵疏魏,是天一觀的道長停做。 經常有香客問我,道長大莫,這世上最難降的妖魔是什么蛉腌? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮葵硕,結果婚禮上眉抬,老公的妹妹穿的比我還像新娘。我一直安慰自己懈凹,他們只是感情好蜀变,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著介评,像睡著了一般库北。 火紅的嫁衣襯著肌膚如雪爬舰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天寒瓦,我揣著相機與錄音情屹,去河邊找鬼。 笑死杂腰,一個胖子當著我的面吹牛垃你,可吹牛的內容都是我干的。 我是一名探鬼主播喂很,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼惜颇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了少辣?” 一聲冷哼從身側響起凌摄,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漓帅,沒想到半個月后锨亏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡忙干,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年器予,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捐迫。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡劣摇,死狀恐怖,靈堂內的尸體忽然破棺而出弓乙,到底是詐尸還是另有隱情,我是刑警寧澤钧惧,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布暇韧,位于F島的核電站,受9級特大地震影響浓瞪,放射性物質發(fā)生泄漏懈玻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一乾颁、第九天 我趴在偏房一處隱蔽的房頂上張望涂乌。 院中可真熱鬧,春花似錦英岭、人聲如沸湾盒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罚勾。三九已至毅人,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尖殃,已是汗流浹背丈莺。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留送丰,地道東北人缔俄。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像器躏,于是被迫代替她去往敵國和親俐载。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內容

  • 作者:blue(又名一書and一世界) 我的github**用途: **當作字典來查 some websites ...
    一書and一世界閱讀 1,196評論 2 19
  • 2D邀桑、3D變形動畫 transform:2D變形:復合屬性 通過 CSS3 轉換瞎疼,我們能夠對元素進行移動、縮放壁畸、轉...
    Zd_silent閱讀 390評論 0 0
  • 關于css3變形 CSS3變形是一些效果的集合贼急,比如平移、旋轉捏萍、縮放和傾斜效果太抓,每個效果都被稱作為變形函數(shù)(Tra...
    hopevow閱讀 6,328評論 2 13
  • 看了很多視頻、文章令杈,最后卻通通忘記了走敌,別人的知識依舊是別人的,自己卻什么都沒獲得逗噩。此系列文章旨在加深自己的印象掉丽,因...
    DCbryant閱讀 1,861評論 0 4
  • 說說昨天的一段"奇遇"。 "今天天氣好晴朗示绊,處處好風光锭部;我在馬路邊撿到五分錢,把它交到警察叔叔……"咦面褐,看地上...
    骰子安紅豆閱讀 262評論 0 0