在 Canvas 中放大纹理时,不同浏览器的行为差异很大。
这是一个创建 2x1 纹理(由一个黑色和一个白色纹素组成)并将其应用到 256x128 像素矩形上的 fiddle :https://jsfiddle.net/ozirus/x1c3m50o/
var texture = ...
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = 512;
ctx.canvas.height = 512;
document.body.appendChild(ctx.canvas);
ctx.setTransform(128, 0, 0, 128, 0, 0);
ctx.fillStyle = ctx.createPattern(texture, "no-repeat");;
ctx.rect(0, 0, 2, 1);
ctx.fill("evenodd");
以下屏幕截图展示了在不同浏览器中运行时的结果。
是否有任何标志/选项可用于控制此行为并使其更加一致?
最后一个像素是环绕/重复插值结果的 IE/Edge 行为是我实际要解决的主要问题。
PS:我知道一些解决方法可以解决问题(半纹素偏移 + 放大,纹理上的透明边框,......)但我宁愿尽可能配置此行为。
编辑:正如@Ryan 在评论中指出的那样,CanvasRenderingContext2D.imageSmoothingEnabled
属性可用于在最近邻模式下具有匹配行为,但我想保持纹理的平滑插值
最佳答案
没有。
不,无法从 javascript 访问 2D API(CPU 和 GPU)背后的代码。该标准有很多漏洞,因此浏览器开发人员只能根据自己的喜好来解释它。
如果您在所有 3 种浏览器上使用“repeat”,您将获得与 Edge 上的“no-repeat”相同的结果。
在 Edge、Firefox 和 Chrome 上
ctx.fillStyle = ctx.createPattern(textureCanvas, "repeat");;
如果您希望结果类似于 FF,则使用 ctx.drawImage
渲染位图。如果您想要不规则形状,则使用 ctx.drawImage
进行渲染,然后使用路径和 ctx.globalCompositeOperation = "destination-in"
进行 mask 。如果您需要渲染现有 Canvas 内容,则使用第二个 Canvas 渲染位图和 mask ,然后将该 Canvas 渲染到现有内容上。
在 Edge、Firefox 和 Chrome 上
ctx.drawImage(textureCanvas,0,1,2,1);
如果您想在所有 3 种浏览器上获得与 Chrome 相同的结果,您需要在图像周围添加一个 1 像素的透明边框,然后渲染 2 像素的中心。
在下面的示例中,Firefox、Edge 和 chrome 上的结果相同(从您的 fiddle https://jsfiddle.net/ozirus/x1c3m50o/ 复制和修改)
var textureCanvas = document.createElement("canvas");
textureCanvas.width = 4;
textureCanvas.height = 3;
var textureContext = textureCanvas.getContext("2d");
var imgData = textureContext.createImageData(4, 3);
var i = 20;
imgData.data[i++] = 0;
imgData.data[i++] = 0;
imgData.data[i++] = 0;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
textureContext.putImageData(imgData, 0, 0);
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = 512;
ctx.canvas.height = 512;
document.body.appendChild(ctx.canvas);
ctx.setTransform(128, 0, 0, 128, 0, 0);
ctx.drawImage(textureCanvas,1,1,2,1,0,0,2,1);
html {
background-color: red;
}
是的。
所以我想这意味着您可以控制它,但可以间接使用不同的技术。
关于html - 是否可以控制 Canvas 纹理高档行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43278555/