首页 /  web前端 /  css3 / html5 3D照片墙

0 21

html5 3D照片墙

html5 3D照片墙_图一
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>3D照片墙</title>
        <style>
            html,
            body {
                margin: 0;
                padding: 0;
                background-color: #29454d;
                /*禁止文字被选中*/
                -moz-user-select: none;
                /*火狐*/
                -webkit-user-select: none;
                /*webkit浏览器*/
                -ms-user-select: none;
                /*IE10*/
                -khtml-user-select: none;
                /*早期浏览器*/
                user-select: none;
            }

            .box {
                position: relative;
                height: 500px;
                width: 500px;
                margin: 100px auto;
                transform-style: preserve-3d;
                perspective: 2000px;
            }

            .di {
                position: absolute;
                left: 50%;
                top: 50%;
                height: 200px;
                width: 200px;
                transform: translate(-50%, -50%) rotatex(90deg);
                transform-style: preserve-3d;
            }

            .z {
                position: relative;
                height: 200px;
                width: 200px;
                border-radius: 50%;
                transform-style: preserve-3d;
                transform: rotatez(1deg);
            }

            p {
                margin: 0;
                position: absolute;
                top: 0;
                /*为了保证圆心在父盒子中心,父盒子旋转时圆心稳定,所以设置left*/
                left: 25px;
                height: 200px;
                width: 150px;
                border: 2px solid #fd7068;
                box-sizing: border-box;
                background-color: #ffffff;
                background-size: cover;
                background-position: center;
                background-repeat: no-repeat;
                /*opacity: .7;*/
                font-size: 10px;
                line-height: 200px;
                text-align: center;
                /*box-shadow: 0 0 100px #16ff8b;*/
                /*倒影,不兼容*/
                -webkit-box-reflect: below 10px -webkit-linear-gradient(top, rgba(250, 250, 250, 0), rgba(250, 250, 250, .0) 30%, rgba(250, 250, 250, 0.5));
                box-reflect: below 10px -webkit-linear-gradient(top, rgba(250, 250, 250, 0), rgba(250, 250, 250, .0) 30%, rgba(250, 250, 250, 0.5));
                /*backface-visibility: hidden;*/
            }
        </style>
    </head>

    <body>
        <div class="box">
            <div class="di">
                <div class="z">
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                    <p>可以拖拽图片文件进来</p>
                </div>
            </div>
        </div>
        <script>
            window.onload = function() {
                //声明变量s为鼠标移动距离和改变角度的比例
                var s = 15;
                var zbox = document.querySelector('.z');
                var dibox = document.querySelector('.di');
                var ps = document.querySelectorAll('p');
                //声明鼠标移动速度的两个变量
                var timer = null;
                var xs = 0;
                var ys = 0;
                //给每个p标签设置位置
                for(var i = 0; i < ps.length; i++) {
                    ps[i].style.transform = 'rotatex(-90deg) rotatey(' + i * 30 + 'deg) translatez(400px)'
                }
                //鼠标按下
                window.onmousedown = function(e) {
                        //清除旋转盒子过渡属性
                        dibox.style.transition = '';
                        zbox.style.transition = '';
                        //          $(dibox).css('transition', '');
                        //          $(zbox).css('transition', '');
                        //声明计算速度用的初始时间tc,初始值等于鼠标按下时的时间
                        var tc = new Date().getTime();
                        //声明t,初始值和按下时间相同
                        var t = tc;
                        //每隔2毫秒更新现在时间t
                        timer = setInterval(function() {
                                t = new Date().getTime();
                            }, 2)
                            //取得按下时的坐标
                        var xc = e.clientX;
                        var yc = e.clientY;
                        //声明计算速度用的初始坐标初始值等于按下时的坐标
                        var xsc = xc;
                        var ysc = yc;
                        //获取3d状态矩阵,处理后得到x轴旋转角度(0~180度之间)
                        var cc = window.getComputedStyle(dibox).transform;
                        //          var cc = $(dibox).css('transform');
                        cc = cc.split(',');
                        cc = Math.acos(cc[5]) / Math.PI * 180;
                        //调用函数得到z轴旋转角度(把matrix()矩阵转换为旋转角度)
                        var zc = getz(zbox);
                        //绑定鼠标移动事件
                        window.onmousemove = function(e) {
                            var x = e.clientX;
                            var y = e.clientY;
                            //如果现在时间和初始时间差值大于10
                            //计算一下鼠标速度xs;ys
                            //重新赋值用来计算速度的初始时间和初始坐标
                            if(t - tc > 10) {
                                xs = (x - xsc) / (t - tc) * 15;
                                xs = xs;
                                ys = (y - ysc) / (t - tc) * 10;
                                ys = ys / 2;
                                tc = t;
                                xsc = x;
                                ysc = y;
                            }
                            //根据鼠标y坐标移动距离计算新的x轴旋转角度并设置给盒子样式,范围1~179
                            //如果转到0或者180时,就完全看不到了,而且获取到的矩阵就变成了6个参数的,下次在拖动时,转换成角度的方法就不适用了
                            var c = cc - (y - yc) / s > 179 ? 179 : (cc - (y - yc) / s < 1 ? 1 : cc - (y - yc) / s);
                            dibox.style.transform = 'translate(-50%, -50%) rotatex(' + c + 'deg)';
                            //              $(dibox).css('transform', 'translate(-50%, -50%) rotatex(' + c + 'deg)')
                            //根据鼠标x坐标移动距离计算新的z轴旋转角度并设置给盒子样式
                            var z = zc - (x - xc) / s;
                            //如果角度大于不在0-360度间,取0-360之间对应的值
                            z = z > 360 ? z - 360 : z < 0 ? 360 + z : z;
                            //测试发现在0.5附近和359.48以上时获取角度的函数会出错(可能是因为js对于小数计算不精确的原因,计算角度时要用三角函数),直接跳过这一段
                            if(z > 359.48) {
                                z = 359.48;
                            }
                            if(z < 0.51 && z > 0.49) {
                                z = 0.49;
                            }
                            zbox.style.transform = 'rotatez(' + z + 'deg)';

                        }
                    }
                    //鼠标松开
                window.onmouseup = function() {
                        levae();
                    }
                    //鼠标松开事件封装函数
                function levae() {
                    //清除用来计算速度时用的计时器,移除鼠标移动事件
                    clearInterval(timer);
                    window.onmousemove = null;
                    if(ys !== 0 || xs !== 0) {
                        //获取到x轴旋转的角度
                        var cc = window.getComputedStyle(dibox).transform;
                        cc = cc.split(',');
                        cc = Math.acos(cc[5]) / Math.PI * 180;
                        //获取到z轴旋转的角度
                        var zc = getz(zbox);
                        //结合速度算出目标状态
                        var c = cc - (ys) > 179 ? 179 : (cc - (ys) < 1 ? 1 : cc - (ys));
                        var z = zc - (xs);
                        //避免跨越0度和360度
                        z = z > 359.48 ? 359.48 : z < 0 ? 0 : z;
                        if(z < 0.51 && z > 0.49) {
                            z = 0.49;
                        }
                        //速度重置为0
                        ys = 0;
                        xs = 0;
                        //设置给盒子目标状态并且加上过渡属性
                        dibox.style.transform = 'translate(-50%, -50%) rotatex(' + c + 'deg)';
                        dibox.style.transition = 'transform  0.5s ease-out';
                        zbox.style.transform = 'rotatez(' + z + 'deg)';
                        zbox.style.transition = 'transform  0.5s ease-out';
                    }
                }

                //获取z轴旋转角度函数
                //引用自:http://blog.csdn.net/u010884130/article/details/50005437
                /*
                 * 解析matrix矩阵,0°-360°,返回旋转角度
                 * 当a=b||-a=b,0<=deg<=180
                 * 当-a+b=180,180<=deg<=270
                 * 当a+b=180,270<=deg<=360
                 *
                 * 当0<=deg<=180,deg=d;
                 * 当180<deg<=270,deg=180+c;
                 * 当270<deg<=360,deg=360-(c||d);
                 * */
                function getz(element) {
                    var c = window.getComputedStyle(element).transform;
                    c = c.split('(')[1].split(',');
                    var aa = Math.round(Math.asin(c[0]) / Math.PI * 180);
                    var bb = Math.round(Math.acos(c[1]) / Math.PI * 180);
                    var cc = Math.round(Math.asin(c[2]) / Math.PI * 180);
                    var dd = Math.round(Math.acos(c[3]) / Math.PI * 180);
                    var deg = 0;
                    if(aa == bb || -aa == bb) {
                        deg = Math.acos(c[3]) / Math.PI * 180;
                    } else if(-aa + bb == 180) {
                        deg = 180 + Math.asin(c[2]) / Math.PI * 180;
                    } else if(aa + bb == 180) {
                        deg = (360 - Math.asin(c[2]) / Math.PI * 180) || (360 - Math.acos(c[3]) / Math.PI * 180);
                    }
                    return deg >= 360 ? 0 : deg;
                    //return (aa+','+bb+','+cc+','+dd);
                }
                //取消鼠标拖拽文件进入窗口的默认行为
                window.ondragover = function(e) {
                    e.preventDefault();
                }
                window.ondrop = function(e) {
                        e.preventDefault();
                }
                //添加拖拽到p标签的事件
                for(var i = 0; i < ps.length; i++) {
                    ps[i].index = i;
                    ps[i].ondrop = function(e){
                        var w = new FileReader();
                        w.index = this.index;
                        w.readAsDataURL(e.dataTransfer.files[0]);
                        w.onload = function(){
                            ps[this.index].style.backgroundImage = 'url('+w.result+')';
                            ps[this.index].innerHTML = '';
                        }
                    }
                }
            }
        </script>
    </body>
</html>

[来源] https://www.qdfuns.com

[声明] 本站资源来自用户分享,如损害你的权益请联系客服QQ:120074275给予处理。

添加一条新回复
容若 2019-09-05 19:14
10
送花
20积分一朵