如何在HTML5canvas中修复模糊文字?

我总共有HTML5 n00b ,我正在使用canvas来渲染形状,颜色和文本。 在我的应用程序中,我有一个视图适配器 ,dynamic创build一个canvas,并填充内容。 这工作真的很好,除了我的文本呈现非常模糊/模糊/拉伸。 我已经看到了很多其他的post,为什么在CSS定义宽度高度将导致这个问题,但我定义了所有的javascript

相关的代码(查看小提琴 ):

HTML

 <div id="layout-content"></div> 

使用Javascript

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

我看到的结果(在Safari中 )比小提琴中显示的要多得多:

在Safari中渲染输出

小提琴

在JSFiddle上渲染输出

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

canvas元素独立于设备或显示器的像素比例运行。

在iPad 3+上,这个比例是2.这基本上意味着您的1000像素宽的canvas现在需要填充2000px以匹配它在iPad显示器上的宽度。 幸运的是,这是由浏览器自动完成的。 另一方面,这也是为什么你看不到直接适合其可见区域的图像和canvas元素的定义。 由于您的canvas只知道如何填充1000px,但要求绘制到2000px,所以浏览器现在必须智能地填充像素之间的空白以显示适当大小的元素。

我强烈build议您从HTML5Rocks中阅读这篇文章 ,其中详细解释了如何创build高清晰度元素。

TL;博士? 下面是一个例子(基于上面的tut),我在自己的项目中用正确的分辨率吐出一个canvas:

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

希望这可以帮助!

解决了!

我决定看看改变了我在javascript设置的宽度高度属性,看看如何影响canvas的大小 – 事实并非如此。 它改变了决议。

为了得到我想要的结果,我还必须设置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 

我通过CSS调整canvas元素,以获取整个宽度的父元素。 我注意到我的元素的宽度和高度没有缩放。 我正在寻找最好的方式来设置大小应该是。

 canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; 

无论您使用什么屏幕,这个简单的方法都可以完美地设置您的canvas。

我稍微调整了canvg下的MyNameIsKo代码(SVG到Canvas js库)。 我困惑了一会儿,花了一些时间。 希望这可以帮助别人。

HTML

 <div id="chart"><canvas></canvas><svg>Your SVG here</svg></div> 

使用Javascript

 window.onload = function() { 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; })(); setHiDPICanvas = function(canvas, w, h, ratio) { if (!ratio) { ratio = PIXEL_RATIO; } var can = 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); } var svg = document.querySelector('#chart svg'), canvas = document.querySelector('#chart canvas'); var svgSize = svg.getBoundingClientRect(); var w = svgSize.width, h = svgSize.height; setHiDPICanvas(canvas, w, h); var svgString = (new XMLSerializer).serializeToString(svg); var ctx = canvas.getContext('2d'); ctx.drawSvg(svgString, 0, 0, w, h); }