名词概念
画布宽高 VS. 样式宽高
API分类:设置状态 VS. 绘制指令
指令式绘图系统(Canvas) VS. 声明式绘图系统(HTML/SVG)
代码片段
清空画布
线条
1 2 3 4 5 6 7 8 9 10 11 12 13
| function drawDashLine( ctx: CanvasRenderingContext2D, start: { x: number; y: number }, end: { x: number; y: number } ) { ctx.moveTo(start.x, start.y); ctx.lineTo(end.x, end.y); ctx.lineWidth = 1; ctx.strokeStyle = '#FFFFFF'; ctx.setLineDash([4, 4]); ctx.lineDashOffset = -10; ctx.stroke(); }
|
文本
关键函数是:fillText()
1 2 3 4 5 6 7 8 9 10 11 12 13
| function drawText( ctx: CanvasRenderingContext2D, point: { x: number; y: number }, content: string, textAlign: CanvasTextAlign = 'start', textBaseline: CanvasTextBaseline = 'alphabetic' ) { ctx.font = '10px serif'; ctx.fillStyle = '#FFFFFF'; ctx.textAlign = textAlign; ctx.textBaseline = textBaseline; ctx.fillText(content, point.x, point.y); }
|
文本的定位基准点
注意:绘制文本时,其定位基准点是文字的左下角!
因此fillText(text, x, y)函数的y一般要设置为文字的高度值。
设置文本的字体大小
canvas可以通过context.font设置字体的单位,且支持绝对尺寸px和相对尺寸rem等:
1 2 3 4
| context.font = 'bold 12px serif';
context.font = 'bold 2rem serif';
|
网格辅助线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function drawGrid(canvasElement: HTMLCanvasElement) { const ctx = canvasElement.getContext('2d'); const { width, height } = canvasElement; console.error('canvasElement.width', canvasElement.width);
const interval = 100;
for (let i = interval; i < width; i += interval) { const start = { x: i, y: 0 }; const end = { x: i, y: height }; drawDashLine(ctx, start, end); drawText(ctx, start, ` ${i}`, 'start', 'top'); }
for (let i = interval; i < height; i += interval) { const start = { x: 0, y: i }; const end = { x: width, y: i }; drawDashLine(ctx, start, end); drawText(ctx, start, `${i}`); } }
|
常见问题
0.5像素问题
在我们K线图中遇到过,中间那根线老是画偏。
实际上不是中间的线偏了,而是矩形柱子在宽度为奇数时,多画了一个像素的宽度。
canvas总结:线段宽度与像素边界 - rockyli - 博客园
canvas中strokeRect的渲染问题:strokeRect把一像素的边框渲染成两像素
参考资料
常用API:
https://blog.csdn.net/zeping891103/article/details/72730968
https://www.runoob.com/w3cnote/html5-canvas-intro.html
浅谈 Canvas 渲染引擎:
https://zhuanlan.zhihu.com/p/608415829