javascript - 在 JavaScript 画布 API 中设置允许的绘图区域
问题描述
我正在使用 JavaScript 画布 API 进行免费绘图。我坚持掩盖允许绘制的区域 - 在我的示例中,它应该只是语音气泡区域。我正在使用这个 Vue 组件:https ://github.com/sametaylak/vue-draw/blob/master/src/components/CanvasDraw.vue
draw(event) {
this.drawCursor(event);
if (!this.isDrawing) return;
if (this.tools[this.selectedToolIdx].name === 'Eraser') {
this.canvasContext.globalCompositeOperation = 'destination-out';
} else {
this.canvasContext.globalCompositeOperation = 'source-over';
this.canvasContext.strokeStyle = this.tools[this.selectedToolIdx].color;
}
this.canvasContext.beginPath();
this.canvasContext.moveTo(this.lastX, this.lastY);
this.canvasContext.lineTo(event.offsetX, event.offsetY);
this.canvasContext.stroke();
[this.lastX, this.lastY] = [event.offsetX, event.offsetY];
},
drawCursor(event) {
this.cursorContext.beginPath();
this.cursorContext.ellipse(
event.offsetX, event.offsetY,
this.brushSize, this.brushSize,
Math.PI / 4, 0, 2 * Math.PI
);
this.cursorContext.stroke();
setTimeout(() => {
this.cursorContext.clearRect(0, 0, this.width, this.height);
}, 100);
},
解决方案
有一个内置clip()
方法将路径设置为剪切区域。
var ctx=document.getElementById("cnv").getContext("2d");
ctx.lineWidth=2;
ctx.strokeStyle="red";
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke(); // 1.
ctx.strokeStyle="black";
ctx.beginPath();
ctx.moveTo(10,10);
ctx.lineTo(100,10);
ctx.lineTo(100,60);
ctx.lineTo(30,60);
ctx.lineTo(10,80);
ctx.closePath();
ctx.stroke(); // 2.
ctx.clip(); // 3.
ctx.strokeStyle="green";
ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(100,0);
ctx.stroke(); // 4.
<canvas id="cnv"></canvas>
- 红线在 0,0 和 100,100 之间绘制,没有剪裁
- 气泡以黑色绘制
- 气泡设置为剪切区域
- 绿线在 0,100 和 100,0 之间绘制,并正确地夹在气泡中。
在实践中,您可能希望在气泡内有一个像素的剪切区域,因此是一个单独的路径(不是stroke()
-d,只是clip()
-ped),因此绘图不能修改气泡本身。如果现在按原样放大,您会看到绿线实际上过度绘制了气泡的内部像素(线宽为 2 个像素,而外部是“未损坏”的)。
推荐阅读
- python - 遍历 Jinja2 模板中的字典列表
- javascript - 服务器响应显示在页面中,无法在客户端处理
- blender - Blender 2.79 材料导出到 gltf 失去光泽
- flutter - Flutter中的主题覆盖不起作用,使用官方示例
- vue.js - 如何将抽屉图标和标题移动到工具栏的左侧
- jsf - 如何正确使用@NotNull 注解?
- visual-studio - 面向 .NET Core 2.2 的 Azure 函数
- powershell - 如果 *.tmp 存在于其中的任何位置,如何不对目录进行操作?
- terraform - Terraform:如果子网不存在,则将 interface 设置为 null
- c++ - 所有类型的 STL 容器的通用排序