canvas代码雨

思路

  • 渡一袁老师学的
  • canvas中文字是使用filltext(text,x,y)进行绘制的,我们需要搞定这些参数就可以绘制出来。
  • 先设定一个fontSize为文字大小,列宽columnWidth =fontSize,可以用来计算绘制多少列以及x坐标,计算列数可以用画布宽度/列宽,假设fontSize=20例如:

列数 = 画布宽度 / 列宽
columnCount = Math.floor(width/columnWidth)

索引 0 1 2 3 4 5
列数 第一列 第二列 第三列 第四列 第五列 第六列
x坐标 0 20 40 60 80 100

可以看出每一列的x=i*fontSize

  • 如何计算y坐标,可以用一个数组来记录列下一个文字,例如:
    [0,0,0]是指当前所有列绘制了0个文字。
    [3,4,7]是指第1列绘制了3个文字,第2列绘制了4个文字,第3列绘制了7个文字
    怎么算呢?看下面这个表
记录的第n个文字 y坐标
0 l 20
1 ; 40
2 k 60
3 k 80
4 f 100
5 s 120
6 m 140
7 n 160

现在可以看出y坐标=(下一个文字+1)*fontSize因为canvasy不是看原点是看基线,可以理解为y在字母的下面。

  • 每次绘制之前要加上一个蒙层,以实现慢慢变淡的效果

效果

canvas代码雨_第1张图片

代码

<template>
  <canvas id="bg">canvas>
template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
const timer = ref<number | undefined>(undefined)
function init() {
  // 获取canvas元素
  const cvs: HTMLCanvasElement = document.getElementById('bg') as HTMLCanvasElement
  // 获取窗口尺寸
  const width = window.innerWidth * devicePixelRatio,
    height = window.innerHeight * devicePixelRatio
  // 设置canvas尺寸
  cvs.width = width
  cvs.height = height
  // 获取绘制上下文
  const ctx = cvs.getContext('2d')
  // 字体大小
  const fontSize = 20 * devicePixelRatio
  // 列宽
  const columnWidth = fontSize
  // 列数
  const columnCount = Math.floor(width / columnWidth)
  // 每一列下一个文字是第几个文字
  const nextChar = new Array(columnCount).fill(0)

  function draw() {
    // 蒙层
    ctx!.fillStyle = 'rgba(240,240,240,0.1)'
    ctx!.fillRect(0, 0, width, height)
    for (let i = 0; i < columnCount; i++) {
      // 画一个字符
      // 颜色,字体,字符,位置
      ctx!.fillStyle = getRandomColor()
      const char = getRandomChar()
      ctx!.font = `${fontSize}px "Roboto Mono"`
      const x = i * fontSize
      const s = nextChar[i]
      const y = (s + 1) * fontSize
      ctx!.fillText(char, x, y)
      if (y > height && Math.random() > 0.99) {
        nextChar[i] = 0
      } else {
        nextChar[i]++
      }
    }
  }
  draw()
  timer.value = setInterval(draw, 100)
}
// 随机颜色
function getRandomColor() {
  return '#' + Math.random().toString(16).slice(2, 8)
}
// 随机文字
function getRandomChar() {
  const str = 'dfdfadfgfadgafdg15561561'
  return str[Math.floor(Math.random() * str.length)]
}
onMounted(init)
onUnmounted(() => {
  clearInterval(timer.value)
})
script>

你可能感兴趣的:(canvas,js)