Skip to content
52 changes: 51 additions & 1 deletion src/core/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ p5.prototype.getFrameRate = function() {

/**
* Specifies the number of frames to be displayed every second. For example,
* the function call frameRate(30) will attempt to refresh 30 times a second.
* the function call `frameRate(30)` will attempt to refresh 30 times a second.
* If the processor is not fast enough to maintain the specified rate, the
* frame rate will not be achieved. Setting the frame rate within <a href="#/p5/setup">setup()</a> is
* recommended. The default rate is 60 frames per second.
Expand Down Expand Up @@ -782,7 +782,39 @@ p5.prototype._onresize = function(e) {
}
};

// Prefer the visual viewport when available (better for mobile: pinch/keyboard/zoom),
// then the layout viewport, then the window inner size, then the body content size.
// Order chosen intentionally:
// 1) window.visualViewport.* -> visual viewport (mobile-friendly; adapts to on-screen keyboard)
// 2) document.documentElement.client* -> layout viewport (avoids including scrollbars on some platforms)
// 3) window.inner* -> includes scrollbars on some platforms (Chrome)
// 4) document.body.client* -> content-box fallback if the above are unavailable
// Caveat: different browsers expose subtly different viewport measurements (scrollbars, zoom,
// and visual viewport). This ordering prefers mobile-friendly measurements while retaining
// sensible fallbacks for desktop browsers.
function getWindowWidth() {
// Prefer including scrollbars when possible per contributor guidance.
// Order: experimental visualViewport.segments (may include scrollbars/handle rotation),
// visualViewport.width, window.innerWidth (includes scrollbars),
// documentElement.clientWidth (excludes scrollbars), document.body.clientWidth.
try {
if (window.visualViewport) {
const segs = window.visualViewport.segments;
if (Array.isArray(segs) && segs.length > 0) {
const w = segs[0] && typeof segs[0].width === 'number' ? segs[0].width : null;
if (w && w > 0) {
return w;
}
}

// if (typeof window.visualViewport.width === 'number' && window.visualViewport.width > 0) {
// return window.visualViewport.width;
// }
}
} catch (e) {
// experimental access may throw; ignore and continue with fallbacks
}

return (
window.innerWidth ||
Comment on lines +785 to 819

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extra visualViewport.segments part and the try/catch around it aren't really needed for this, which isn't what this bug is about. There are also a few commented-out lines left in getWindowWidth/getWindowHeight that we can remove to keep things tidy.

So it could come down to just this one line:

(document.documentElement && document.documentElement.clientWidth) || window.innerWidth || (document.body && document.body.clientWidth) || 0

(document.documentElement && document.documentElement.clientWidth) ||
Expand All @@ -792,6 +824,24 @@ function getWindowWidth() {
}

function getWindowHeight() {
try {
if (window.visualViewport) {
const segs = window.visualViewport.segments;
if (Array.isArray(segs) && segs.length > 0) {
const h = segs[0] && typeof segs[0].height === 'number' ? segs[0].height : null;
if (h && h > 0) {
return h;
}
}

// if (typeof window.visualViewport.height === 'number' && window.visualViewport.height > 0) {
// return window.visualViewport.height;
// }
}
} catch (e) {
// experimental access may throw; ignore and continue with fallbacks
}

return (
window.innerHeight ||
(document.documentElement && document.documentElement.clientHeight) ||
Expand Down
Loading