在vuepress博客添加樱花特效(vue樱花组件源码)

写在前面

写过博客的同学都知道,飘落樱花是一个比较常见的博客特效。
平时都是用插件来实现的,有想过去了解它到底是怎么实现的吗?

  • 它是用canvas实现的
  • 就针对vuepress,我们需要写一个vue组件来实现效果

本篇文章会贴出樱花的vue组件源码vuepress使用樱花的步骤

可以先来我博客看看效果,哈哈 博客效果演示

樱花的源码

<template>
  <div class="Sakura">
    <canvas id="canvas_sakura" ref="canvas_sakura" :style="{ zIndex: zIndex }"></canvas>
  </div>
</template>

<script>
class Sakura {
  constructor(x, y, s, r, fn, that, img) {
    this.x = x;
    this.y = y;
    this.s = s;
    this.r = r;
    this.fn = fn;
    this.that = that;
    this.img = img;
  }
  draw (cxt) {
    cxt.save();
    // eslint-disable-next-line no-unused-vars
    var xc = 40 * this.s / 4;
    cxt.translate(this.x, this.y);
    cxt.rotate(this.r);
    cxt.drawImage(this.img, 0, 0, 40 * this.s, 40 * this.s)
    cxt.restore();
  }
  update () {
    this.x = this.fn.x(this.x, this.y);
    this.y = this.fn.y(this.y, this.y);
    this.r = this.fn.r(this.r);
    if (this.x > window.innerWidth ||
      this.x < 0 ||
      this.y > window.innerHeight ||
      this.y < 0
    ) {
      this.r = this.that.getRandom('fnr');
      if (Math.random() > 0.4) {
        this.x = this.that.getRandom('x');
        this.y = 0;
        this.s = this.that.getRandom('s');
        this.r = this.that.getRandom('r');
      } else {
        this.x = window.innerWidth;
        this.y = this.that.getRandom('y');
        this.s = this.that.getRandom('s');
        this.r = this.that.getRandom('r');
      }
    }
  }
}
class SakuraList {
  constructor() {
    this.list = []
  }
  push (sakura) {
    this.list.push(sakura);
  }
  update () {
    for (var i = 0, len = this.list.length; i < len; i++) {
      this.list[i].update();
    }
  }
  draw (cxt) {
    for (var i = 0, len = this.list.length; i < len; i++) {
      this.list[i].draw(cxt);
    }
  }
  get (i) {
    return this.list[i];
  }
  size () {
    return this.list.length;
  }
}
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'Sakura',
  data () {
    return {
      staticx: false,
      stop: null,
      num: 50,
      show: true,
      zIndex: 0,
    }
  },
  mounted () {
    this.$nextTick(() => {
      if (this.show) {
        this.startSakura()
      }
    })
  },
  methods: {
    getRandom (option) {
      var ret, random;
      switch (option) {
        case 'x':
          ret = Math.random() * window.innerWidth;
          break;
        case 'y':
          ret = Math.random() * window.innerHeight;
          break;
        case 's':
          ret = Math.random();
          break;
        case 'r':
          ret = Math.random() * 6;
          break;
        case 'fnx':
          random = -0.5 + Math.random() * 1;
          // eslint-disable-next-line no-unused-vars
          ret = function (x, y) {
            return x + 0.15 * random - 1.7 * 0.3;
          };
          break;
        case 'fny':
          random = 1.5 + Math.random() * 0.7
          ret = function (x, y) {
            return y + 0.3 * random;
          };
          break;
        case 'fnr':
          random = Math.random() * 0.03;
          ret = function (r) {
            return r + random;
          };
          break;
      }
      return ret;
    },
    startSakura () {
      let that = this
      // eslint-disable-next-line no-global-assign
      requestAnimationFrame = window.requestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame;
      var canvas = document.getElementById('canvas_sakura');
      this.staticx = true;
      this.$refs.canvas_sakura.width = window.innerWidth;
      this.$refs.canvas_sakura.height = window.innerHeight;
      var cxt = this.$refs.canvas_sakura.getContext('2d');
      var sakuraList = new SakuraList();
      const img = new Image();

      img.src = '/Hundred-refining-into-Immortals/sakura.png'; //樱花效果图相对路径

      for (var i = 0; i < that.num; i++) {
        let sakura, randomX, randomY, randomS, randomR, randomFnx, randomFny, randomFnR;
        randomX = this.getRandom('x');
        randomY = this.getRandom('y');
        randomR = this.getRandom('r');
        randomS = this.getRandom('s');
        randomFnx = this.getRandom('fnx');
        randomFny = this.getRandom('fny');
        randomFnR = this.getRandom('fnr');
        sakura = new Sakura(randomX, randomY, randomS, randomR, {
          x: randomFnx,
          y: randomFny,
          r: randomFnR
        }, this, img);
        sakura.draw(cxt);
        sakuraList.push(sakura);
      }
      this.stop = requestAnimationFrame(function fn () {
        cxt.clearRect(0, 0, canvas.width, canvas.height);
        sakuraList.update();
        sakuraList.draw(cxt);
        that.stop = requestAnimationFrame(fn);
      })
    },
    stopp () {
      if (this.staticx) {
        var child = document.getElementById("canvas_sakura");
        child.parentNode.removeChild(child);
        window.cancelAnimationFrame(this.stop);
        this.staticx = false;
      } else {
        this.startSakura();
      }
    }
  }
}
</script>

<style scoped>
#canvas_sakura {
  pointer-events: none;
  position: fixed;
  top: 0;
  left: 0;
}
</style>

在vuepress使用

  • .vuepress/components文件夹下面新建一个Sakura.vue文件,内容就是上面的源码
    • 在vuepress里面会自动吧上面文件夹里面的vue文件挂载到全局
    • 这样全局就可以使用
  • 在你想出现樱花的页面调用组件就可以了,这样<Sakura></Sakura>
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值