Last year I made a little game: Connect Dots Offline
I did play a similar game, but it was riddled with adverts and flashy distractions to keep the dopamine flowing.
Baseline
This year I noticed that there is a stark difference in rendering quality between text in a div
and on a canvas
element on mobile browsers:
On my test device the text looked a bit blurry last year, but now it was bad. What has changed?
Well, I am not sure, but probably that the window.devicePixelRatio
changed from 2.0
to 3.1578...
with my new device.
Also switching from a plastic screen protector to a glass one "disables the natural diffuser".
Rendering at full scale
To keep the code flexible I added a scale_ratio
that is reading window.devicePixelRatio
.
Now the canvas needs to be scaled by attribute while staying the same with CSS:
width = canvas.offsetWidth;
width *= scale_ratio;
canvas.width = `${width}`;
// repeat for height as well
With CSS like this:
canvas {
width: 100%; /* all the other rules ... */
}
Nice rendering, but the events are broken now. Time to pre-process all touch and mouse input:
function screen_to_element_relative(element, clientX, clientY) {
return {
x: (clientX - element.offsetLeft) * scale_ratio,
y: (clientY - element.offsetTop) * scale_ratio,
};
}
This will be feed from Touch and Mouse Event's like this:
// TouchEvent or multi-touch
const xy = screen_to_element_relative(canvas, touch.clientX, touch.clientY);
// or MouseEvent
const xy = screen_to_element_relative(canvas, ev.clientX, ev.clientY);
2x Super Resolution
What if we increase the resolution?
This becomes simple, just add a scale_ratio * 2.0
and we are golden:
Well that makes a difference of a few pixels, but no one can actually see this by eye.
So reverting back to the native resolution and save the battery for other tasks.
With all this tuning done, enjoy Connect and consider donating a bit or invite me for a snack when we meet in real life.