Vue鼠标移动跟随特效(开箱即用)

5 篇文章 0 订阅
5 篇文章 0 订阅

效果图

在这里插入图片描述

直接在需要的页面引用该组件就行

<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都可以

Vue中实现鼠标移动特效有很多种方式,以下是其中一种常见的实现方法: 首先,在Vue组件中,你可以使用`@mousemove`事件监听鼠标移动事件。在事件处理函数中,你可以获取鼠标的坐标,并计算出相对于元素的位置。 例如,假设你要实现一个鼠标移动时产生气泡效果的特效。你可以在组件的`data`中定义一个数组,用于存储气泡的位置信息。然后,在`mounted`钩子函数中添加事件监听器。 ```vue <template> <div class="container" @mousemove="handleMouseMove"> <div class="bubble" v-for="(bubble, index) in bubbles" :key="index" :style="{ top: bubble.y + 'px', left: bubble.x + 'px' }"></div> </div> </template> <script> export default { data() { return { bubbles: [] // 存储气泡位置信息的数组 }; }, mounted() { window.addEventListener('resize', this.handleResize); }, methods: { handleMouseMove(event) { const x = event.clientX; const y = event.clientY; this.bubbles.push({ x, y }); }, handleResize() { // 处理窗口大小变化的逻辑 } }, beforeDestroy() { window.removeEventListener('resize', this.handleResize); } }; </script> <style> .container { position: relative; width: 100%; height: 100vh; } .bubble { position: absolute; width: 20px; height: 20px; border-radius: 50%; background-color: #ff0000; } </style> ``` 在上述代码中,我们监听了鼠标移动事件`@mousemove`,并在事件处理函数`handleMouseMove`中获取鼠标的坐标`event.clientX`和`event.clientY`。然后将坐标信息存储在`bubbles`数组中,并通过`v-for`指令动态渲染气泡。 你可以根据自己的需求进行样式和动画的调整,例如改变气泡的大小、颜色以及添加过渡动画等。以上只是一个简单的示例,希望对你有所帮助。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值