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
布局实现了 水平垂直居中。小伙伴们平时喜欢什么方式来实现这个效果呢?
我们开始正戏前,先看看目前的效果:
没啥问题,也不该有啥问题,可以接着走了。
爱心生成并跟随
这部分我们需要思考三个问题。
三个问题
- 怎么生成爱心,什么时候生成?
- 生成的爱心怎么跟随鼠标?
- 怎么让爱心消失?
爱心生成
我们一个一个看,首先是生成爱心,爱心我们可以用一张 透明爱心图片 充当,这里之所以要透明图片是因为防止 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
对象中包含了 offsetX
和 offsetY
两个属性,通过这两个属性,我们就可以知道当前鼠标的位置,此时将爱心的位置也设置为 (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);
});;
看看效果:
可以发现稍微有点僵硬,我们尝试给爱心一个边向后偏移边旋转的动画试试:
span::before {
animation: moveShape 1s linear infinite;
}
@keyframes moveShape {
0% {
transform: translate(0) rotate(0deg);
}
100% {
transform: translate(300px) rotate(360deg);
}
}
效果好很多啦,让我们继续添砖加瓦。
随机大小
如果我们能将每个爱心都设置成不同大小就好了,随机的大小像冒泡泡一样,显得更可爱。
我们可以通过一个随机数,来改变爱心容器 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,才更明显。
我们来看看此时的效果:
不错,味道好极了,啊不,是效果好极了,如果能加点旋转就好了。
让爱心转起来
同样的,我们可以用刚刚的思路,通过 rotate
属性动态的改变每个爱心的角度。
document.addEventListener('mousemove', function(e) {
//...
let transformValue = Math.random() * 360;
heart.style.transform = `rotate(${transformValue}deg)`;
body.appendChild(heart);
})
这里的系数我们要乘 360,表示有 360° 的角度可以随机到。此时我们再看看效果:
让爱心散开
为了让爱心能更浪漫点,我们需要将这些爱心在以鼠标坐标为中心,向四周散开。
相信大家都知道套路,实际上就是改变每个爱心的偏移,那么就要用到动画了。
span::before {
animation: moveShape 1s linear infinite;
}
@keyframes moveShape {
0% {
transform: translate(0) rotate(0deg);
}
100% {
transform: translate(300px) rotate(360deg);
}
}
我们设置在动画开始到动画结束的过程中,偏移量从 0 至 300px,同时旋转 360°。
让我们看看效果:
可以,已经很棒了。但是还不够,我们仔细看动图,可以发现爱心消失的很突然,所以我们接下来要淡化一下这么生硬的消失效果。
消失动画
为了让爱心消失的不那么突然,我们可以使用 opacity
搭配动画,从 1 到 0 的让爱心慢慢消失。
span {
animation: fadeInOut 1s linear infinite;
}
@keyframes fadeInOut {
0%,100% {
opacity: 0;
}
20%, 80% {
opacity: 1;
}
}
看看我们的最终效果:
Github 源码地址
juejin-demo/heart-demo at main · catwatermelon/juejin-demo (github.com)