How to Fix Blurry Text in My Html5 Canvas

How do I fix blurry text in my HTML5 canvas?

The canvas element runs independent from the device or monitor's pixel ratio.

On the iPad 3+, this ratio is 2. This essentially means that your 1000px width canvas would now need to fill 2000px to match it's stated width on the iPad display. Fortunately for us, this is done automatically by the browser. On the other hand, this is also the reason why you see less definition on images and canvas elements that were made to directly fit their visible area. Because your canvas only knows how to fill 1000px but is asked to draw to 2000px, the browser must now intelligently fill in the blanks between pixels to display the element at its proper size.

I would highly recommend you read this article from HTML5Rocks which explains in more detail how to create high definition elements.

tl;dr?
Here is an example (based on the above tut) that I use in my own projects to spit out a canvas with the proper resolution:

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

Hope this helps!

The Text on The Canvas Looks Pretty Blurry

What could be the reason for this?

That's how canvas works. It's a raster image, not a vector.

You create a text using 16px font (context.font = "16px Comic Sans MS") and then enlarge it by using CSS (width: 936px; height: 435px;).

There are a few possible solutions to make the text non-blurry.

  • Do not use canvas.
  • Do not resize canvas.

Canvas is stretched when using CSS but normal with width / height properties

It seems that the width and height attributes determine the width or height of the canvas’s coordinate system, whereas the CSS properties just determine the size of the box in which it will be shown.

This is explained in the HTML specification:

The canvas element has two attributes to control the size of the element’s bitmap: width and height. These attributes, when specified, must have values that are valid non-negative integers. The rules for parsing non-negative integers must be used to obtain their numeric values. If an attribute is missing, or if parsing its value returns an error, then the default value must be used instead. The width attribute defaults to 300, and the height attribute defaults to 150.

Canvas drawings, like lines, are blurry

When drawing lines in canvas, you actually need to straddle the pixels. It was a bizarre choice in the API in my opinion, but easy to work with:

Instead of this:

context.moveTo(10, 0);
context.lineTo(10, 30);

Do this:

context.moveTo(10.5, 0);
context.lineTo(10.5, 30);

Dive into HTML5's canvas chapter talks about this nicely

HTML5 Canvas font gets blurry if added to a pdf file with jspdf

Current workaround:

I changed the input unit format to px and calculate the size factor between the code generated and the original size from the dataURL and found that the code generated is exactly 1.7784 times bigger.

So I just divide the size with this factor

pdf.addImage(contentDataURL, 'PNG', 0, 0, Math.floor(canvas.width / 1.7784), Math.floor(canvas.height / 1.7784));

It will work. But I feel like that there is a better way to do that.


Edit:

I found the better way. When providing a width and heigth of 0, the size will be set to the actual size of the added image:

pdf.addImage(contentDataURL, 'PNG', 0, 0, 0, 0);


Related Topics



Leave a reply



Submit