canvas
矩形绘制
实心矩形
使用 fillRect 方法可以绘制实心矩形,下面是fillRect 方法的参数说明
参数 | 说明 |
---|---|
x | 矩形左上角的 x 坐标 |
y | 矩形左上角的 y 坐标 |
width | 矩形的宽度,以像素计 |
height | 矩形的高度,以像素计 |
const el = document.getElementById('canvas')
// 画布对象
const app = el.getContext('2d')
// 定义天聪颜色
app.fillStyle = '#16a085'
// 绘制矩形
app.fillRect(0, 0, 500, 500)
<canvas id="canvas" width="500" height="500">
您的浏览器不支持 HTML5 canvas
</canvas>
空心矩形
使用 strokeRect 方法可以绘制空心矩形,下面是strokeRect 方法的参数说明
参数 | 说明 |
---|---|
x | 矩形左上角的 x 坐标 |
y | 矩形左上角的 y 坐标 |
width | 矩形的宽度,以像素计 |
height | 矩形的高度,以像素计 |
const el = document.getElementById('canvas')
// 画布对象
const ctx = el.getContext('2d')
// 定义填充颜色
ctx.strokeStyle = '#16a085'
// 线条宽度
ctx.lineWidth = 30
// 边角类型:bevel斜角 ,round圆角,miter尖角
ctx.lineJoin = 'round'
// 绘制矩形边框
ctx.strokeRect(50, 50, 300, 300)
圆形绘制
arc
下面是绘制圆方法 arc 的参数说明
参数 | 说明 |
---|---|
x | 圆的中心的 x 坐标。 |
y | 圆的中心的 y 坐标。 |
r | 圆的半径。 |
sAngle | 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。 |
eAngle | 结束角,以弧度计。 |
counterclockwise | 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。 |
绘制空心圆
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
ctx.beginPath()
ctx.strokeStyle = 'red'
ctx.lineWidth = 20
ctx.arc(100, 100, 60, 0, 2 * Math.PI)
ctx.stroke()
绘制实心圆
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
ctx.beginPath()
ctx.fillStyle = '#f1c40f'
ctx.arc(100, 100, 60, 0, 2 * Math.PI)
ctx.fill()
节点绘制
我们可以通过以下方法定义不同节点、线条样式来绘制图形
- beginPath() 重置绘制路径
- lineTo() 开始绘制线条
- moveTo() 把路径移动到画布中的指定点,但不会创建线条(lineTo方法会绘制线条)
- closePath() 闭合线条绘制,即当前点连接到线条开始绘制点
- lineWidth 线条宽度
- strokeStyle 线条的样式,可以是颜色 、渐变
- stroke() 根据上面方法定义的节点绘制出线条
绘制多边形
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
ctx.fillStyle = '#8e44ad'
ctx.fillRect(0, 0, el.clientWidth, el.height)
// 开始画线
ctx.beginPath()
// 移动起始点
ctx.moveTo(200, 0)
// 下一个节点
ctx.lineTo(400, 200)
ctx.lineTo(0, 200)
// 闭合节点
ctx.closePath()
// 线宽
ctx.lineWidth = 10
// 线颜色
ctx.strokeStyle = '#f1c40f'
// 划线
ctx.stroke()
线性渐变
使用canvas的createLinearGradient() 方法可以创建线性的渐变对象,用于实现线性渐变效果。
createLinearGradient
下面是createLinearGradient线性渐变的参数
参数 | 描述 |
---|---|
x0 | 渐变开始点的 x 坐标 |
y0 | 渐变开始点的 y 坐标 |
x1 | 渐变结束点的 x 坐标 |
y1 | 渐变结束点的 y 坐标 |
渐变边框
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
// 定义渐变的开始与结束坐标
const gradient = ctx.createLinearGradient(0, 0, 500, 500)
// 定义渐变位置与颜色,参数一为位置是从 0~1 之间,参数二为激变颜色
gradient.addColorStop(0, '#1abc9c')
gradient.addColorStop(0.5, '#9b59b6')
gradient.addColorStop(1, '#f1c40f')
// 渐变填充
ctx.strokeStyle = gradient
// 设置线的宽度
ctx.lineWidth = 20
// 绘制线条矩形
ctx.strokeRect(100, 100, 300, 300)
渐变填充
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
// 定义渐变的开始与结束坐标
const gradient = ctx.createLinearGradient(0, 0, 500, 500)
// 定义渐变位置与颜色,参数一为位置是从 0~1 之间,参数二为激变颜色
gradient.addColorStop(0, '#1abc9c')
gradient.addColorStop(0.5, '#9b59b6')
gradient.addColorStop(1, '#f1c40f')
// 渐变填充
ctx.fillStyle = gradient
// 绘制线条矩形
ctx.fillRect(0, 0, 500, 500)
清空区域
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
// 渐变填充
ctx.fillStyle = 'red'
// 绘制线条矩形
ctx.fillRect(0, 0, 500, 500)
// 清除矩形区域
ctx.clearRect(50, 50, 100, 100)
填充文字
fillText
下面是 fillText 方法的参数
参数 | 描述 |
---|---|
text | 规定在画布上输出的文本。 |
x | 开始绘制文本的 x 坐标位置(相对于画布)。 |
y | 开始绘制文本的 y 坐标位置(相对于画布)。 |
maxWidth | 可选。允许的最大文本宽度,以像素计。 |
textBaseline
textBaseline用于定义文字基线
参数 | 说明 |
---|---|
alphabetic | 默认。文本基线是普通的字母基线。 |
top | 文本基线是 em 方框的顶端。。 |
hanging | 文本基线是悬挂基线。 |
middle | 文本基线是 em 方框的正中。 |
ideographic | 文本基线是表意基线。 |
bottom | 文本基线是 em 方框的底端。 |
textAlign
textAlign用于文本的对齐方式的属性
参数 | 说明 |
---|---|
left | 文本左对齐 |
right | 文本右对齐 |
center | 文本居中对齐 |
start | 文本对齐界线开始的地方 (左对齐指本地从左向右,右对齐指本地从右向左) |
end | 文本对齐界线结束的地方 (左对齐指本地从左向右,右对齐指本地从右向左) |
示例
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
// 渐变填充
ctx.fillStyle = 'red'
// 文字大小与字体设置
ctx.font = '30px yahei'
// 定义文字基线
ctx.textBaseline = 'top'
// 文字对齐
ctx.textAlign = 'left'
// 清除矩形区域
ctx.fillText('mkimq.com', 0, 0)
激变文字
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
// 定义渐变的开始与结束坐标
const gradient = ctx.createLinearGradient(0, 0, 500, 500)
// 定义渐变位置与颜色,参数一为位置是从 0~1 之间,参数二为激变颜色
gradient.addColorStop(0, '#1abc9c')
gradient.addColorStop(0.5, '#9b59b6')
gradient.addColorStop(1, '#f1c40f')
// 渐变填充
ctx.strokeStyle = gradient
// 文字大小与字体设置
ctx.font = '30px yahei'
// 定义文字基线
ctx.textBaseline = 'top'
// 文字对齐
ctx.textAlign = 'left'
// 清除矩形区域
ctx.strokeText('http://www.mkimq.com', 0, 0)
图片填充
参数说明
参数 | 描述 |
---|---|
image | 规定要使用的图片、画布或视频元素。 |
repeat | 默认。该模式在水平和垂直方向重复。 |
repeat-x | 该模式只在水平方向重复。 |
repeat-y | 该模式只在垂直方向重复。 |
no-repeat | 该模式只显示一次(不重复)。 |
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
// 创建图片
const img = new Image()
img.src = 'https://img2.baidu.com/it/u=1814268193,3619863984&fm=253&fmt=auto&app=138&f=JPEG?w=632&h=500'
img.onload = () => {
// 第二个参数:"repeat|repeat-x|repeat-y|no-repeat"
const pat = ctx.createPattern(img, 'repeat')
ctx.fillStyle = pat
ctx.fillRect(0, 0, 500, 500)
}
图片缩放
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
// 创建图片
const img = new Image()
img.src = 'https://img2.baidu.com/it/u=1814268193,3619863984&fm=253&fmt=auto&app=138&f=JPEG?w=632&h=500'
img.onload = () => {
el.width = img.naturalWidth * scale(img, el)
el.height = img.naturalHeight * scale(img, el)
ctx.drawImage(img, 0, 0, el.width, el.height)
}
// 取最小缩放
function scale(img, el) {
return Math.min(el.width/ img.naturalWidth, el.height / img.naturalHeight)
}
绘制像素
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, el.width, el.height)
// 像画布绘制点
for (let i = 0; i < 1000; i++) {
// 随机坐标
const x = Math.floor(Math.random() * el.width)
const y = Math.floor(Math.random() * el.height)
// 绘制5*5白块
ctx.rect(x, y, 5, 5)
ctx.fillStyle = '#fff'
ctx.fill()
}
绘制不规则
const el = document.getElementById('canvas')
const ctx = el.getContext('2d')
ctx.fillStyle = '#000'
ctx.fillRect(0, 0, el.width, el.height)
// 像画布绘制点
for (let i = 0; i < 20; i++) {
ctx.beginPath()
ctx.arc(Math.random() * el.width, Math.random() * el.height, 5 + Math.floor(Math.random() * 100), 0, 2 * Math.PI)
ctx.fillStyle = ['yellow', 'red', '#16a085', '#2ecc71', '#f1c40f', '#9b59b6'].sort(() => {
return Math.floor(Math.random() * 3) ? 1 : -1
})[0]
ctx.fill()
}
黑板实例
class Draw {
constructor(width, height, el, app, btns) {
this.el = el
this.app = app
this.btns = btns
this.el.width = width
this.el.height = height
this.#setBackground()
this.#event()
}
#event() {
// bind会返回新函数,addEventListener与removeEventListener要使用相同函数
const callback = this.#drawEventCallback.bind(this)
this.el.addEventListener('mousedown', () => {
// 重新画线
this.app.beginPath()
// 鼠标移动事件
this.el.addEventListener('mousemove', callback)
})
// 鼠标抬起时移除事件
this.el.addEventListener('mouseup', () => this.el.removeEventListener('mousemove', callback))
return this
}
// 黑板写字的事件回调函数
#drawEventCallback(event) {
this.app.lineTo(event.offsetX, event.offsetY)
this.app.strokeStyle = 'white'
this.app.stroke()
}
short() {
const bt = document.createElement('button')
bt.innerText = '截图'
this.btns.insertAdjacentElement('beforeend', bt)
const img = new Image()
this.el.insertAdjacentElement('afterend', img)
bt.addEventListener('click', () => {
// 使用canval标签的toDataURL方法,获取图片数据内容
img.src = this.el.toDataURL('image/jpeg')
img.style.cssText = 'width:300px;position:absolute;bottom:50px;right:0;border:solid 10px white;left:50%;transform:translateX(-50%);'
})
return this
}
clear() {
const bt = document.createElement('button')
bt.innerText = '清屏'
this.btns.insertAdjacentElement('beforeend', bt)
bt.addEventListener('click', () => {
this.app.fillStyle = '#000'
this.app.fillRect(0, 0, this.el.width, this.el.height)
})
}
#setBackground() {
this.app.fillStyle = '#000'
this.app.fillRect(0, 0, this.el.width, this.el.height)
}
}
const el = document.getElementById('canvas')
const app = el.getContext('2d')
const btns = el.insertAdjacentElement('afterend', document.createElement('div'))
const blackboard = new Draw(800, 300, el, app, btns)
blackboard.short()
blackboard.clear()