我希望在画布上以背景的反色绘制文本(以确保文本无论背景颜色如何都可以读取)。 我相信在旧式的位块传输中,这是一种异或操作。
如何实现?
如何实现?
更新:现在大多数新版浏览器都支持混合模式“差异”,可以实现相同的效果。
context.globalCompositeOperation = "difference";
更新演示。
旧答案:
人们可能会认为合成的XOR模式可以做到这一点,但不幸的是,画布的XOR仅XOR alpha位。
通过应用以下代码,我们可以获得如下结果:
你可以像这样为画布创建一个扩展:CanvasRenderingContext2D.prototype.fillInversedText =
function(txt, x, y) {
//code - see below
}
ctx.fillInversedText(txt, x, y);
var tw = this.measureText(txt).width;
var th = parseInt(ctx.font, '10');
th = (th === 0) ? 10 : th; //assume default if no font and size is set
var co = document.createElement('canvas');
co.width = tw;
co.height = th;
然后绘制实际文本。颜色并不重要,因为我们只对此画布的 alpha 通道感兴趣:
var octx = co.getContext('2d');
octx.font = this.font;
octx.textBaseline = 'top';
octx.fillText(txt, 0, 0);
然后,我们提取要绘制反转文本的区域的像素缓冲区以及所有离屏画布的像素,该画布现在包含我们的文本:
var ddata = this.getImageData(x, y, tw, th);
var sdata = octx.getImageData(0, 0, tw, th);
var dd = ddata.data; //cache for increased speed
var ds = sdata.data;
var len = ds.length;
然后我们反转每个像素,其中像素的 alpha 通道大于 0。
for (var i = 0; i < len; i += 4) {
if (ds[i + 3] > 0) {
dd[i] = 255 - dd[i];
dd[i + 1] = 255 - dd[i + 1];
dd[i + 2] = 255 - dd[i + 2];
}
}
最后将倒置的图像放回:
this.putImageData(ddata, x, y);
这可能看起来像很多操作,但速度相当快。
演示(如果您对闪烁敏感,请注意警告)
(迷幻背景只是为了有一些变化,因为fiddle需要外部图像,而大多数图像在使用像素处理时都会受到CORS的限制。)
我已经删除了我的旧答案,因为它没有解决问题。 最近,出现了新的globalCompositeOperation
,可以做各种很棒的事情。 我创建了一个示例,展示如何获得反转文本。 如果该链接失效,方法基本上是这样的:
ctx.globalCompositeOperation = "difference";
ctx.fillStyle = "white";
//draw inverted things here
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation