最近我迷上了 HTMLcanvas
绘图及其视网膜支持。无需进一步绘制配置线canvas
-元素在视网膜显示屏上看起来有点模糊。
我确实知道视网膜显示屏的像素是其四倍,因此默认情况下必须填充一些设备像素(否则图片将只有预期大小的一半)。
Example:
绘制 HTMLcanvas
with width: 50px
and height: 50px
.
<canvas height="50px" width="50px">
浏览器位于normalscreen 只是绘制它(50*50 像素)。视网膜显示屏上的浏览器接收 50x50px 画布,但由于它是视网膜 50*50 设备像素将比预期的要小。因此浏览器在视网膜上绘制 100*100 像素。
画布上的清晰线条(单像素线黑/白)现在变得有点模糊,因为浏览器必须填充附近的像素并使用附近的周围环境 - 一些像素变成灰色。
如何修复它:
这段代码应该可以解决问题:
// Returns: 1 on 'normal' screens, 2 on retina displays
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.backingStorePixelRatio || 1;
return dpr / bsr;
})();
function makeCanvasHiPPI(canvas) {
canvas.style.width = canvas.width + "px";
canvas.style.height = canvas.height + "px";
canvas.width *= PIXEL_RATIO;
canvas.height *= PIXEL_RATIO;
var context = canvas.getContext('2d');
context.scale(PIXEL_RATIO, PIXEL_RATIO)
}
我认为代码的作用是:
通过在画布上使用这段代码,浏览器被告知使用 50*50px(这就是canvas.style
设置为)如上例所示 - 普通屏幕上为 50*50px,视网膜上为 100*100px。But它在内部将画布处理为两倍大小的画布(至少在视网膜设备上),因此能够绘制通常由浏览器填充的像素。
棘手的部分(我不quite理解):
缩放比例。双“canvas.width”?好吧,现在我们有更多的像素可以写入——更多的信息。好的。
但现在它已经缩放了,因此我们不really写入额外的像素(画布上只会显示 0 - 50) - 这次谁填充设备像素?我在没有缩放的情况下尝试了它,它允许我在 0 - 100 范围内的视网膜(~1 设备像素)上绘制更细的线条 - 这些像素仍然有点模糊,缩放后的线条更粗,但晶莹剔透。仅在大量缩放时才可见模糊。
专业规模:
- 水晶线
- 在我的示例中,没有缩放以某种方式没有产生强烈的黑色(在强变焦下可见)
专业无规模:
- 绘制细线的能力
-
canvas.width
真正代表我可以写入的像素。例如:
context.moveTo(0, context.canvas.height/2);
context.lineTo(context.canvas.width, context.canvas.height/2);
作品。这不适用于缩放,因为context.canvas.width
返回未缩放的值。
我的问题:
- 为什么即使我自己没有填充额外像素,缩放后线条仍然清晰?
- 我该如何处理误导性的返回值?
- 我应该总是使用
context.canvas.width / PIXEL_RATIO
(有缩放)?这确实解决了问题,但在代码中看起来不太好(OCD https://en.wikipedia.org/wiki/Obsessive%E2%80%93compulsive_disorder开始)。我会坚持下去,直到我得到更好的东西。