Canvas has inconsistent pixel grid across browsers when using drawImage()(使用 drawImage() 时,Canvas 的跨浏览器像素网格不一致)
问题描述
我认识到
您可能希望通过他们的 bug-tracker 让他们知道.
解决方法是确保您永远不会停留在浮动坐标上,即使在您的转换矩阵中也是如此.
I recognize that Canvas drawImage is inexplicably offset by 1 Pixel is a very similar issue, but I was already applying the advice given in that question's answer before I even came across this problem.
I'm implementing a sprite sheet system for an HTML5-based game. Individual frames are defined simply:
frame = new AnimationFrame(img, x, y, w, h);
Inside the AnimationFrame constructor, all of the numeric parameters are truncated to integers.
Then when I go to draw it on the canvas, I use what should also be simple code:
context.drawImage(frame.img,
frame.x,
frame.y,
frame.w,
frame.h,
this.position.x | 0,
this.position.y | 0,
frame.w,
frame.h,
);
Unfortunately, I get different results in different browsers.
In Chrome on Mac and Firefox on Mac, slicing the sprite sheet this way causes the individual frames to be offset by half a pixel, causing the top edge of the character's head to be drawn too thin and the top of the next sprite down to peek into the bottom of this one.
I can accommodate this problem with frame.x - 0.5
and frame.y - 0.5
but if I do that then I get the opposite problem in Safari on Mac and iOS and in Firefox on Windows.
I don't particularly WANT to do a browser detect to decide how to nudge the coordinate system, so I'm looking for suggestions for a way to either (1) force the various browsers to behave the same way, or (2) detect the issue at page load time with a test so I can just store the pixel grid offset in a variable.
NB: I'm going for a chunky pixel aesthetic, so my canvas is scaled by a factor of 2. This works fine without blurring, but it makes the half-pixel issue more clearly visible. Without scaling, the edges of the sprite still get distorted, so that's not the problem.
I can't tell for IE, but at least for Safari, this sounds like a bug in their nearest-neighbor algorithm when the transformation matrix translate is set to exactly n.5
.
onload = function() {
var ctx = document.querySelector('canvas').getContext('2d');
ctx.imageSmoothingEnabled = false;
var img = document.querySelector('#hero');
ctx.setTransform(2, 0, 0, 2, 99.49, 99.49);
ctx.drawImage(img, 32, 32, 16, 16, 0, 0, 16, 16);
ctx.setTransform(2, 0, 0, 2, 99.5, 99.5);
ctx.drawImage(img, 32, 32, 16, 16, 16, 0, 16, 16);
ctx.setTransform(2, 0, 0, 2, 99.51, 99.51);
ctx.drawImage(img, 32, 32, 16, 16, 32, 0, 16, 16);
};
<img src='http://xmpps.greenmaw.com/~coda/html52d/hero.png' id='hero' style='display:none' />
<canvas width='200' height='200'></canvas>
Result in Safari 11.0.3
You may want to let them know about it from their bug-tracker.
The workaround would be to make sure that you never lay on floating coordinates, even in your transformation matrix.
这篇关于使用 drawImage() 时,Canvas 的跨浏览器像素网格不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 drawImage() 时,Canvas 的跨浏览器像素网格不一致
基础教程推荐
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- Chart.js 在线性图表上拖动点 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- 直接将值设置为滑块 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01