canvas的大小的设置
- canvas大小指的是画布大小,应通过canvas的width和height属性进行设置。
注意事项:
勿通过css来设置canvas大小。
通过css设置的是canvas元素dom的大小,并非画布大小(默认宽300,高150)。在绘制的时候画布内容是自适应于dom元素大小,就会导致canvas内容变形。
- 采用默认画布大小绘制:fillRect(20, 20, 50, 50)
- 采用默认画布大小,并通过css设置canvas元素大小。
canvas {
width: 600px;
height: 100px;
}
设置方式:
通过获取canvas父级容器大小来设置其内部的canvas大小。
示例:
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)
效果图:
补充说明:
渐变是沿着起点至终点这个方向进行渐变的,渐变色是从特定点开始渐变,并在特定节点完成颜色的逐渐转变
起点-终点这条线上,垂直于该线的垂直线上的各个像素点颜色都是一样的。
canvas线的绘制
图-line
前提点:
屏幕上一个像素点相当于一个微小的LED灯,它只能显示一个颜色。所以线应该用完整的像素点来绘制。
上图-line的中间示例中,线框位于像素点中间,则canvas会采用填充颜色的一半效果绘制完整的像素点,就会造成模糊的效果。
如图所示,左边的竖线明显模糊,右边的竖线明显清晰。
备注:
当绘制宽度为1的线的时候,线的坐标应位于像素点中间,这样绘制的线就是清晰的。
蚂蚁线的绘制
(这里丢失了虚线滚动向前的动画效果)
// 蚂蚁线;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)
效果如图
说明:
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)
效果如图:
说明点:
每行的高度需要事先定义,可以通过字体大小大概运算得出。
文本的textalign
文本对齐选项。可选的值包括:start, end, left, right or center. 默认值是 start
文本的textBaseLine
基线对齐选项。可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic