jspaint icon indicating copy to clipboard operation
jspaint copied to clipboard

Dev need help on zoom

Open Meta-Ben opened this issue 3 years ago • 7 comments

I try to to a paint app for a school project but im stick on the zoom I don't understand in your code how you manage to do a pixel perfect zoom

Can you help me please ? 😄

Thanks in advance !!

Meta-Ben avatar Aug 14 '21 20:08 Meta-Ben

One important thing to note is that on some screens, a CSS pixel is not a device pixel, and so you have to use window.devicePixelRatio if you want a canvas element to line up with device pixels exactly. If you explain further what you're trying to do and where you're struggling I can probably help.

1j01 avatar Aug 29 '21 13:08 1j01

Hello Thanks for the response ! 😄

I tried to get a pixel grid as you had in your paint.js

like If I use the magnifier I get bigger pixel and my paint draw bigger square ( to represent one pixel on the grid )

I manage to use brensendham algoritm to get the pixel line drawing but not to zoom on it

Its more clear ? Don't hesitate if you need more information and thanks for helping 😄

Meta-Ben avatar Aug 30 '21 14:08 Meta-Ben

Zooming is done by setting the visual dimensions (canvas.style.width/height) differently to the resolution of the canvas (canvas.width/height).

canvas.style.width = canvas.width * magnification;
canvas.style.height = canvas.height * magnification;

By default this will be blurry; to get crisp squares you need to style the canvas also with image-rendering

canvas.style.imageRendering = "pixelated";

But note that on High-DPI screens, there is a pixel scaling applied to make content a reasonable size, and it's not always an integer scale. This scale is available as devicePixelRatio. If the canvas is scaled by a non-integer, when factoring in devicePixelRatio and magnification, then image-rendering of pixelated will give ugly non-square pixels. I don't handle this properly in jspaint yet. You might want something like:

if ((magnification * devicePixelRatio == Math.floor(magnification * devicePixelRatio))) {
    canvas.style.imageRendering = "pixelated";
} else {
    canvas.style.imageRendering = ""; // defaults to smooth
}

See also High DPI Canvas - HTML5 Rocks

1j01 avatar Sep 02 '21 17:09 1j01

Thanks very much for these informations ! I will try it asap and let you know if it work of course if you want to see the final project let me know I will gladly share it with you

Meta-Ben avatar Sep 04 '21 23:09 Meta-Ben

Thanks its work very well I just forgot to set pixel style as "px" at the end... Also my cursor had now an offset with my line have you an idea ?

Meta-Ben avatar Sep 05 '21 12:09 Meta-Ben

You'll have to divide the mouse coordinates by the magnification, after subtracting the top-left of the canvas.

var rect = canvas.getBoundingClientRect();
var mouseX = (event.clientX - rect.left) / magnification;
var mouseY = (event.clientY - rect.top) / magnification;

maybe divide by devicePixelRatio too (Sorry if this reply is too late, maybe you already figured it out.)

1j01 avatar Sep 15 '21 16:09 1j01

Oh okay thanks No really no problem its really nice to you to helping me ! since I'm working I not have much time to think about this problem so don't worry

I will try that asap :)

Thanks very much again :)

Meta-Ben avatar Sep 17 '21 11:09 Meta-Ben