canvas—画元素
1、不同于 SVG,<canvas> 只支持两种形式的图形绘制:矩形和路径(由一系列点连成的线段)。所有其他类型的图形都是通过一条或者多条路径组合而成的。不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能。
2、canvas里面位置都是基于坐标系的,这点和DOM完全不一样。 DOM的布局是基于文档流的。下面的标签会在上面排好的基础上自动接着排列, 有点像排队。 而 canvas 都是基于坐标系的,每个部件在画时都是设定坐标确定位置的。
参考:https://www.runoob.com/w3cnote/html5-canvas-intro.html 或 https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes
一、画矩形:
// 默认画笔的宽度是1px【这是个人理解的】 /* 矩形 * */ // 矩形——实心 ctx.fillRect(10,10,100, 200) // 矩形——边框 ctx.strokeRect(120,10,100, 200) // 矩形——边框有宽度【不是画笔本身的宽度】 ctx.fillRect(230,10,100, 200) ctx.clearRect(255,60,50,100)
canvas提供了一个画矩形路径的API,使用它就可以实现 路径方式画矩形:
ctx.beginPath() ctx.rect(200,200,100,100) // 矩形路径 ctx.closePath() ctx.stroke() // 空心矩形,如果要画实心就用fill
二、画线(即 路径):
/* 线 * */ // 线-直线 ctx.beginPath() ctx.moveTo(10, 220); ctx.lineTo(110, 220) ctx.stroke() // ctx.fill() /*这里无效,fill虽然会自动闭合路径,但是对于直线是无法闭合的。所以直线调用fill是无效的。无法填充*/ // 线-直角 ctx.beginPath() ctx.moveTo(120, 220); ctx.lineTo(220, 220) ctx.lineTo(220, 320) ctx.closePath() // 自动把线连接到路径的起始位置,相当与简写了最后一个ctx.lineTo到起始位置的线。 ctx.stroke() // 线-直角-填充 ctx.beginPath() ctx.moveTo(230, 220); ctx.lineTo(330, 220) ctx.lineTo(330, 320) ctx.stroke() ctx.fill() // 非直线,fill会自动闭合路径,然后填充颜色。
说明:
- 画线通过填充也是可以画矩形的,当然没有上面专门用来画矩形的方便。
- 闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。可以理解为,
closePath 相当于调用了 lineTo(开始点坐标),不过 closePath 比 lineTo完美(在线宽比较大时就能体现出来)。
- 后面使用 beginPath,就会把前面的 路径列表清空重置。不影响后面的路径。
- closePath 结束的只是路径,画笔上设置的 颜色(strokeStyle)、线宽(lineWidth)后面的路径还是会继承的。
- 同一个路径的直角,拐角处比两条路径的拐角完美,没有缺口。类似上面使用 closePath 比 lineTo 完美。
即,一个直角用一条路径画 或 比 分成 两条画 更 完美。
三、圆弧:
/* 圆 * 说明:圆不像线,从一个点开始画,圆是基于数学原理。从圆心开始定位,设定半径来实现的。所以画圆,不需要moveTo函数。 * */ // 圆弧——线 ctx.beginPath() ctx.arc(100,380,80,0,2) ctx.stroke() // 圆弧——填充 ctx.beginPath() ctx.arc(300,380,80,0,2) ctx.fill()
四、二次贝塞尔曲线:
/* 二次贝塞尔曲线 * */ ctx.beginPath() ctx.moveTo(10,580) ctx.quadraticCurveTo(200,500,280,580) ctx.stroke()
五、绘制文本:
/* 绘制文本 * */ ctx.font = "42px serif" ctx.textAlign = "center" ctx.textBaseline = "middle" ctx.fillText('hello word', 10, 650)
六、绘制图片:
/* 绘制图片 * */ var img = new Image() img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png' ctx.drawImage(img,10,700)
完整代码:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); // 默认画笔的宽度是1px【这是个人理解的】 /* 矩形 * */ // 矩形——实心 ctx.fillRect(10,10,100, 200) // 矩形——边框 ctx.strokeRect(120,10,100, 200) // 矩形——边框 ctx.fillRect(230,10,100, 200) ctx.clearRect(255,60,50,100) /*canvas中除了矩形,其它的现状都是通过路径实现的*/ /* 线 * */ // 线-直线 ctx.beginPath() ctx.moveTo(10, 220); ctx.lineTo(110, 220) ctx.stroke() // ctx.fill() /*这里无效,fill虽然会自动闭合路径,但是对于直线是无法闭合的。所以直线调用fill是无效的。无法填充*/ // 线-直角 ctx.beginPath() ctx.moveTo(120, 220); ctx.lineTo(220, 220) ctx.lineTo(220, 320) ctx.closePath() // 自动把线连接到路径的起始位置,相当与简写了最后一个ctx.lineTo到起始位置的线。 ctx.stroke() // 线-直角-填充 ctx.beginPath() ctx.moveTo(230, 220); ctx.lineTo(330, 220) ctx.lineTo(330, 320) ctx.stroke() ctx.fill() // 非直线,fill会自动闭合路径,然后填充颜色。 /* 圆弧 * 说明:圆不像线,从一个点开始画,圆是基于数学原理。从圆心开始定位,设定半径来实现的。所以画圆,不需要moveTo函数。 * */ // 圆——线 ctx.beginPath() ctx.arc(100,380,80,0,2) ctx.stroke() // 圆——填充 ctx.beginPath() ctx.arc(300,380,80,0,2) ctx.fill() /* 二次贝塞尔曲线 * */ ctx.beginPath() ctx.moveTo(10,580) ctx.quadraticCurveTo(200,500,280,580) ctx.stroke() // ////////////////////////////////////////// /* 绘制文本 * */ ctx.font = "42px serif" ctx.fillText('hello word', 10, 650) /* 绘制图片 * */ var img = new Image() img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png' ctx.drawImage(img,10,700)