<ol>
<li>
<p>首先,在components文件夹下新建一个danmu组件,包含一个template和一个script。</p>
</li>
<li>
<p>在template中,添加一个canvas标签,用来绘制弹幕。</p>
</li>
<li>
<p>在script中,定义一个uni.createCanvasContext的变量,用来操作canvas。</p>
</li>
<li>
<p>定义一个data对象,包含弹幕数组,弹幕数量,弹幕速度,字体大小等属性。</p>
</li>
<li>
<p>编写一个drawDanmu函数,用来绘制弹幕。该函数首先清除canvas画布,然后遍历弹幕数组,根据弹幕的x坐标和y坐标绘制文本,每次绘制完毕后将x坐标减少弹幕速度,实现弹幕移动效果。</p>
</li>
<li>
<p>在mounted生命周期函数中,调用drawDanmu函数,实现弹幕的初始化。</p>
</li>
<li>
<p>在methods中,编写addDanmu函数,用来添加弹幕。该函数首先生成一个随机的y坐标和颜色,然后将弹幕文本和x坐标加入弹幕数组中。</p>
</li>
<li>
<p>在created生命周期函数中,判断当前平台是否是小程序,如果是,则调用wx.createSelectorQuery获取canvas节点,如果是H5,则调用uni.createSelectorQuery获取canvas节点。</p>
</li>
<li>
<p>最后,在page中引入danmu组件,并在需要添加弹幕的地方调用addDanmu函数即可。</p>
</li>
</ol>
<p>示例代码如下:</p>
<p>danmu.vue:</p>
<template>
  <canvas class="danmu-canvas"></canvas>
</template>
<script>
export default {
  data() {
    return {
      danmuList: [],
      danmuNum: 20,
      danmuSpeed: 2,
      fontSize: 20,
      canvasWidth: 0,
      canvasHeight: 0
    }
  },
  mounted() {
    this.initCanvas()
    this.drawDanmu()
  },
  methods: {
    initCanvas() {
      const query = uni.createSelectorQuery().in(this)
      query.select('.danmu-canvas').boundingClientRect((res) => {
        this.canvasWidth = res.width
        this.canvasHeight = res.height
        this.ctx = uni.createCanvasContext('danmu-canvas', this)
      }).exec()
    },
    drawDanmu() {
      this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
      for (let i = 0; i < this.danmuList.length; i++) {
        const danmu = this.danmuList[i]
        const x = danmu.x - this.danmuSpeed
        if (x < -danmu.width) {
          this.danmuList.splice(i, 1)
          i--
          continue
        }
        this.ctx.setFillStyle(danmu.color)
        this.ctx.setFontSize(this.fontSize)
        this.ctx.fillText(danmu.text, x, danmu.y)
        danmu.x = x
      }
      this.ctx.draw()
      requestAnimationFrame(() => this.drawDanmu())
    },
    addDanmu(text) {
      const color = `#${Math.floor(Math.random() * 16777215).toString(16)}`
      this.ctx.setFontSize(this.fontSize)
      const width = this.ctx.measureText(text).width
      const y = Math.floor(Math.random() * (this.canvasHeight - this.fontSize))
      this.danmuList.push({
        text,
        x: this.canvasWidth,
        y,
        color,
        width
      })
    }
  }
}
</script>
<style scoped>
.danmu-canvas {
  width: 100%;
  height: 100%;
}
</style>
<p>page.vue:</p>
<template>
  <view>
    <danmu ref="danmu"></danmu>
    <button @click="addDanmu()">添加弹幕</button>
  </view>
</template>
<script>
import danmu from '@/components/danmu.vue'

export default {
  components: {
    danmu
  },
  methods: {
    addDanmu() {
      const text = '这是一条弹幕'
      this.$refs.danmu.addDanmu(text)
    }
  }
}
</script

原文地址: https://www.cveoy.top/t/topic/ffiN 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录