canvas的注意要点

347 阅读3分钟

canvas的大小的设置

  • canvas大小指的是画布大小,应通过canvas的width和height属性进行设置。
注意事项:

勿通过css来设置canvas大小。

通过css设置的是canvas元素dom的大小,并非画布大小(默认宽300,高150)。在绘制的时候画布内容是自适应于dom元素大小,就会导致canvas内容变形。

  • 采用默认画布大小绘制:fillRect(20, 20, 50, 50)

image.png

  • 采用默认画布大小,并通过css设置canvas元素大小。
canvas {
  width: 600px;
  height: 100px;
}

image.png

设置方式:

通过获取canvas父级容器大小来设置其内部的canvas大小。

示例: image.png

CanvasGradient - canvas梯度

以线性渐变,圆形渐变设置渐变色。并赋值给fillStyle,strokeStyle使用。

以线性渐变示例说明
// 声明起点10,10;终点100,100的线性渐变梯度
    const canvasGradient = canvasContext.createLinearGradient(10, 10, 100, 100)

    canvasGradient?.addColorStop(0, 'red')
    canvasGradient?.addColorStop(1, 'green')
    canvasContext.fillStyle = canvasGradient
    canvasContext.fillRect(0, 0, 220, 220)

    canvasContext.strokeStyle = 'red'
    canvasContext.strokeRect(10, 10, 100, 100)

效果图:
image.png

补充说明:
渐变是沿着起点至终点这个方向进行渐变的,渐变色是从特定点开始渐变,并在特定节点完成颜色的逐渐转变

起点-终点这条线上,垂直于该线的垂直线上的各个像素点颜色都是一样的。

canvas线的绘制

image.png

图-line

前提点:

屏幕上一个像素点相当于一个微小的LED灯,它只能显示一个颜色。所以线应该用完整的像素点来绘制。

上图-line的中间示例中,线框位于像素点中间,则canvas会采用填充颜色的一半效果绘制完整的像素点,就会造成模糊的效果。

image.png

如图所示,左边的竖线明显模糊,右边的竖线明显清晰。

备注:

当绘制宽度为1的线的时候,线的坐标应位于像素点中间,这样绘制的线就是清晰的。

蚂蚁线的绘制

image.png

(这里丢失了虚线滚动向前的动画效果)

    // 蚂蚁线;offset是蚂蚁移动的速度
    let offset = 0
    setInterval(() => {
      canvasContext.clearRect(0, 0, canvasRef.current!.width, canvasRef.current!.height)
      offset += 1
      canvasContext.setLineDash([12, 12])
      canvasContext.lineDashOffset = offset
      canvasContext.strokeRect(10, 10, 300, 300)
    }, 1)

循环执行的第一行代码clearReact(),这个函数作用清除了画布的内容。

canvas动画说明

我们知道在视频里有视频帧,就是一张张图片。视频的动态播放就是一系列图片的快速切换让人看起是动的效果。早期的动画片就是经典例子。
canvas的动画本质上也是一个个画布的绘制,显示,清除,再绘制,再显示;如此循环的过程。

文本的绘制

  • 绘制方法 fillText 和 strokeText。参数都是三个;text,x,y,maxWidth。
    // 文本的绘制
    canvasContext.font = 'bold 48px serif'
    canvasContext.fillText('Hello World', 100, 100)
    canvasContext.strokeText('Hello World', 100, 200)
    canvasContext.strokeText('Hello World', 100, 300, 100)

效果如图

image.png

说明:
maxWidth的设置会在特定范围内绘制文本,如果文本宽度超过maxWidth则会出现文本宽度压缩情况。

绘制多行文本
// 绘制多行文本
function drawMultipleText(text: string, x: number, y: number, cellWidth: number, canvasContext: CanvasRenderingContext2D) {
  const lineHeight = 43
  canvasContext.font = 'bold 40px serif'

  let drawY = y
  let startIndex = 0
  let endIndex = 0
  for (let index = 1; index < text.length; index++) {
    const str = text.slice(startIndex, index)
    // 当前文本超过一行宽度了,需要将其换行显示
    if (canvasContext.measureText(str).width > cellWidth) {
      canvasContext.fillText(str, x, drawY)
      startIndex = index - 1
      drawY += lineHeight
    }
    endIndex = index
  }
  canvasContext.fillText(text.slice(startIndex, endIndex), x, drawY)
}
drawMultipleText('撒旦发射点发啊手动阀撒旦发射点f', 100, 100, 300, canvasContext)

效果如图:

image.png

说明点:
每行的高度需要事先定义,可以通过字体大小大概运算得出。

文本的textalign

文本对齐选项。可选的值包括:startendleftright or center. 默认值是 start

image.png

文本的textBaseLine

基线对齐选项。可选的值包括:tophangingmiddlealphabeticideographicbottom。默认值是 alphabetic

image.png