美文网首页
3D transform (学习笔记)

3D transform (学习笔记)

作者: iStorm | 来源:发表于2017-08-23 17:26 被阅读0次

    原文: 张鑫旭老师的 好吧,CSS3 3D transform变换,不过如此!

    参考资料:w3school ||
    CSS 3D Panorama - 淘宝造物节技术剖析
    || 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转换,在参数中规定角度
    • 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属性所关联的布局框。值: 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)');
            })
    
        })()
    

    拓展实例:

    模拟开门特效(反方向)

    突然来了灵感,当然以前也看过同样的效果,当时很不解,不知道怎么实现,现在终于可以实现相类似的效果了。

    使用到的属性:

    • 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: 这只是单纯的实现了特效还未与js相结合、后端数据结合。

    相关文章

      网友评论

          本文标题:3D transform (学习笔记)

          本文链接:https://www.haomeiwen.com/subject/eoqjdxtx.html