如何修复 HTML5 画布中的模糊文本?

新手上路,请多包涵

我完全不喜欢 --- HTML5 并且正在使用 canvas 渲染形状、颜色和文本。在我的应用程序中,我有一个动态创建画布并用内容填充它的 _视图适配器_。这真的很好用,只是我的文本呈现得非常模糊/模糊/拉伸。我看过很多其他帖子,说明为什么在 CSS 中定义 宽度高度 会导致此问题,但我将其全部定义在 javascript 中。

相关代码(查看 Fiddle ):

 var width  = 500;//FIXME:size.w;
var height = 500;//FIXME:size.h;

var canvas = document.createElement("canvas");
//canvas.className="singleUserCanvas";
canvas.width=width;
canvas.height=height;
canvas.border = "3px solid #999999";
canvas.bgcolor = "#999999";
canvas.margin = "(0, 2%, 0, 2%)";

var context = canvas.getContext("2d");

//////////////////
////  SHAPES  ////
//////////////////

var left = 0;

//draw zone 1 rect
context.fillStyle = "#8bacbe";
context.fillRect(0, (canvas.height*5/6)+1, canvas.width*1.5/8.5, canvas.height*1/6);

left = left + canvas.width*1.5/8.5;

//draw zone 2 rect
context.fillStyle = "#ffe381";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*2.75/8.5, canvas.height*1/6);

left = left + canvas.width*2.75/8.5 + 1;

//draw zone 3 rect
context.fillStyle = "#fbbd36";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5;

//draw target zone rect
context.fillStyle = "#004880";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*0.25/8.5, canvas.height*1/6);

left = left + canvas.width*0.25/8.5;

//draw zone 4 rect
context.fillStyle = "#f8961d";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5 + 1;

//draw zone 5 rect
context.fillStyle = "#8a1002";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width-left, canvas.height*1/6);

////////////////
////  TEXT  ////
////////////////

//user name
context.fillStyle = "black";
context.font = "bold 18px sans-serif";
context.textAlign = 'right';
context.fillText("User Name", canvas.width, canvas.height*.05);

//AT:
context.font = "bold 12px sans-serif";
context.fillText("AT: 140", canvas.width, canvas.height*.1);

//AB:
context.fillText("AB: 94", canvas.width, canvas.height*.15);

//this part is done after the callback from the view adapter, but is relevant here to add the view back into the layout.
var parent = document.getElementById("layout-content");
parent.appendChild(canvas);
 <div id="layout-content"></div>

我看到的结果(在 Safari 中)比 Fiddle 中显示的更偏斜:

Safari 中的渲染输出

小提琴

JSFiddle 上的渲染输出

我做错了什么?每个文本元素都需要单独的画布吗?是字体吗?我需要先在 HTML5 布局中定义画布吗?有错字吗?我搞不清楚了。

原文由 Phil 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 444
2 个回答

画布元素独立于设备或监视器的像素比运行。

在 iPad 3+ 上,这个比率是 2。这实际上意味着您的 1000 像素宽度的画布现在需要填充 2000 像素以匹配它在 iPad 显示屏上规定的宽度。对我们来说幸运的是,这是由浏览器自动完成的。另一方面,这也是为什么在直接适合其可见区域的图像和画布元素上看到清晰度较低的原因。因为您的画布只知道如何填充 1000 像素,但被要求绘制到 2000 像素,浏览器现在必须智能地填充像素之间的空白,以便以适当的大小显示元素。

我强烈建议您阅读 HTML5Rocks 中的 这篇文章,其中更详细地解释了如何创建高清元素。

tl;博士?这是一个示例(基于上面的教程),我在自己的项目中使用它来吐出具有适当分辨率的画布:

 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;
})();

createHiDPICanvas = function(w, h, ratio) {
    if (!ratio) { ratio = PIXEL_RATIO; }
    var can = document.createElement("canvas");
    can.width = w * ratio;
    can.height = h * ratio;
    can.style.width = w + "px";
    can.style.height = h + "px";
    can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
    return can;
}

//Create canvas with the device resolution.
var myCanvas = createHiDPICanvas(500, 250);

//Create canvas with a custom resolution.
var myCustomCanvas = createHiDPICanvas(500, 200, 4);

希望这可以帮助!

原文由 MyNameIsKo 发布,翻译遵循 CC BY-SA 3.0 许可协议

解决了!

我决定看看是什么改变了我在 javascript 中设置的 宽度高度 属性,看看它是如何影响画布大小的——但它没有。它改变了分辨率。

为了获得我想要的结果,我还必须设置 canvas.style.width 属性,这会更改 canvas 的物理大小:

 canvas.width=1000;//horizontal resolution (?) - increase for better looking text
canvas.height=500;//vertical resolution (?) - increase for better looking text
canvas.style.width=width;//actual width of canvas
canvas.style.height=height;//actual height of canvas

原文由 Phil 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题