-
-
Save callumlocke/cc258a193839691f60dd to your computer and use it in GitHub Desktop.
/* | |
UPDATED for 2023 - Now much simpler. The old tricks are no longer needed. | |
The following code makes an 800×600 canvas that is always as sharp as possible for the device. | |
You still draw on it as if it's the logical size (800×600 in this case), but everything just | |
looks sharper on high-DPI screens. Regular non-sharp screens are not affected. | |
*/ | |
const width = 800 | |
const height = 600 | |
const canvas = document.createElement('canvas') | |
const ctx = canvas.getContext('2d') | |
// 1. Multiply the canvas's width and height by the devicePixelRatio | |
const ratio = window.devicePixelRatio || 1 | |
canvas.width = width * ratio | |
canvas.height = height * ratio | |
// 2. Force it to display at the original (logical) size with CSS or style attributes | |
canvas.style.width = width 'px' | |
canvas.style.height = height 'px' | |
// 3. Scale the context so you can draw on it without considering the ratio. | |
ctx.scale(ratio, ratio) |
I love you.
Thank you!!
Thanks!
Couldn't find proper docs if still need/ allow to use .backingStorePixelRatio
? Seems to be deprecated? Instead, just use .devicePixelRatio
? Pls check this
Thanks! Every snippet I found was missing the "scale back down in CSS" part...
Legend, it works perfectly! Thanks!
Nice
-
I didn't pass in the width and height but grab that from within the function
-
did a check when there might not be a window (SSR)
-
call this function on resize
const devicePixelRatio = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1; // get current size of the canvas const rect = canvas.getBoundingClientRect(); // get width and height const { width, height } = rect;
Thanks, this saved me a lot of time!
If it helps anyone I did a lil' refactor in typescript also including some of @j2is changes.
Seems to me that the .backingStorePixelRatio
is deprecated(?), so I removed that as well.
function scaleCanvas(
canvas: HTMLCanvasElement,
context: CanvasRenderingContext2D,
width: number,
height: number
) {
// Handle window for SSR
if (typeof window === 'undefined') return null
// determine the actual ratio we want to draw at
const ratio = window.devicePixelRatio || 1
if (devicePixelRatio !== 1) {
// set the 'real' canvas size to the higher width/height
canvas.width = width * ratio
canvas.height = height * ratio
// ...then scale it back down with CSS
canvas.style.width = width 'px'
canvas.style.height = height 'px'
} else {
// this is a normal 1:1 device; just scale it simply
canvas.width = width
canvas.height = height
canvas.style.width = ''
canvas.style.height = ''
}
// scale the drawing context so everything will work at the higher ratio
context.scale(ratio, ratio)
}
This worked better for me because it scale the context too! :
function createHiPPICanvas(width, height) {
const ratio = window.devicePixelRatio;
const canvas = document.createElement("canvas");
canvas.width = width * ratio;
canvas.height = height * ratio;
canvas.style.width = width "px";
canvas.style.height = height "px";
canvas.getContext("2d").scale(ratio, ratio);
return canvas;
}
from https://stackoverflow.com/questions/15661339/how-do-i-fix-blurry-text-in-my-html5-canvas
Sweet. Still works. Thanks!