灏天阁

CSS 实现爱心跟随鼠标效果

· Yin灏

CSS 实现爱心跟随鼠标效果!

前言

秋天都懂得浪漫,你天天被人说木讷,何不做点改变?今天我来教大家属于程序员的浪漫——使用 CSS 搭配 JS 实现爱心跟随鼠标发散效果。

添加文字

首先当然要将我们的文字添加上去啦。

<body>
  <div id="text">CatWatermelon</div>
</body>;;

很简单是不是,这才开始呢,我们接下来绘制背景先。

绘制背景

首先老规矩,我们将 CSS 样式重置 ,方便各个浏览器统一展示效果。

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

ps:大家开发的时候可不敢这么写,要不代码是上午写的,桶是下午提的了。

接下来通过添加 min-height: 100vh 属性,将 body 限制为 视口大小 且通过 overflow: hidden 来将 超出部分隐藏

body {
    min-height: 100vh;
    background-color: #111;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
}

注意这里用了 flex 布局实现了 水平垂直居中。小伙伴们平时喜欢什么方式来实现这个效果呢?

我们开始正戏前,先看看目前的效果:

微信截图_20221010193239.png

没啥问题,也不该有啥问题,可以接着走了。

爱心生成并跟随

这部分我们需要思考三个问题。

三个问题

  1. 怎么生成爱心,什么时候生成?
  2. 生成的爱心怎么跟随鼠标?
  3. 怎么让爱心消失?

爱心生成

我们一个一个看,首先是生成爱心,爱心我们可以用一张 透明爱心图片 充当,这里之所以要透明图片是因为防止 body 背景色和图片产生色差,影响美观。具体的,我们可以用一个容器 span ,将其背景 background 设置为这个爱心图片。如下所示:

span::before {
    content: "";
    position: absolute;
    width: 100px;
    height: 100px;
    background: url(./static/1.png);
    background-size: cover;
}

那么承载爱心的容器 span 应该在什么时候生成呢?明显的,我们鼠标移动的时候,会不停的创建小心心,那么我们应该在鼠标移动事件 mousemove 触发时,在回调中不断的通过 document.createElement 创建 span

跟随鼠标

创建好爱心后,我们为了实现爱心跟随鼠标的效果,应该将新生成的爱心的位置和鼠标位置同步。在 mousemove 事件中,回调函数的入参 e 对象中包含了 offsetXoffsetY 两个属性,通过这两个属性,我们就可以知道当前鼠标的位置,此时将爱心的位置也设置为 (offsetX, offsetY),就可以实现爱心跟随的效果了。

爱心消失

爱心消失我们可以设定一个时间,比如一秒,在上面创建 span 标签时,设置一个 setTimeout 定时器,指定一秒后通过实例调用 remove 方法,就可以实现爱心一秒后消失的效果啦。

document.addEventListener("mousemove", function (e) {
  let body = document.querySelector("body");
  let heart = document.createElement("span");
  let x = e.offsetX;
  let y = e.offsetY;
  heart.style.left = x + "px";
  heart.style.top = y + "px";

  body.appendChild(heart);

  setTimeout(() => {
    heart.remove();
  }, 1000);
});;

看看效果:

20221010_194749 (1).gif

可以发现稍微有点僵硬,我们尝试给爱心一个边向后偏移边旋转的动画试试:

span::before {
    animation: moveShape 1s linear infinite;
}
@keyframes moveShape {
    0% {
        transform: translate(0) rotate(0deg);
    }
    100% {
        transform: translate(300px) rotate(360deg);
    }
}

20221010_195057.gif

效果好很多啦,让我们继续添砖加瓦。

随机大小

如果我们能将每个爱心都设置成不同大小就好了,随机的大小像冒泡泡一样,显得更可爱。

我们可以通过一个随机数,来改变爱心容器 span 的大小。为了让每个 span 大小不会相差太多,我们可以用一个 固定宽高 作为基数,然后加上随机得到的一个数,作为最终的宽高。

document.addEventListener('mousemove', function(e) {
    //...
    let size = Math.random() * 80;
    heart.style.width = 20 + size + 'px';
    heart.style.height = 20 + size + 'px';

    body.appendChild(heart);
})

Math.random 方法返回的是 [0, 1) 之间的数,因此我们乘上一个系数放大 80,才更明显。

我们来看看此时的效果:

20221010_200204.gif

不错,味道好极了,啊不,是效果好极了,如果能加点旋转就好了。

让爱心转起来

同样的,我们可以用刚刚的思路,通过 rotate 属性动态的改变每个爱心的角度。

document.addEventListener('mousemove', function(e) {
    //...
    let transformValue = Math.random() * 360;
    heart.style.transform = `rotate(${transformValue}deg)`;

    body.appendChild(heart);
})

这里的系数我们要乘 360,表示有 360° 的角度可以随机到。此时我们再看看效果:

20221010_200125.gif

让爱心散开

为了让爱心能更浪漫点,我们需要将这些爱心在以鼠标坐标为中心,向四周散开。

相信大家都知道套路,实际上就是改变每个爱心的偏移,那么就要用到动画了。

 span::before {
    animation: moveShape 1s linear infinite;
}
@keyframes moveShape {
    0% {
        transform: translate(0) rotate(0deg);
    }
    100% {
        transform: translate(300px) rotate(360deg);
    }
}

我们设置在动画开始到动画结束的过程中,偏移量从 0 至 300px,同时旋转 360°。

让我们看看效果:

20221010_201603.gif

可以,已经很棒了。但是还不够,我们仔细看动图,可以发现爱心消失的很突然,所以我们接下来要淡化一下这么生硬的消失效果。

消失动画

为了让爱心消失的不那么突然,我们可以使用 opacity 搭配动画,从 1 到 0 的让爱心慢慢消失。

span {
    animation: fadeInOut 1s linear infinite;
}
@keyframes fadeInOut {
    0%,100% {
        opacity: 0;
    }
    20%, 80% {
        opacity: 1;
    }
}

看看我们的最终效果:

20221010_201247.gif

Github 源码地址

juejin-demo/heart-demo at main · catwatermelon/juejin-demo (github.com)

- Book Lists -