html - 是否可以控制 Canvas 纹理高档行为?

标签 html canvas cross-browser html5-canvas

在 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");

以下屏幕截图展示了在不同浏览器中运行时的结果。

在 Chrome 中:
Chrome

在 Firefox 中:
Firefox

在 IE11/Edge 中:
IE/Edge

是否有任何标志/选项可用于控制此行为并使其更加一致?

最后一个像素是环绕/重复插值结果的 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");;

enter image description here

如果您希望结果类似于 FF,则使用 ctx.drawImage 渲染位图。如果您想要不规则形状,则使用 ctx.drawImage 进行渲染,然后使用路径和 ctx.globalCompositeOperation = "destination-in" 进行 mask 。如果您需要渲染现有 Canvas 内容,则使用第二个 Canvas 渲染位图和 mask ,然后将该 Canvas 渲染到现有内容上。

在 Edge、Firefox 和 Chrome 上

ctx.drawImage(textureCanvas,0,1,2,1);

enter image description here

如果您想在所有 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/

相关文章:

javascript - 使用 Htmlcanvas 时出现安全错误 : The operation is insecure.

asp.net - 不同浏览器的 ASP 按钮看起来不同

javascript - 即使未设置也获取宽度

javascript - 如何在 jquery keyup 实时搜索期间排除 <ul> 元素?

javascript - 如何获取 Fabric JS 中形状的坐标?

javascript - 将 HTML 文本转换为图像 - Javascript

php - mysql在数据库中两次插入记录

css - 为什么对于这个 CSS,背景颜色属性不起作用?

html - 如何预加载 svg Sprite ?

html - 如何消除 HTML 页面的闪烁?