简单实现 3D 相册

1,559 阅读3分钟
原文链接: www.extlight.com

image

一、前言

之前写过《CSS3 动画简单入门》,文章内容只是简单介绍 CSS3 动画属性的使用,并没有一个综合的案例演示,因此本章作为前者的内容补充。

下面简单介绍本章需要实现的 3D 效果:

当加载页面后,图片展示“摊牌”的效果,当鼠标点击页面左滑动或者右滑动时,图片会跟随左旋转或右旋转。当鼠标点击页面上滑动或下滑动时,可以改变观察图片的角度。

二、实现

2.1 布局

<!DOCTYPE html>
<html onselectstart="return false">
<head>
    <meta charset="utf-8">
    <title>3D相册</title>
    <link href="css/style.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <div id="wrap" class="images">
            <img src="images/01.png" alt="">
            <img src="images/02.png" alt="">
            <img src="images/03.png" alt="">
            <img src="images/04.png" alt="">
            <img src="images/05.png" alt="">
            <img src="images/06.png" alt="">
            <img src="images/07.png" alt="">
            <img src="images/08.png" alt="">
            <img src="images/09.png" alt="">
            <img src="images/10.png" alt="">
            <img src="images/11.png" alt="">
        </div>
    </div>
    <script src="script/main.js"></script>
</body>
</html>

没有样式的效果图:

image

2.2 样式

style.css 文件内容:

* {
    margin: 0px;
    padding: 0px;
}
body {
    background-color: #000;
}
.container {
    perspective: 1500px;
}
.images {
    width: 100px;
    height: 100px;
    margin: 150px auto;
    position: relative;
    transform: rotateX(-20deg);
    transform-style: preserve-3d;/*切换 3D 效果*/
}
.images img {
    position: absolute;
    box-shadow: 0 0 8px #eee;
}

添加样式的效果图:

image

图片被设置 position: absolute; 后,所有图片重叠在一起了。

2.3 事件

从演示图中我们可以看出,3D 效果可以分 2 个步骤:摊牌效果和图片旋转效果。

2.3.1 摊牌效果

所有图片分摊 360 度,设置其旋转角度即可。

main.js 文件内容:

window.onload = function() {
    var wrap = document.getElementById("wrap");
    var images = document.getElementsByTagName("img");
    var length = images.length;
    var deg = 360 / length;
    for (var i = 0; i < length; i++) {
        images[i].style.transform = "rotateY(" + deg * i + "deg) translateZ(240px)";
        images[length - i - 1].style.transition = "1s " + 0.2 * i + "s";
    }
}

演示效果和动态图一样,此处省略。

所有图片包含在 div 中,当图片设置 rotateY 时,图片会以该 div 作为中心轴旋转。

图片还设置了 transition 属性,第一个参数表示过渡时间,第二个参数表示延迟时间。

2.3.2 旋转效果

实现图片旋转效果,只要改变中心轴的旋转角度即可。

main.js 文件完整内容:

window.onload = function() {
    var wrap = document.getElementById("wrap");
    var images = document.getElementsByTagName("img");
    var length = images.length;
    var deg = 360 / length;
    for (var i = 0; i < length; i++) {
        images[i].style.transform = "rotateY(" + deg * i + "deg) translateZ(240px)";
        images[length - i - 1].style.transition = "1s " + 0.2 * i + "s";
    }
    // 点击坐标
    var clickX, clickY;
    // 移动坐标
    var moveX, moveY;
    // 移动距离坐标
    var minusX, minusY;
    // 旋转角度
    var rotateX = 0,
        rotateY = -20;
    var timer = null;
    // 鼠标按下事件
    document.onmousedown = function(e) {
        clickX = e.clientX;
        clickY = e.clientY;
        // 鼠标移动
        this.onmousemove = function(e) {
            moveX = e.clientX;
            moveY = e.clientY;
            // 移动距离
            minusX = moveX - clickX;
            minusY = moveY - clickY;
            // 旋转角度,避免旋转太快故* 0.1
            rotateX += minusX * 0.1;
            rotateY -= minusY * 0.1;
            // 中心轴旋转
            wrap.style.transform = "rotateX(" + rotateY + "deg) rotateY(" + rotateX + "deg)"
            clickX = moveX;
            clickY = moveY;
        }
        // 鼠标释放
        this.onmouseup = function() {
            this.onmousemove = null;
            // 旋转惯性
            timer = setInterval(function() {
                minusX *= 0.99;
                minusY *= 0.98;
                // 旋转角度
                rotateX += minusX * 0.2;
                rotateY -= minusY * 0.1;
                // 中心轴旋转
                wrap.style.transform = 'rotateX(' + rotateY + 'deg) rotateY(' + rotateX + 'deg) ';
                if (Math.abs(minusX) < 0.1 && Math.abs(minusY) < 0.1) {
                    clearInterval(timer);
                }
            }, 10);
        }
    }
}

三、源码

rotate-photo-album