目录
canvas元素一些默认特性
- 在默认状况下,canvas元素的背景色与其父元素的背景色一致。
- 默认的canvas元素大小是300×150个屏幕像素 。
- 在设置canvas的宽度与高度时,不能使用px后缀。
canvas是立即模式绘图系统
canvas元素是采用“立即模式”(immediate—mode)来绘制图形的,这意味着它会立刻将你所指定的内容绘制在canvas上。然后,它就会立刻忘记刚才绘制的内容,这表示canvas之中不会包含将要绘制的图形对象列表。某些绘图系统,比如SVG,则会维护一份所绘图形对象的列表。这些绘图系统被叫做“保留模式”(retained—mode)绘图系统。
由于立即模式并不维护所绘制对象的列表,所以相对于保留模式来说,它是一种更加底层的绘图模式。立即模式也更加灵活,因为它是直接向屏幕上绘制的,而不是像保留模式那样,需要调整由绘图系统传递过来的图形对象。
立即模式的绘制系统更适合制作“绘画应用程序”(paint application),这种程序不需要 跟踪记录用户所绘制的东西,而保留模式的绘制系统则更适合制作“画图应用程序”(drawing application),此种应用程序可以让用户操作其所创建的图形对象。
canvas元素的大小与绘图表面的大小,也就是css控制的大小和canvas实际大小
使用CSS来设置canvas元素的大小,与直接设置属性相比,其差别是基于这样一个事实 的:canvas元素实际上有两套尺寸。一个是元素本身的大小,还有一个是元素绘图表面(drawing surface)的大小。
当设置元素的width与height属性时,实际上是同时修改了该元素本身的大小与元素绘图表 面的大小。然而,如果是通过CSS来设定canvas元素的大小,那么只会改变元素本身的大小, 而不会影响到绘图表面。在默认情况下,canvas元素与其绘图表面,都是300像素宽、150像素 高。程序清单1—3的代码,使用CSS来将canvas元素的大小设置成600像素宽、300像素高,然而,绘图表面的大小依然没有改变,还是默认的300×150像素。
这时,有趣的事情就发生了。当canvas元素的大小不符合其绘图表面的大小时,浏览器就会 对绘图表面进行缩放,使其符合元素的大小。
在board.js
中,可以看到根据设备分辨率设置canvas 绘图表面大小和canvas 元素大小的代码。
// canvas 绘图表面大小 this.template.canvasEle.width = pageWidth * Utils.pixelRatio; this.template.canvasEle.height = pageHeight * Utils.pixelRatio; // canvas 元素大小 this.template.canvasEle.style.width = pageWidth + "px"; this.template.canvasEle.style.height = pageHeight + "px";
在board.js
中,可以看到根据设备分辨率获取鼠标在canvas 绘图表面位置的代码。
// 获取鼠标在【绘图表面】上的位置 _getPoint(e) { if (Utils.isMobile) { return { 'x': (e.touches[0].clientX - this.template.canvasEle.getBoundingClientRect().left) * Utils.pixelRatio, 'y': (e.touches[0].clientY - this.template.canvasEle.getBoundingClientRect().top) * Utils.pixelRatio }; } else { return { 'x': e.offsetX * Utils.pixelRatio, 'y': e.offsetY * Utils.pixelRatio }; } }
canvas的两个属性和三个API
在board.js
中,获取了canvas的数据地址,也就是base64格式的字符串,更新到了评论框中。
_getImage() { return this.template.canvasEle.toDataURL("image/png"); } _updateEditor = function (url) { return (url) => { let imgDom = `<img data-type="cdraw" src="${url}" />`; let reg = /\<img data-type="cdraw".*\>/g; if (reg.test(this.template.commentEle.value)) { this.template.commentEle.value = this.template.commentEle.value.replace(reg, imgDom); } else if (this.template.commentEle.value == "") { this.template.commentEle.value = imgDom; } else { if (/\n$/.test(this.template.commentEle.value)) { this.template.commentEle.value = this.template.commentEle.value + imgDom; } else { this.template.commentEle.value = this.template.commentEle.value + '\n' + imgDom; } } this.options.afterUpdateEditor(); } }
canvas的2d绘图环境(context)的所有属性
在board.js
中,设置了lineCap、lineJoin属性。
initCanvasStyle() { // 设置线条末端样式 this.context.lineCap = "round"; // 设定线条与线条间接合处的样式 this.context.lineJoin = "round"; }
save()/restore()方法
Canvas的API提供了两个名叫save()和restore()的方法,用于保存及恢复当前canvas绘图 环境的所有属性。save()与restore()方法也许看上去没什么大不了的,不过一旦开始使用Canvas进行开发,就会发现它们其实是不可或缺的功能。
save()与restore()方法可以嵌套式调用。绘图环境的save()方法会将当前的绘图环境压入堆栈顶部。对应的restore()方法则会从堆栈顶部弹出一组状态信息,并据此恢复当前绘图环境的各个状态。这意味着可以嵌套式地调用save()/restore()方法。
在shape/eraser.js
中,绘制橡皮擦时候,临时更改了lineWidth、strokeStyle,但由于先调用了this.context.save()
保存了先前的绘图属性,最后又调用了this.context.restore()
恢复了先前的绘图属性,所以,其他形状的绘制不会收到影响,可以体会到上文的意思:“不过一旦开始使用Canvas进行开发,就会发现它们其实是不可或缺的功能”。
// 显示圆形橡皮擦 _drawEraser(x, y) { // 橡皮擦 let eraserWidth = this.board.lineWidth; let eraserLineWidth = 5 * Utils.pixelRatio; let eraserStrokeStyle = 'rgb(252,150,148)'; this.context.save(); // 实际测试 lineWidth 绘制在了圆点内部 this.context.lineWidth = eraserLineWidth; this.context.strokeStyle = eraserStrokeStyle; this.context.beginPath(); this.context.arc(x, y, eraserWidth / 2, 0, Math.PI * 2); this.context.clip(); this.context.stroke(); this.context.restore(); }
反馈:您觉得本站怎么样?(此评价不会公开,也不会对博主产生任何实际利益。)
- 非常优秀
- 可以
- 一般
- 垃圾
- 超级恶心