鼠标点击出现炫彩小球效果Canvas

<template>
  <div @click="createBall($event)" class="box">
    <canvas ref="canvas"></canvas>
  </div>
</template>

<script>
export default {
  mounted() {
    // 获取画布
    const canvas = this.$refs.canvas;
    // 获取画布的 2D 上下文对象。
    const ctx = canvas.getContext("2d");
    // 存储生成的小球对象的数组。
    const ballList = [];
    const colorList = ["red", "green", "yellow", "blue", "black", "#ccc"];
   // 创建小球对象的构造函数
   // 设置了小球的初始位置、颜色、速度、透明度和半径。其中,透明度和半径都是随机生成的。
    function Ball(x, y) {
      this.x = x;
      this.y = y;
      this.color = colorList[Math.floor(this.mathRandom(0, 6))];
      this.xv = this.mathRandom(-3, 3);
      this.yv = this.mathRandom(-3, 3);
      this.Alpha1 = 1;
      this.Alpha2 = 0.95;
      this.radius = this.mathRandom(5, 10); // 设置最小半径和最大半径
    }
   // 更新小球的绘制样式
    Ball.prototype.update = function () {
      ctx.save();
      ctx.beginPath();
      ctx.fillStyle = this.color;
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
      ctx.fill();
      ctx.closePath();
    };
   // 更新小球的位置和透明度,并处理小球碰壁的情况。
    Ball.prototype.move = function () {
      this.Alpha1 *= this.Alpha2;
      ctx.globalAlpha = this.Alpha1;
      this.x += this.xv;
      this.y += this.yv;

      if (this.x < 0 || this.x > canvas.width) {
        this.xv *= -1;
      }
      if (this.y < 0 || this.y > canvas.height) {
        this.yv *= -1;
      }
    };
   // 生成一个指定范围内的随机数
    Ball.prototype.mathRandom = function (min, max) {
      return (max - min) * Math.random() + min;
    };
   // 执行动画的函数,清空画布、更新小球位置和绘制小球。
    function animate() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ballList.forEach((item) => {
        item.update();
        item.move();
      });
      requestAnimationFrame(animate);
    }
  // 设置画布的宽度和高度为窗口的宽度和高度,并调用 animate() 函数开始动画。
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    animate();
   // 在点击事件中生成小球。获取鼠标点击的坐标,创建并添加多个小球对象到 ballList 数组中。
    this.createBall = function (event) {
      const x = event.clientX;
      const y = event.clientY;

      for (let i = 0; i < 10; i++) {
        ballList.push(new Ball(x, y));
      }
    };
   // 监听窗口大小变化事件,调整画布的宽度和高度。
    window.addEventListener("resize", () => {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    });
  },
};
</script>

<style>
.box
{
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}

canvas {
  position: absolute;
}
</style>

 把小球换成正方形

  function Ball(x, y) {
      this.x = x
      this.y = y
      this.color = colorList[Math.floor(Math.random() * 6)]
      this.xv = Math.random() * 6 - 3
      this.yv = Math.random() * 6 - 3
      this.Alpha1 = 1
      this.Alpha2 = 0.95
      this.sideLength = Math.random() * 6 + 5 // 正方形的边长
    }
    Ball.prototype.update = function () {
      ctx.save()
      ctx.fillStyle = this.color
      ctx.fillRect(this.x, this.y, this.sideLength, this.sideLength)
    }

 换成心形

   function Ball(x, y) {
      this.x = x
      this.y = y
      this.color = colorList[Math.floor(Math.random() * 6)] // 随机选择小球的颜色
      this.xv = Math.random() * 6 - 3 // 随机生成小球在 x 轴方向的速度
      this.yv = Math.random() * 6 - 3 // 随机生成小球在 y 轴方向的速度
      this.Alpha1 = 1
      this.Alpha2 = 0.95
      this.sideLength = Math.random() * 6 + 5 // 心形的尺寸大小
    }

    Ball.prototype.update = function () {
      ctx.save()
      ctx.fillStyle = this.color // 设置填充颜色为小球的颜色
      // 根据小球的形状选择不同的绘制方式
      // 这里使用了现成的心形路径来绘制心形
      ctx.beginPath()
      ctx.moveTo(this.x, this.y + this.sideLength / 2)
       //bezierCurveTo 方法绘制两条贝塞尔曲线,用于定义心形的外轮廓。
      ctx.bezierCurveTo(
        this.x + this.sideLength / 4,
        this.y - this.sideLength / 2,
        this.x - this.sideLength,
        this.y - this.sideLength / 4,
        this.x,
        this.y + this.sideLength
      )
      ctx.bezierCurveTo(
        this.x + this.sideLength,
        this.y - this.sideLength / 4,
        this.x - this.sideLength / 4,
        this.y - this.sideLength / 2,
        this.x,
        this.y + this.sideLength / 2
      )
      ctx.closePath() // 封闭路径
      ctx.fill() // 填充心形

      ctx.restore() // 恢复画布状态
    }

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值