我有一个带有鼠标悬停事件的简单画布。当用户移动鼠标时,我想在事件的x,y坐标处绘制单个像素(将来它将比单个像素更复杂)。基本上它就像一个自定义光标。
逻辑非常简单,如下所示。奇怪的是,虽然我正在清理旧的像素位置,但留下的像素残留很少(因为我发布了这个问题,我发现它与Retina显示有关)。我已经能够解决这个问题了。而不是保存1px并恢复1px,我保存3px并恢复3px。但是我不明白为什么我需要这样做,并且将来当我绘制一个更复杂的光标时,我希望脏像素处理是精确的。
这是一个可运行的JSFiddle示例:http://jsfiddle.net/sbCq3/2/
// cleanup previously drawn pixel
ctx.putImageData(lastImageData, lastImageX, lastImageY);
// save the imageData currently at x,y
lastImageData = ctx.getImageData(x, y, 1, 1);
lastImageX = x;
lastImageY = y;
// draw the dot
var dotData = ctx.createImageData(1, 1);
...
ctx.putImageData(dotData, x, y);
我有点难过。我想知道它是否与我的Retina显示器有任何关系。如果我在5,5处绘制单个像素,它是图像数据中的单个像素 - 但我可以使用DigitalColor Meter(内置缩放工具)进行缩放,并看到单个像素被细分并消除锯齿。然而,如果我在Windows机器上查看该像素,那么它就是一个很好的实心像素。我还没有测试过这个问题是否出现在Windows或非视网膜机器上。 (我不是指普通的画布抗锯齿问题)。
更新:我刚刚在我的同事非视网膜MacBook 17上进行了测试,它完全正常。所以这肯定与Retina显示器有关。
答案 0 :(得分:0)
我不完全确定,但我认为这可能与不同屏幕的分辨率有关。如果你曾经看过智能手机上的html5画布,其中大多数每平方英寸的分辨率都比显示器高得多,那么你会发现质量下降得多,因为网络浏览器会扩展你告诉它的100px使用相同的物理尺寸,最终约为130px。我认为你的视网膜显示也是如此,因为它使用了一个疯狂的好分辨率。基本上,不同的屏幕具有不同的像素尺寸比。为了解决这个问题,我在代码中添加了以下内容。
var PIXEL_RATIO = (function() {
var ctx = document.createElement("canvas").getContext("2d"),
dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backignStorePixelRatio || 1;
return dpr / bsr;
})();
现在,无论何时制作画布或绘制任何内容,都要将常量乘以变量PIXEL_RATIO。