Vue鼠标移动跟随特效(开箱即用)
效果图直接在需要的页面引用该组件就行<template><div id="panel"></div></template><script>export default {methods: {mouseMove(e) {/*这里获取元素节点*/let oPanel = document.getElementById("panel");
·
效果图
直接在需要的页面引用该组件就行
<template>
<div id="panel">
</div>
</template>
<script>
export default {
methods: {
mouseMove(e) {
/*这里获取元素节点*/
let oPanel = document.getElementById("panel");
let oSpan = document.createElement(`span`);
/*浏览器兼容*/
e = e || window.Event;
// let x = e.clientX;
// let y = e.clientY;
/*获取相关参数*/
oSpan.style.left = e.clientX + `px`;
oSpan.style.top = e.clientY - 50 + `px`;
/*设定随机数存储在size中*/
let size = Math.random() * 20;
/*给节点赋值参数数值*/
oSpan.style.width = 5 + size + `px`;
oSpan.style.height = 5 + size + `px`;
/*在body中添加span标签*/
oPanel.appendChild(oSpan);
/*设置定时器 间隔时间为2000毫秒*/
setTimeout(() => {
/*清除ospan节点*/
oSpan.remove();
}, 1000);
},
},
mounted() {
/*这里是给整个页面添加了一个鼠标移动的监听事件 e为事件对象*/
document.addEventListener(`mousemove`, this.mouseMove);
},
beforeDestroy() {
document.removeEventListener(`mousemove`, this.mouseMove);
},
};
</script>
<style lang='less'>
#panel {
height: 100vh;
width: 100%;
// display: flex;
// align-items: center;
// justify-content: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
span {
width: 10px;
height: 10px;
background: #55b9f3;
border-radius: 50%;
position: absolute;
box-shadow: 5px 5px 15px #489dcf, -5px -5px 15px #62d5ff;
animation: blow 4s linear infinite;
-webkit-animation: blow 4s linear infinite;
}
}
/*这里是定义里一个动画效果*/
@keyframes blow {
0% {
transform: translate(-50%, -50%);
/*这里是定义初始透明度为1*/
opacity: 1;
/*
这里是初始滤镜效果
给图像应用色相旋转。"angle"一值设定图像会被调整的色环角度值。
值为0deg,则图像无变化。若值未设置,默认值是0deg。
该值虽然没有最大值,超过360deg的值相当于又绕一圈。
*/
filter: hue-rotate(0deg);
/*这里是浏览器兼容*/
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
}
100% {
/*
2D转化
这里是从自身向上平移
*/
transform: translate(-50%, -1000%);
/*这里是定义结束时透明度为0*/
opacity: 0;
/*
这里是结束滤镜效果
给图像应用色相旋转。"angle"一值设定图像会被调整的色环角度值。
值为0deg,则图像无变化。若值未设置,默认值是0deg。
该值虽然没有最大值,超过360deg的值相当于又绕一圈。
*/
filter: hue-rotate(720deg);
/*这里是浏览器兼容*/
-webkit-transform: translate(-50%, -1000%);
-moz-transform: translate(-50%, -1000%);
-ms-transform: translate(-50%, -1000%);
-o-transform: translate(-50%, -1000%);
-webkit-filter: hue-rotate(720deg);
}
}
</style>
注意:1.
<style lang='less'>
全局样式才能作用于创建的元素,2.z-index
层级问题,鼠标不能点击 3.filter: hue-rotate(720deg)
角度越大,颜色越多
Vue3的Hook版本,只需要一行引入代码即可实现
实现代码
import { onMounted, onUnmounted, ref } from "vue";
export const useMouseAnimate = () => {
const canvasRef = ref<HTMLCanvasElement>();
const ctx = ref<CanvasRenderingContext2D | null>(null);
let balls: Array<{
x: number;
y: number;
opacity: number;
raduis: number;
randomColor1: number;
randomColor2: number;
randomColor3: number;
}> = [];
/**
* @description 初始化canvas
*/
const initCanvas = () => {
// 不想要全局的canvas可以自己手动修改
const canvasEl = document.createElement("canvas");
canvasRef.value = canvasEl;
document.body.appendChild(canvasRef.value!);
canvasEl.style.position = "fixed";
canvasEl.style.top = "0";
canvasEl.style.left = "0";
canvasEl.style.zIndex = "9999";
canvasEl.style.pointerEvents = "none";
canvasEl.width = window.innerWidth;
canvasEl.height = window.innerHeight;
ctx.value = canvasEl.getContext("2d");
if (!ctx) return;
window.addEventListener("mousemove", initBall, true);
requestAnimationFrame(animte);
};
let count = 0;
const initBall = (event: MouseEvent) => {
count++;
// 避免创建太多小球
if (count >= 3) {
const x = event.clientX;
const y = event.clientY;
const random = (Math.random() + 1) * 6; //随机球的半径
const randomColor1 = Math.floor(Math.random() * 255); //随机球的颜色
const randomColor2 = Math.floor(Math.random() * 255); //随机球的颜色
const randomColor3 = Math.floor(Math.random() * 255); //随机球的颜色
balls.push({
x,
y,
opacity: 1,
raduis: random,
randomColor1,
randomColor2,
randomColor3,
});
count = 0;
}
};
const animte = () => {
// 每一帧 将所有小球重新画出来
ctx.value!.clearRect(0, 0, canvasRef.value!.width, canvasRef.value!.height);
balls.forEach((ball) => {
// 小球透明度递减
ball.opacity -= 0.01;
// y轴递减
ball.y += 0.5;
ctx.value!.beginPath();
ctx.value!.arc(ball.x, ball.y, ball.raduis, 0, Math.PI * 2);
ctx.value!.fillStyle = `rgba(${ball.randomColor1},${ball.randomColor2},${ball.randomColor3},${ball.opacity})`;
ctx.value!.fill();
// 透明度为0删除
if (ball.opacity <= 0) {
balls.shift();
}
});
requestAnimationFrame(animte);
};
onMounted(() => {
initCanvas();
});
onUnmounted(() => {
window.removeEventListener("mousemove", initBall, true);
});
};
引入
<template></template>
<script lang="ts">
export default { name: "MouseAnimate" };
</script>
<script lang="ts" setup>
import { useMouseAnimate } from "./mouse";
useMouseAnimate();
</script>
<style lang="scss" scoped></style>
可以将hook里面的球大小、颜色等拿出来形成配置,或者不想全局的canvas,可以把canvasRef
导出来给自己想要的canvas都可以
更多推荐
已为社区贡献8条内容
所有评论(0)