0
点赞
收藏
分享

微信扫一扫

canvas实现下雨或掉落任何东西

犹大之窗 2024-01-30 阅读 16

<template>
  <canvas id="canvas"> </canvas>
  </template>

  <script>
  export default {
    props: {
      icon:{
        type:String,
        required:true
      },
      total: {
        type: Number,
        default: 30,
      },
      // 最小速度
      minSpeed: {
        type: Number,
        default: 14,
      },
      // 最大速度
      maxSpeed: {
        type: Number,
        default: 15,
      },
      // 雨滴最小宽度
      minWidth: {
        type: Number,
        default: 1,
      },
      // 雨滴最大宽度
      maxWidth: {
        type: Number,
        default: 5,
      },
      // 高度 指定高度将不再随机高度
      height: {
        type: Number,
      }
    },
    data() {
      return {
        canvas: null,
        ctx: null,
        image: null,
        rains: [],
        raf: null,
      };
    },
    methods: {
      // 获取指定范围的随机数
      random(min, max) {
        return Math.random() * (max - min) + min;
      },

      // 创建雨滴的函数
      createRain() {
        for (let i = 0; i < this.total; i++) {
          let width = this.random(this.minWidth, this.maxWidth);
          let rain = {
            x: this.random(0, this.canvas.width),
            y: this.random(0, this.canvas.height),
            speed: this.random(this.minSpeed, this.maxSpeed),
            opacity: 1,
            width: width,
            height: this.height ? this.height : width * this.random(10, 20),
          };
          this.rains.push(rain);
        }
      },
      // 更新雨滴的函数
      updateRain() {
        for (let i = 0; i < this.total; i++) {
          let rain = this.rains[i];
          rain.y += rain.speed * rain.width;
          rain.opacity -= 0.005;
          // 如果雨滴超出画布,重置位置
          if (rain.y > this.canvas.height) {
            rain.x = this.random(1, this.canvas.width);
            rain.y = 0;
            rain.opacity = 1;
          }
        }
      },
      // 绘制雨滴的函数
      drawRain() {
        for (let i = 0; i < this.total; i++) {
          let rain = this.rains[i];
          this.ctx.save();
          this.ctx.translate(rain.x, rain.y);
          this.ctx.drawImage(this.image, 0, 0, rain.width, rain.height); // 绘制图片到雨滴上
          this.image.style.opacity = rain.opacity;
          this.ctx.restore();
        }
      },
      resizeCanvas() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
      },
    },
    mounted() {
      let _this = this;
      this.canvas = document.getElementById("canvas");
      let parentEl = this.canvas.parentElement;
      this.ctx = this.canvas.getContext("2d");
      this.canvas.width = parentEl.getBoundingClientRect().width;
      this.canvas.height = parentEl.getBoundingClientRect().height;

      let image = new Image();
      image.src = this.icon;
      this.image = image;

      this.createRain();
      // 动画循环
      function animate() {
        _this.ctx.clearRect(0, 0, _this.canvas.width, _this.canvas.height);
        _this.updateRain();
        _this.drawRain();
        _this.raf = requestAnimationFrame(animate);
      }
      // 开始动画
      animate();

      window.addEventListener("resize", this.resizeCanvas);
    },
    beforeDestroy() {
      cancelAnimationFrame(this.raf);
      window.removeEventListener("resize", this.resizeCanvas);
  },
};
</script>

<style lang="less" scoped>
</style>

举报

相关推荐

0 条评论