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
andheight
. 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. Thewidth
attribute defaults to 300, and theheight
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
Saving Binary Data as File Using JavaScript from a Browser
How to Convert a Dom Node List to an Array in JavaScript
How to Get the Background Color of an HTML Element
Change an Image With Onclick()
Css Transition Doesn't Start/Callback Isn't Called
Adding an Image Within a Circle Object in D3 JavaScript
How to Convert Unordered List into Nicely Styled ≪Select≫ Dropdown Using Jquery
What Is the Scope of Variables in JavaScript
How to Check If an Array Includes a Value in JavaScript
How to Set Focus on an Element in an HTML Form Using JavaScript
How to Run JavaScript Before the Whole Page Is Loaded
How to Escape Quotes in HTML Attribute Values
How to Get Element in User-Agent Shadow Root With JavaScript
Prevent Body from Scrolling When a Modal Is Opened