Hi,
I am working on a canvas and I want it to be responsive (look same on different screen sizes), resizable (look same when browser window resizes and resize properly), size-adjustable (user can enter canvas output size) and look sharp (no blurry edges of shapes).
The code I have below satisfies all other criteria but it shows edges of shapes blurry. For example, the top and left edges of the rectangle in the drawing below are blurry, whereas right and bottom edges are sharp (on Firefox, and vice versa on Chrome).
My code is below but you can also test it live here on my site: https://www.yenren.art/cnv/
Please either right click and view the canvas image or save it to see the blurry edges better.
test.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<style>body{overflow:hidden;background:#222;margin:0}#wrp{margin:0 auto}canvas{margin:auto;width:100%;height:100%}
</style>
</head>
<body>
<div id="wrp"><canvas id="canvas"></canvas></div>
<script src="./draw.js"></script>
</body>
</html>
draw.js:
var cnv = document.getElementById("canvas"), ctx = cnv.getContext("2d");
var wrp = document.getElementById("wrp");
// ar (aspect ratio), size (user can enter different values - the canvas size to save as output)
var ar = 0.8, size = 2000;
var width, height;
var scale = size / ((innerWidth < innerHeight * ar) ? innerWidth : innerHeight * ar);
function draw() {
setup();
ctx.fillStyle = "#D4CAA3"; ctx.fillRect(0, 0, width, height); // background
ctx.fillStyle = "#A15837"; ctx.fillRect(200, 200, 200, 200); // position can change and a scene may have multiple rectangles
}
function setup() {
const PR = window.devicePixelRatio || 1;
let w = innerWidth, h = innerHeight;
// accounts for portrait and landscape orientations
width = (w < h * ar) ? w : h * ar;
height = (w < h * ar) ? w / ar : h;
wrp.style.width = width + "px";
wrp.style.height = height + "px";
cnv.width = Math.ceil(size * PR);
cnv.height = Math.ceil(size / ar * PR);
ctx.scale(scale, scale);
}
window.addEventListener("resize", draw, false);
draw();
The above code is a result of endless search on various resources, but I still couldnāt get rid of the blurry edges. Any ideas how to fix that?
P.S. Adding 0.5px to coordinates or width/height do not always work, so, I am looking for other approaches if possible.
My last resort is to draw each shape 3-4 times, which makes them appear sharp but this is not ideal code and performance wise, and will avoid if I can find another solution.
Thanks!