这个鼠标跟随效果被我一晚上硬撸出来了~

前段时间,咱们摸金群的小伙伴发了一个网站的首页很有意思,鼠标移动,眼睛会跟着移动,并且还会眨眼,很久不动了,眼睛还会闭起来,链接在这:坏打印机。大家可以在线感受下。我也录了个gif图片,是不是有点意思?

bad.gif

今天我们一步一步把它给实现了。

获取底图资源

从官网看,这整个底图就是一个svg。我们把它copy到我们自己的html中,并设置下body背景色为黑色:

image.png

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background-color: #000;
        }
    </style>
</head>

<body>
    <svg data-v-5d3d8b0b="" id="logo_svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 734 554.58">
        <g data-v-5d3d8b0b="" id="图层_2" data-name="图层 2">
            <g data-v-5d3d8b0b="" id="图层_1-2" data-name="图层 1" fill="#fff">
                <path data-v-5d3d8b0b=""
                    d="M711.91,360,520.69,81a186.32,186.32,0,0,0-307.38,0L22.09,360c-26.55,38.74-29.33,86.68-7.44,128.23s63,66.36,110,66.36H609.37c47,0,88.08-24.81,110-66.36S738.46,398.73,711.91,360ZM367,329.86c74.92,0,135.88,43,135.88,95.83s-61,95.82-135.88,95.82-135.88-43-135.88-95.82S292.08,329.86,367,329.86Zm176,95.83c0-32.79-14.79-64-41.81-88.39a57.24,57.24,0,1,0-96.07-44.4,233.21,233.21,0,0,0-76.22,0,57.24,57.24,0,1,0-96.07,44.4c-27,24.43-41.81,55.6-41.81,88.39,0,33.2,14.88,64.27,42.24,88.78H124.63c-31.82,0-59.66-16.81-74.49-45s-13-60.61,5-86.85l191.22-279C274.08,63.27,318,40.11,367,40.11s92.92,23.16,120.6,63.55l191.22,279c18,26.24,19.87,58.71,5,86.85s-42.67,45-74.49,45H500.76C528.11,490,543,458.89,543,425.69Z"
                    class="cls-1"></path>
            </g>
            <g data-v-5d3d8b0b="" id="图层_1-2" data-name="图层 1" fill="#fff"
                transform="translate(13.60081135328548, -1.3109917530108988)">
                <path data-v-5d3d8b0b=""
                    d="M349.43,410.21a21.3,21.3,0,0,0,35.14,0l23.19-33.83a13.79,13.79,0,0,0-11.37-21.58H337.61a13.79,13.79,0,0,0-11.37,21.58Z"
                    class="cls-1"></path>
            </g>
            <circle data-v-5d3d8b0b="" r="24" fill="black"
                transform="translate(297.4478007306761, 284.46662534712266) scale(1, 0.9961503835103371)"></circle>
            <circle data-v-5d3d8b0b="" cx="270" cy="290" r="24" fill="rgba(0, 0, 0, 0)"></circle>
            <circle data-v-5d3d8b0b="" r="24" fill="black"
                transform="translate(488.95544468246584, 282.42345712276835) scale(1, 0.9961503835103371)"></circle>
            <circle data-v-5d3d8b0b="" cx="462" cy="290" r="24" fill="rgba(0, 0, 0, 0)"></circle>
        </g>
    </svg>
</body>
</html>

image.png

布局排版

我们让这个svg置于浏览器中心,并设置宽高:

<style>
    html,body{
        padding: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
    }
    body {
        background-color: #000;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    #logo_svg {
        width: 600px;
        height: 453px;
    }
</style>

image.png

ok,前两步都是准备工作,接下来要开始真正秀操作了!

操作svg元素

我们先把svg里面中文命名的id改成英文,方便我们获取:

image.png

扫描二维码关注公众号,回复: 14405640 查看本文章

小试牛刀

我们先拿鼻子来试试水吧,看下能不能改变它的位置,让它动起来。我们先拿到它的元素:

<script>
    const nose = document.getElementById('nose');
    console.log(nose);
</script>

image.png

看这后面跟着一串数字没,原网站用的是transform属性来改变位置,我们来试验一下,我们每隔0.2秒就改变一下鼻子的位置:

    const nose = document.getElementById('nose');
    setInterval(() => {
        let x = Math.random() * 50;
        let y = Math.random() * 50;
        nose.setAttribute('transform', `translate(${x}, ${y})`);
    }, 200);

bad1.gif

哈哈哈,有意思,后面只需根据鼠标移动改变鼻子的位置即可。咱们后面再说。我们再来看看眼睛部分:

可以看到我圈起来的部分,提供了一个圆心位置,猜测是为了定位眼睛可转动的范围,这边它的填充色是透明的,所以为了简化实现,咱们可以定义两个变量,保存这两个圆心的位置,这两个circle咱们就可以删了

image.png

删完后,效果没变。我们获取2个眼睛就可以这么写:

    const eyes = document.querySelectorAll('circle');
    console.log(eyes);

image.png

用刚刚的方法,试着改变眼睛的位置:

    const eyes = document.querySelectorAll('circle');
    setInterval(() => {
        let x = Math.random() * 20 * Math.pow(-1, Math.floor(Math.random()*2)) + 270;
        let y = Math.random() * 20 * Math.pow(-1, Math.floor(Math.random()*2)) + 290;
        eyes[0].setAttribute('transform', `translate(${x}, ${y})`);
        eyes[1].setAttribute('transform', `translate(${x + 462 - 270}, ${y})`);
    }, 200)

bad2.gif

哈哈哈,笑死了,真的魔性~ ok,现在我们试着用鼠标来控制眼睛鼻子的位置

鼠标控制

    document.body.addEventListener('mousemove', (e) => {
        // 获取鼠标当前位置
        let x = e.clientX;
        let y = e.clientY;
        // 计算鼠标位置距离眼睛的长度值
        let ex = x - (window.innerWidth - 600) / 2 - 220;
        let ey = y - (window.innerHeight - 453) / 2 - 240;

        // 根据三角函数计算出眼睛和鼻子的位置
        let angle = ex / ey;
        let sy = ey > 0 ? Math.cos(Math.atan(angle)) * 20 : -Math.cos(Math.atan(angle)) * 20;
        let sx = ey > 0 ? Math.sin(Math.atan(angle)) * 20 : -Math.sin(Math.atan(angle)) * 20;
        eyes[0].setAttribute('transform', `translate(${sx + 270}, ${sy + 290})`);
        eyes[1].setAttribute('transform', `translate(${sx + 462}, ${sy + 290})`);
        // 鼻子幅度小一点
        nose.setAttribute('transform', `translate(${sx / 5}, ${sy / 5})`);
    })

bad3.gif

哎呀,这三角函数整了我半天啊,不知道对不对。不过效果好像是这么回事了哈哈哈。

码上掘金

往期作品

# 一个30+大龄前端的2022年中总结(还贷,还情,还我金铲铲)

# 我用PIXI + GSAP导了一出好戏《刹车》 | 猿创营

# UI不给切图?那就自己写一个!(真香警告)

这些都很不错哟,喜欢的可以丢个赞呀,感谢感谢!最后祝大家工作爱情双丰收~

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿

猜你喜欢

转载自juejin.im/post/7124709471745474591