我面临一个明显已知的问题,HTML画布中的行不能禁用抗锯齿(例如this question提到这只能用于使用context.imageSmoothingEnabled= false
的图像,而不能用于行。< / p>
我想知道是否有任何更新,如果有可能绘制一个清晰(即使“像素化”)线?所有我需要的是例如当使用普通的“铅笔”工具(参见下面的左侧笔划)时,MS Paint可以实现,而不是更平滑的“笔刷”类型(参见右侧笔划)。
这是一个问题,因为我正在尝试设置一个鼠标事件,它给出了线条的确切颜色,但是在实际颜色周围使用抗锯齿,它会在光标到达之前返回一些不需要的颜色。这条线的中心部分。
有人可以确认在画布上真的没有办法强迫“铅笔”般的笔画吗?如果是这样,可能有一个简单的解决方法,例如“切断”中风的边缘?
答案 0 :(得分:2)
您可以使用SVG滤镜在画布上绘制这样的像素化形状,该滤镜可以移除形状边缘的Alpha值。 (但是SVG过滤器有点重。)
const ctx = canvas.getContext("2d");
//normal line(antialiased)
ctx.moveTo(20,20); ctx.lineTo(180,20);
ctx.stroke();
//set "crisp edge" filter
ctx.filter = "url(#crisp)";
//crisp line
ctx.beginPath();ctx.moveTo(20,40); ctx.lineTo(180,40);
ctx.moveTo(20, 50); ctx.lineTo(180, 70);
//crisp circle
ctx.moveTo(150, 130); ctx.arc(100, 130, 50, 0, Math.PI*2);
ctx.stroke();
&#13;
<canvas id="canvas" width="200" height="200"></canvas>
<svg style="visibility:hidden;width:0;height:0;">
<defs>
<!--SVG filter to remove alpha-->
<filter id="crisp">
<feComponentTransfer>
<feFuncA type="discrete" tableValues="0,1"></feFuncA>
</feComponentTransfer>
</filter>
</defs>
</svg>
&#13;
注意:但Chrome使用SVG过滤器会在输出图像上引发安全性错误。
如果您需要自己实现此类过滤器,ImageData
对象将对您有所帮助。这没有安全错误风险。
但手工过滤器太重,无法应用于每个活动图纸。你应该仔细考虑申请时间。
const ctx = canvas.getContext("2d");
//temporary canvas to removeAlpha
const tmp = document.createElement("canvas");
[tmp.width, tmp.height] = [canvas.width, canvas.height];
const tctx = tmp.getContext("2d");
//normal line(antialiased)
ctx.moveTo(20,20); ctx.lineTo(180,20);
ctx.stroke();
//crisp line
tctx.beginPath(); tctx.moveTo(20,40); tctx.lineTo(180,40);
tctx.moveTo(20, 50); tctx.lineTo(180, 70);
removeAlpha();
//crisp circle
tctx.moveTo(150, 130); tctx.arc(100, 130, 50, 0, Math.PI*2);
tctx.stroke();
removeAlpha();
//remove alpha on tmp canvas and draw it to main canvas.
function removeAlpha(){
const threshold = 128;//you can change the value
const id = tctx.getImageData(0, 0, tmp.width, tmp.height);
const data = id.data;//pixel data array
//remove alpha values pixel by pixel.
for(let i = 0, len = canvas.width * canvas.height; i<len; i++){
const apos = i * 4 + 3;//alpha data position
const a = data[apos];
data[apos] = a > threshold ? 255 : 0;
}
tctx.putImageData(id, 0, 0);
ctx.drawImage(tmp, 0, 0);
tctx.clearRect(0, 0, tmp.width, tmp.height);
}
&#13;
<canvas id="canvas" width="200" height="200"></canvas>
&#13;