「西安加油」前端简单实现2.5D大雁塔

1,702 阅读3分钟

PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛

前言

为了这次掘金的闹新春活动,我也算是苦思冥想了两天,因为现在西安的疫情,西安还在隔离中,所以想为西安加加油,希望疫情早日结束。

结果

下面是我实现的两个简单的效果图

1.gif

动画.gif

参考

视差特效的原理和实现方法 animejs官网

b78fcfe50f8347578925960667fa53f1_tplv-k3u1fbpfcp-zoom-crop-mark_1304_1304_1304_734.webp 谢谢这位大神(德育处主任)给的思路!!!

实现

html

    <div class="card">
        <p>西安加油</p>
        <img src="./img/dyt.png" alt="大雁塔">
    </div>

css

    * {
            margin: 0;
            padding: 0;
        }

        html,
        body {
            position: relative;
            height: 100%;
        }

        body {
            background: #fff;
            font-family: Georgia, "Times New Roman", Times, serif;
            font-size: 14px;
            color: #fff;
            margin: 0;
            padding: 0;
            vertical-align: middle;
            display: flex;
            align-items: center;
            justify-content: center;
            perspective: 50vw;
            perspective-origin: 50% 50%;
        }

        .card {
            position: relative;
            width: 185px;
            height: 260px;
            overflow: hidden;
            background-image: url(./img/xianrichu.jpg);
            background-repeat: no-repeat;
            background-position: 50% 50%;
            background-size: 110% 110%;
            transform-origin: 50% 50%;
            perspective: 1800px;
            transform-style: preserve-3d;
            border-radius: 8px;
            box-shadow: 0px 10px 20px 20px rgba(0, 0, 0, 0.17);
        }

        .card img {
            height: 40%;
            position: absolute;
            bottom: 5px;
            left: 80px;
        }

        .card p {
            text-align: center;
            margin-top: 50px;
            color: #fff700;
            font-size: 20px;
        }

静态效果

在HTML中写上上面的代码效果如下:

image.png

js(重点)

  • 引入animejs
    <script src="./js/anime.min.js"></script>
  • 编写js
    let clientWidth = document.body.clientWidth;
        let clientHeight = document.body.clientHeight;
        document.onmousemove = function (e) {
            e = e || window.event;
            let movex = 0;
            let movey = 0;
            if (e.pageX || e.pageY) {
                movex = e.pageX;
                movey = e.pageY
            }

            anime({
                targets: '.card',
                translateX: movex / 30 - 20,
                translateY: movey / 30 - 20,
                rotateX: (movey > clientHeight / 2 ? -1 : 1) * 5 + 'deg',
                rotateY: (movex > clientWidth / 2 ? 1 : -1) * 5 + 'deg',
                duration: 1000,
                easing: 'easeOutCirc'
            });

            anime({
                targets: '.card img',
                translateX: (movex - clientWidth / 2) / 30,
                translateY: (movey - clientHeight / 2) / 30,
                duration: 1000,
                easing: 'easeOutCirc'
            });

            anime({
                targets: '.card p',
                translateX: (movex - clientWidth / 2) / 30,
                translateY: (movey - clientHeight / 2) / 30,
                duration: 1000,
                easing: 'easeOutCirc'
            });
        }

这样就可以实现了!

动画1.gif

创新

通过上面的代码编写,我们只是实现了PC端,鼠标滑动时的动态效果,于是我先手机和pad上怎么办了?

  • 答案: 手机有陀螺仪

说干就干,话不多说,先看图

image.png

参考

html5的陀螺仪

使用浏览器传感器工具测试手机陀螺仪效果

手机实现

html

因为不好测试,我自己写了一个简单的工具:

     <div class="tool">
        <p>左右:<span id="alpha">0</span>
        </p>
        <p>前后:<span id="beta">0</span>
        </p>
        <p>扭转:<span id="gamma">0</span>
        </p>
    </div>

css

.tool {
    position: absolute;
    top: 0;
    left: 0;
    background: rebeccapurple;
    display: none;
}

@media screen and (max-width: 400px) {
    .tool {
        display: block;
    }
}

js

// 获取手机陀螺仪
    var updateGravity = function (event) {
        let x = Math.ceil(event.alpha * 100) / 100;
        let y = Math.ceil(event.beta * 100) / 100;
        let z = Math.ceil(event.gamma * 100) / 100;

        document.getElementById("alpha").innerHTML = x;
        document.getElementById("beta").innerHTML = y;
        document.getElementById("gamma").innerHTML = z;

        anime({
            targets: '.card',
            rotateX: (y > 0 ? 1 : -1) * 5 + 'deg',
            rotateY: (z > 0 ? 1 : -1) * 5 + 'deg',
            duration: 1000,
            easing: 'easeOutCirc'
        });


        anime({
            targets: '.card img',
            translateX: z % 180 / 5,
            translateY: y / 10,
            duration: 1000,
            easing: 'easeOutCirc'
        });

        anime({
            targets: '.card p',
            translateX: z % 180 / 5,
            translateY: y / 10,
            duration: 1000,
            easing: 'easeOutCirc'
        });

    };
    // 监听 window 的 deviceorientation 事件 
    window.addEventListener('deviceorientation', updateGravity, false);

调试

image.png

结果

image.png

重点

手机陀螺仪需要https环境,本地可以修改host解决

优化

增加红灯笼

因为是过年,想增加过年的气氛,所以增加了红灯笼,红灯笼的代码如下:

anime({
    targets: ['.deng', '.shui-a', '.shui-b', '.shui-c'],
    rotate: ['0deg', '10deg', '-10deg'],
    duration: 3000,
    loop: true,
    easing: 'easeInOutQuad'
});

推荐

日常开发中很少直接用原生的方式去实现视差效果的。

这里推荐一个 轻量JS动画库『Anime.js』

这个库的用法太简单了,直接看 《官方文档》 就知道怎么用了,本文不进行讲解。

013.gif

推荐文章

前端收藏,常用在线图片网站