I'm working on this website : sphere.mars2540.com.
Is there any way in javascript or css to force the canvas size not to scale regarding the zoom factor of the page and to constantly correspond to the real pixels of a screen (even 4k) ?
thank you
CodePudding user response:
I managed to find a total answer in the context of webgl animation with THREE.js : using this trick I detect the ratio of zoom for the device :
function detectRatio() {
var orientation=(screen.orientation || {}).type || screen.mozOrientation || screen.msOrientation;
if ("userAgentData" in window.navigator && window.navigator.userAgentData.mobile && orientation==="landscape-primary" || orientation==="landscape-secondary") {
return window.devicePixelRatio;
} else if ("userAgentData" in window.navigator && !window.navigator.userAgentData.mobile && orientation==="landscape-primary" || orientation==="landscape-secondary") {
return window.outerWidth/window.innerWidth;
} else if (orientation==="portrait-secondary" || orientation==="portrait-primary") {
return window.devicePixelRatio;
} else {
return Math.max(window.devicePixelRatio, window.outerWidth/window.innerWidth);
}
}
var ratio1=detectRatio();
Then I detect the change due to retina using this trick :
var ratio2=window.devicePixelRatio/ratio1;
Finally, I scale the canvas size with THREE.js api using for example :
renderer.setSize(width*ratio1*ratio2, height*ratio1*ratio2);
Todo -> Tada ! It's always on the max resolution.
CodePudding user response:
According to this answer it's not possible to disable page zooming, which is OK. What you can do instead and what would be actually better is to resize your canvas to match current page zoom (or actually make the canvas to be always the same size).
It's very simple, you just need to include window.devicePixelRatio
in your canvas resize calculations.
The window.devicePixelRatio
variable has value of 1
when there is no page zoom and changes on each zoom operation to match current zoom percentage.
For example to always match window dimensions you can do:
function resizeToWindow() {
canvas.width = window.innerWidth * window.devicePixelRatio;
canvas.height = window.innerHeight * window.devicePixelRatio;
}
To match parent container's size you can do:
function resizeToParent() {
canvas.width = canvas.clientWidth * window.devicePixelRatio;
canvas.height = canvas.clientHeight * window.devicePixelRatio;
}
With these or similar styles:
canvas {position: absolute; top: 0; left: 0; width: 100%; height: 100%}
The best place to detect is there need to call above functions and actually resize is to use requestAnimationFrame
and compare current canvas dimensions and devicePixelRatio
value with the values from last frame (do the check each frame, but don't resize each frame if there is no need).
Alternatively you could use the ResizeObserver API to obtain more accurate dimensions with the devicePixelContentBoxSize
property, but browser support as of today is very limited.