vue.js+ jquery+javascript+css+html实现炫酷动画电影墙效果

<!DOCTYPE html>
<html lang='en'>

<head>
    <meta charset='utf-8' />
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.min.js"></script>

    <style>
        li,
        ul,
        div,
        html,
        body {
            margin: 0;
            padding: 0;
        }

        html,
        body {
            height: 100%
        }

        li {
            list-style-type: none
        }

        .wrap {
            height: 100%;
            overflow: hidden;
            perspective: 800px;
        }

        #box {
            top: 50%;
            left: 50%;
            width: 0;
            height: 0;
            position: relative;
            transform-style: preserve-3d;
            transform: translateZ(-1600px);
            z-index: 1;
           
        }
   
        #box li img {
            top: -80px;
            left: -60px;
            width: 240px;
            height: 320px;
            position: absolute;
            text-align: center;
            line-height: 160px;
            background-color: rgba(5, 100, 80, 0.2);
            border: 1px solid rgba(125, 255, 255, 0.25);
            box-shadow: 0 0 15px rgba(0, 255, 255, 0.5);
            cursor: pointer;
        }

        #box li span {
            font-size: 28px;
            font-weight: blod;
            text-shadow: 2px 2px 5px black;
            color: #efebef;
        }

        .mask {
            width: 100%;
            height: 100%;
            background: url('https://materials.cdn.bcebos.com/images/40054665/64daa47e7470404400dd7add58431e8e.jpeg') no-repeat center;
            background-size: cover;
            filter: blur(5px);
        }

        .mask>.bg-mask {
            width: 100%;
            height: 100%;
            background: #000;
            opacity: 0.25;
        }
        .bottomstyle h1{
            width: 240px;
            background: white;
            height:100px;
            position: absolute;
            top:120px;
            left:-60px;
            color: #000;
            text-align: center;
        }
        .bottomstyle span{
            background: white;
            width: 240px;
            overflow: hidden;
            color: #000;
            text-align: center;
        }
       .callWard{
        padding-left: 30px;
        position: absolute;
           top: 0;
           left: 0;
           margin-top: 10px;
           z-index: 100;
           background: rgba(255,255,255,0.3);
           width: 300px;
           height: 50px;
        
        }
        .callWard::before{
            position: absolute;
            top:0;
            left: 0;
            content: "";
            background: #817b7b;
            width: 30px;
            height: 50px;
        }
        .callWard .text{
            color: #454444;
            font-size: small;

            font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
        }
    </style>
</head>

<body>
    <div class="callWard">
        
        <div class="text">提示词:</div>
        <div class="text">点击中间盒子照片区域可转化动画</div>
        <div class="text">点击白色区域可跳转响应top视频页面</div>
      </div>
    <div class="wrap">
        <ul id="box">
            <div id="app">
            </div>
        </ul>
       
        <div class="mask">
            <div></div>
         
        </div>
      
    </div>
    <script>
        Vue.config.devtools = true
        const Moveone = {
            template: `
            <div>
              
        <li v-for="item in items">
         <img :src="item.pic" alt="">
         <a :href="item.url" class="bottomstyle" target="_blank">
           <h1> {{item.title}}</h1>
            </a>
        </li>                
            </div>
        `,
            data() {
                return {
                    items:[{
                                     
                            "title": "海洋",
                            "url": "https://movie.douban.com/subject/3443389/",
                            "pic": "https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2559581324.jpg",
                            "rating_num": "9.1",
                            "commment_num": "154413人评价",
                            "info": "导演:雅克·贝汉JacquesPerrin/雅克·克鲁奥德JacquesCluzaud主演:...2009/法国瑞士西班牙美国阿联酋摩纳哥/纪录片"
                        },
                        {
                            "title": "穿越时空的少女",
                            "url": "https://movie.douban.com/subject/1937946/",
                            "pic": "https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2079334286.jpg",
                            "rating_num": "8.6",
                            "commment_num": "372498人评价",
                            "info": "导演:细田守MamoruHosoda主演:仲里依纱RiisaNaka/石田卓也Takuya...2006/日本/剧情爱情科幻动画"
                        },
                        {
                            "title": "我爱你",
                            "url": "https://movie.douban.com/subject/5908478/",
                            "pic": "https://img2.doubanio.com/view/photo/s_ratio_poster/public/p824590592.jpg",
                            "rating_num": "9.0",
                            "commment_num": "161733人评价",
                            "info": "导演:秋昌民Chang-minChoo主演:宋在河Jae-hoSong/李顺载Soon-jae...2011/韩国/剧情爱情"
                        },
                        {
                            "title": "地球上的星星",
                            "url": "https://movie.douban.com/subject/2363506/",
                            "pic": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2197897857.jpg",
                            "rating_num": "8.9",
                            "commment_num": "199772人评价",
                            "info": "导演:阿米尔·汗AamirKhan主演:达席尔·萨法瑞DarsheelSafary/阿...2007/印度/剧情儿童家庭"
                        }
                    ]
                }
            }
        }
   const vm= new Vue({
      template:`<Moveone></Moveone>
      `,
      el:'#app',
      components:{
            Moveone
      }
})
    </script>
       <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script>
        // 开启一个独立的空间避免全局变量污染
        (function () {
            let

                idx,
                timer,

                // 存放li 元素
                liElem,

                // 存放span 元素
                spanElem,

                // 记录布局类型
                currentStyle,

                // 鼠标X、Y坐标值
                oldCoordX,
                oldCoordY,
                nowCoordX,
                nowCoordY,

                // li 元素水平、垂直、纵深方向偏移位
                offsetStepX,
                offsetStepY,
                offsetStepZ,

                // li 元素的坐标
                liElemCoordX,
                liElemCoordY,
                liElemCoordZ,

                // 鼠标X、Y差值
                minusX = 0,
                minusY = 0,

                // X、Y偏移度数
                liElemDegX = 0,
                liElemDegY = 0,

                // li 元素的最大个数
                liElemMaxNum = 162,

                // li 元素 水平、垂直铺放的最大个数
                liElemRowMaxNum = 5,
                liElemColMaxNum = 5,

                // li 元素水平、垂直、纵深方向的最大间隔距离
                liElemOffsetX = 350,
                liElemOffsetY = 350,
                liElemOffsetZ = 350,

                // li 元素默认景深
                liElemDepDefault = -1000,

                // 避免覆盖默认景深值
                depDefault = liElemDepDefault - 600;

            // 避免第一次拖动发生错位
            liElemDepZ = liElemDepDefault - 600,

                // 单个方阵中 li 元素的总个数
                aScreenNum = liElemRowMaxNum * liElemColMaxNum,

                // li 元素纵深方向的最在间隔距离
                liElemDepMaxDist = parseInt(liElemMaxNum / aScreenNum),

                // 计算第一个li 元素的坐标点
                liElemFristSiteX = parseInt('-' + liElemRowMaxNum / 2) * liElemOffsetX,
                liElemFristSiteY = parseInt('-' + liElemColMaxNum / 2) * liElemOffsetY,
                liElemFristSiteZ = parseInt('-' + liElemDepMaxDist / 2) * liElemOffsetZ,

                // 文本内容
                data = [''];

            // 指定一个区间,获取一个随机数
            randomFrom = (lowerValue, upperValue) => {
                return Math.floor(Math.random() * (upperValue - lowerValue + 1) + lowerValue);
            }

            // 方阵
            gridLayout = _ => {
                let arr = [...Array(liElemMaxNum).keys()];
                $('#box li').each(i => {
                    // 数组的索引
                    let idx = randomFrom(0, arr.length - 1);

                    // 计算li 元素 水平、垂直、纵深方向的偏移位
                    offsetStepX = ((i % aScreenNum) % liElemRowMaxNum) * liElemOffsetX;
                    offsetStepY = parseInt((i % aScreenNum) / liElemColMaxNum) * liElemOffsetY;
                    offsetStepZ = parseInt(i / aScreenNum) * liElemOffsetZ;

                    // 计算当前li 元素的坐标值
                    liElemCoordX = liElemFristSiteX + offsetStepX;
                    liElemCoordY = liElemFristSiteY + offsetStepY;
                    liElemCoordZ = liElemFristSiteZ + offsetStepZ;

                    $('#box li').eq(arr[idx]).css({
                        "transform": `translate3d(${liElemCoordX}px,${liElemCoordY}px,${liElemCoordZ}px)`,
                        "transition": "4s ease-in-out"
                    })

                    // 删除数组中的值
                    arr.splice(idx, 1);
                });
                currentStyle = gridLayout;
            }

            // 螺旋
            helixLayout = _ => {
                let arr = [...Array(liElemMaxNum).keys()];
                $('#box li').each(i => {
                    let idx = randomFrom(0, arr.length - 1);
                    let liElemDegY = 10 * i;
                    let liElemDepY = -10 * parseInt(liElemMaxNum / 2) + 10 * i;

                    $('#box li').eq(arr[idx]).css({
                        "transform": `rotateY(${liElemDegY}deg) translateY(${liElemDepY}px) translateZ(${Math.abs(liElemDepDefault)}px)`,
                        "transition": "4s ease-in-out"
                    })

                    // 删除数组中的值
                    arr.splice(idx, 1)
                });
                currentStyle = helixLayout;
            }

            // 球形
            sphereLayout = _ => {
                let arr = [...Array(liElemMaxNum).keys()];
                $('#box li').each(i => {
                    let idx = randomFrom(0, arr.length - 1);
                    let liElemDegY = 3 * i;
                    let liElemDegX = 30 * i;

                    $('#box li').eq(arr[idx]).css({
                        "transform": `rotateY(${liElemDegY}deg) rotateX(${liElemDegX}deg) translateZ(${Math.abs(liElemDepDefault)}px)`,
                        "transition": "4s ease-in-out"
                    })

                    // 删除数组中的值
                    arr.splice(idx, 1)
                });
                currentStyle = sphereLayout;
            }

            // 三体
            threeLayout = _ => {
                let arr = [...Array(liElemMaxNum).keys()];
                $('#box li').each(i => {
                    let idx = randomFrom(0, arr.length - 1);
                    let liElemDegY = 3 * i;
                    let liElemDegX = 60 * i;

                    $('#box li').eq(arr[idx]).css({
                        "transform": `rotateY(${liElemDegY}deg) rotateX(${liElemDegX}deg) translateZ(${Math.abs(liElemDepDefault)}px)`,
                        "transition": "4s ease-in-out"
                    })

                    // 删除数组中的值
                    arr.splice(idx, 1)
                });
                currentStyle = threeLayout;
            }

            // 几何
            geomeLayout = _ => {
                let arr = [...Array(liElemMaxNum).keys()];
                $('#box li').each(i => {
                    let idx = randomFrom(0, arr.length - 1);
                    let liElemDegY = 8.9 * i;
                    let liElemDegX = 2.9 * i;

                    $('#box li').eq(arr[idx]).css({
                        "transform": `rotateY(${liElemDegY}deg) rotateX(${liElemDegX}deg) translateZ(${Math.abs(liElemDepDefault)}px)`,
                        "transition": "4s ease-in-out"
                    })

                    // 删除数组中的值
                    arr.splice(idx, 1)
                });
                currentStyle = geomeLayout;
            }

            // 曲线
            curveLayout = _ => {
                let arr = [...Array(liElemMaxNum).keys()];
                $('#box li').each(i => {
                    let idx = randomFrom(0, arr.length - 1);
                    let liElemDegY = 1 * i;
                    let liElemDegX = 2 * i;

                    $('#box li').eq(arr[idx]).css({
                        "transform": `rotateY(${liElemDegY}deg) rotateX(${liElemDegX}deg) translateZ(${liElemDepDefault}px)`,
                        "transition": "4s ease-in-out"
                    })

                    // 删除数组中的值
                    arr.splice(idx, 1)
                });
                currentStyle = curveLayout;
            }

            // 随机
            chaoticLayout = _ => {
                $('#box li').each(function (i) {
                    // 随机生成li 元素的坐标点
                    liElemCoordX = (Math.random() - 0.5) * 3000;
                    liElemCoordY = (Math.random() - 0.5) * 3000;
                    liElemCoordZ = (Math.random() - 0.5) * 3000;

                    $(this).css({
                        "transform": `translate3d(${liElemCoordX}px,${liElemCoordY}px,${liElemCoordZ}px)`,
                        "transition": "4s ease-in-out"
                    })
                });
                currentStyle = chaoticLayout;
            }

            function main() {
                $([...Array(liElemMaxNum).keys()]).each(i => {
                    // 创建一个li 元素
                    liElem = $('<li></li>');
                    let idx = randomFrom(0, data.length - 1);

                    // 创建一个span 元素
                    spanElem = $(`<span>${data[idx]}</span>`);
                    liElem.append(spanElem);

                    // 设置span 中的文本颜色
                    spanElem.css('color',
                        `rgb(${randomFrom(100,255)},${randomFrom(100,255)},${randomFrom(100,255)})`);

                    // 将已创建的li 元素添加至容器中
                    $('#box').append(liElem);
                })

                // 布局类型
                layoutStyle = [gridLayout, helixLayout, chaoticLayout, sphereLayout,
                    threeLayout, geomeLayout, curveLayout
                ];

                // 鼠标移入移出效果
                $('#box li').hover(function () {
                    $(this).css('border', '1px solid rgba(125,255,255,0.75)');
                    $(this).css('boxShadow', '0 0 15px rgba(0,255,255,0.75)');
                    $(this).css('transition', '0s');
                }, function () {
                    $(this).css('border', '1px solid rgba(125,255,255,0.25)');
                    $(this).css('boxShadow', '0 0 15px rgba(0,255,255,0.5)');
                    $(this).css('transition', '0s');
                })

                // 鼠标点击,切换布局
                $('#box li').click(function () {
                    switch ($(this).text()) {
                        case 'Grid':
                            gridLayout();
                            break;
                        case 'Helix':
                            helixLayout();
                            break;
                        case 'Three':
                            threeLayout();
                            break;
                        case 'Geome':
                            geomeLayout();
                            break;
                        case 'Curve':
                            curveLayout();
                            break;
                        case 'Sphere':
                            sphereLayout();
                            break;
                        case 'Chaotic':
                            chaoticLayout();
                            break;

                        default:
                            while (true) {
                                idx = randomFrom(0, layoutStyle.length - 1);
                                if (layoutStyle[idx] != currentStyle) {
                                    return layoutStyle[idx]();
                                }
                            }
                            break;
                    }
                })

                // 鼠标拖动与滚轮效果
                $(document).mousedown(function (event) {
                    event = event || window.event;

                    // 上一个点的X、Y坐标
                    oldCoordX = event.clientX;
                    oldCoordY = event.clientY;

                    $(this).on('mousemove', event => {
                        event = event || window.event;

                        // 若上一个定时器存在,则将其删除
                        timer && clearInterval(timer);

                        // 当前点的X、Y坐标
                        nowCoordX = event.clientX;
                        nowCoordY = event.clientY;

                        // 计算机X、Y差值
                        minusX = nowCoordX - oldCoordX;
                        minusY = nowCoordY - oldCoordY;

                        // 更新上一个点的X、Y坐标值
                        oldCoordX = nowCoordX;
                        oldCoordY = nowCoordY;

                        // 计算X、Y轴的移动度数
                        liElemDegX -= minusY * 0.1;
                        liElemDegY += minusX * 0.1;

                        $('#box').css({
                            "transform": `translateZ(${liElemDepZ}px) rotateX(${liElemDegX}deg) rotateY(${liElemDegY}deg)`
                        })


                    }).mouseup(_ => {
                        // 当鼠标弹起解除移动
                        $(document).off('mousemove');

                        // 若上一个定时器存在,则将其删除
                        timer && clearInterval(timer);

                        // 鼠标弹起后有缓动效果
                        timer = setInterval(_ => {
                            // 缓动差值 
                            minusX *= 0.95;
                            minusY *= 0.95;

                            // 计算X、Y轴的移动度数
                            liElemDegX -= minusY * 0.1;
                            liElemDegY += minusX * 0.1;

                            // 当差值超出指定范围时,则清除定时器
                            Math.abs(minusX) < 0.05 &&
                                Math.abs(minusY) < 0.05 &&
                                clearInterval(timer);

                            $('#box').css({
                                "transform": `translateZ(${liElemDepZ}px) rotateX(${liElemDegX}deg) rotateY(${liElemDegY}deg)`
                            })
                        }, 12);
                    })

                }).on('mousewheel DOMMouseScroll', e => {
                    // 若上一个定时器存在,则将其删除
                    timer && clearInterval(timer);

                    // 获取鼠标滚动方向
                    let step = (e.originalEvent.wheelDelta &&
                            (e.originalEvent.wheelDelta > 0 ? 1 : -1)) ||
                        (e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1));

                    // 计算滚轮滚动时Z 轴景深的步长
                    liElemDepZ = depDefault += step * 90;

                    $('#box').css({
                        "transform": `translateZ(${liElemDepZ}px) rotateX(${liElemDegX}deg) rotateY(${liElemDegY}deg)`
                    })

                    // 设置缓动效果
                    timer = setInterval(_ => {
                        // 缓动步长
                        step *= 0.6;
                        liElemDepZ += step * 80;

                        Math.abs(step) < 0.000005 &&
                            clearInterval(timer);

                        $('#box').css({
                            "transform": `translateZ(${liElemDepZ}px) rotateX(${liElemDegX}deg) rotateY(${liElemDegY}deg)`
                        })
                    }, 12);
                })

                // 加载布局
                setTimeout(gridLayout, 1000);
            }

            main();

        })();
    </script>
</body>

</html>

效果图如下:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值