mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-23 03:59:30 -07:00
Merge branch 'fullscreen-kiosk-sizing'
This commit is contained in:
@@ -357,6 +357,17 @@ const isIOS = () => {
|
|||||||
let lastAppliedScale = null;
|
let lastAppliedScale = null;
|
||||||
let lastAppliedKioskMode = null;
|
let lastAppliedKioskMode = null;
|
||||||
|
|
||||||
|
// Helper function to clear CSS properties from elements
|
||||||
|
const clearElementStyles = (element, properties) => {
|
||||||
|
properties.forEach((prop) => element.style.removeProperty(prop));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define property groups for different scaling modes
|
||||||
|
const SCALING_PROPERTIES = {
|
||||||
|
wrapper: ['width', 'height', 'transform', 'transform-origin'],
|
||||||
|
positioning: ['transform', 'transform-origin', 'width', 'height', 'position', 'left', 'top', 'margin-left', 'margin-top'],
|
||||||
|
};
|
||||||
|
|
||||||
// resize the container on a page resize
|
// resize the container on a page resize
|
||||||
const resize = (force = false) => {
|
const resize = (force = false) => {
|
||||||
// Ignore resize events caused by pinch-to-zoom on mobile
|
// Ignore resize events caused by pinch-to-zoom on mobile
|
||||||
@@ -376,9 +387,8 @@ const resize = (force = false) => {
|
|||||||
// Standard scaling: fit within both dimensions
|
// Standard scaling: fit within both dimensions
|
||||||
const scale = Math.min(widthZoomPercent, heightZoomPercent);
|
const scale = Math.min(widthZoomPercent, heightZoomPercent);
|
||||||
|
|
||||||
// For Mobile Safari in kiosk mode, always use centering behavior regardless of scale
|
// Use centering behavior for fullscreen, kiosk mode, or Mobile Safari kiosk mode
|
||||||
// For other platforms, only use fullscreen/centering behavior for actual fullscreen or kiosk mode where content fits naturally
|
const isKioskLike = isFullscreen || isKioskMode || isMobileSafariKiosk;
|
||||||
const isKioskLike = isFullscreen || (isKioskMode && scale >= 1.0) || isMobileSafariKiosk;
|
|
||||||
|
|
||||||
if (debugFlag('resize') || debugFlag('fullscreen')) {
|
if (debugFlag('resize') || debugFlag('fullscreen')) {
|
||||||
console.log(`🖥️ Resize: force=${force} isKioskLike=${isKioskLike} window=${window.innerWidth}x${window.innerHeight} targetWidth=${targetWidth} widthZoom=${widthZoomPercent.toFixed(3)} heightZoom=${heightZoomPercent.toFixed(3)} finalScale=${scale.toFixed(3)} fullscreenElement=${!!document.fullscreenElement} isIOS=${isIOS()} standalone=${window.navigator.standalone} isMobileSafariKiosk=${isMobileSafariKiosk} kioskMode=${settings.kiosk?.value} wideMode=${settings.wide.value}`);
|
console.log(`🖥️ Resize: force=${force} isKioskLike=${isKioskLike} window=${window.innerWidth}x${window.innerHeight} targetWidth=${targetWidth} widthZoom=${widthZoomPercent.toFixed(3)} heightZoom=${heightZoomPercent.toFixed(3)} finalScale=${scale.toFixed(3)} fullscreenElement=${!!document.fullscreenElement} isIOS=${isIOS()} standalone=${window.navigator.standalone} isMobileSafariKiosk=${isMobileSafariKiosk} kioskMode=${settings.kiosk?.value} wideMode=${settings.wide.value}`);
|
||||||
@@ -412,40 +422,35 @@ const resize = (force = false) => {
|
|||||||
console.log('🖥️ Resetting fullscreen/kiosk styles to normal');
|
console.log('🖥️ Resetting fullscreen/kiosk styles to normal');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset wrapper styles (only properties that are actually set in fullscreen/scaling modes)
|
// Reset all scaling-related styles
|
||||||
wrapper.style.removeProperty('width');
|
const container = document.querySelector('#container');
|
||||||
wrapper.style.removeProperty('height');
|
clearElementStyles(wrapper, SCALING_PROPERTIES.wrapper);
|
||||||
wrapper.style.removeProperty('overflow');
|
clearElementStyles(container, SCALING_PROPERTIES.positioning);
|
||||||
wrapper.style.removeProperty('transform');
|
clearElementStyles(mainContainer, SCALING_PROPERTIES.positioning);
|
||||||
wrapper.style.removeProperty('transform-origin');
|
|
||||||
|
|
||||||
// Reset container styles that might have been applied during fullscreen
|
|
||||||
mainContainer.style.removeProperty('transform');
|
|
||||||
mainContainer.style.removeProperty('transform-origin');
|
|
||||||
mainContainer.style.removeProperty('width');
|
|
||||||
mainContainer.style.removeProperty('height');
|
|
||||||
mainContainer.style.removeProperty('position');
|
|
||||||
mainContainer.style.removeProperty('left');
|
|
||||||
mainContainer.style.removeProperty('top');
|
|
||||||
mainContainer.style.removeProperty('margin-left');
|
|
||||||
mainContainer.style.removeProperty('margin-top');
|
|
||||||
|
|
||||||
applyScanlineScaling(1.0);
|
applyScanlineScaling(1.0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MOBILE SCALING: Use wrapper scaling for mobile devices (but not Mobile Safari kiosk mode)
|
// MOBILE SCALING: Use wrapper scaling for mobile devices (but not when in fullscreen/kiosk mode)
|
||||||
if ((scale < 1.0 || (isKioskMode && !isKioskLike)) && !isMobileSafariKiosk) {
|
if ((scale < 1.0 || (isKioskMode && !isKioskLike)) && !isMobileSafariKiosk && !isKioskLike) {
|
||||||
/*
|
/*
|
||||||
* MOBILE SCALING (Wrapper Scaling)
|
* MOBILE SCALING (Wrapper Scaling)
|
||||||
*
|
*
|
||||||
|
* This path is used for regular mobile browsing (NOT fullscreen/kiosk modes).
|
||||||
* Why scale the wrapper instead of mainContainer?
|
* Why scale the wrapper instead of mainContainer?
|
||||||
* - For mobile devices where content is larger than viewport, we need to scale the entire layout
|
* - For mobile devices where content is larger than viewport, we need to scale the entire layout
|
||||||
* - The wrapper (#divTwc) contains both the main content AND the bottom navigation bar
|
* - The wrapper (#divTwc) contains both the main content AND the bottom navigation bar
|
||||||
* - Scaling the wrapper ensures both elements are scaled together as a unit
|
* - Scaling the wrapper ensures both elements are scaled together as a unit
|
||||||
* - No centering is applied - content aligns to top-left for typical mobile behavior
|
* - Content aligns to top-left for typical mobile web browsing behavior (no centering)
|
||||||
* - Uses explicit dimensions to prevent layout issues and eliminate gaps after scaling
|
* - Uses explicit dimensions to prevent layout issues and eliminate gaps after scaling
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Reset any container/mainContainer styles that might have been set during fullscreen/kiosk mode
|
||||||
|
const container = document.querySelector('#container');
|
||||||
|
clearElementStyles(container, SCALING_PROPERTIES.positioning);
|
||||||
|
clearElementStyles(mainContainer, SCALING_PROPERTIES.positioning);
|
||||||
|
|
||||||
wrapper.style.setProperty('transform', `scale(${scale})`);
|
wrapper.style.setProperty('transform', `scale(${scale})`);
|
||||||
wrapper.style.setProperty('transform-origin', 'top left'); // Scale from top-left corner
|
wrapper.style.setProperty('transform-origin', 'top left'); // Scale from top-left corner
|
||||||
|
|
||||||
@@ -458,7 +463,7 @@ const resize = (force = false) => {
|
|||||||
const scaledHeight = totalHeight * scale; // Height after scaling
|
const scaledHeight = totalHeight * scale; // Height after scaling
|
||||||
|
|
||||||
wrapper.style.setProperty('width', `${wrapperWidth}px`);
|
wrapper.style.setProperty('width', `${wrapperWidth}px`);
|
||||||
wrapper.style.setProperty('height', `${scaledHeight}px`); // Use scaled height to eliminate gap
|
wrapper.style.setProperty('height', `${scaledHeight}px`); // Use scaled height to eliminate gap under #divTwc on index page
|
||||||
applyScanlineScaling(scale);
|
applyScanlineScaling(scale);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -468,10 +473,7 @@ const resize = (force = false) => {
|
|||||||
const wrapperHeight = 480;
|
const wrapperHeight = 480;
|
||||||
|
|
||||||
// Reset wrapper styles to avoid double scaling (wrapper remains unstyled)
|
// Reset wrapper styles to avoid double scaling (wrapper remains unstyled)
|
||||||
wrapper.style.removeProperty('width');
|
clearElementStyles(wrapper, SCALING_PROPERTIES.wrapper);
|
||||||
wrapper.style.removeProperty('height');
|
|
||||||
wrapper.style.removeProperty('transform');
|
|
||||||
wrapper.style.removeProperty('transform-origin');
|
|
||||||
|
|
||||||
// Platform-specific positioning logic
|
// Platform-specific positioning logic
|
||||||
let transformOrigin;
|
let transformOrigin;
|
||||||
@@ -529,7 +531,7 @@ const resize = (force = false) => {
|
|||||||
const offsetY = (window.innerHeight - scaledHeight) / 2;
|
const offsetY = (window.innerHeight - scaledHeight) / 2;
|
||||||
|
|
||||||
if (debugFlag('fullscreen')) {
|
if (debugFlag('fullscreen')) {
|
||||||
console.log(`🖥️ Applying fullscreen/kiosk scaling: wrapper=${wrapperWidth}x${wrapperHeight} scale=${scale.toFixed(3)} offset=${offsetX.toFixed(1)},${offsetY.toFixed(1)} transform: scale(${scale}) translate(${offsetX / scale}px, ${offsetY / scale}px)`);
|
console.log(`🖥️ Applying fullscreen/kiosk scaling: wrapper=${wrapperWidth}x${wrapperHeight} scale=${scale.toFixed(3)} offset=${offsetX.toFixed(1)},${offsetY.toFixed(1)} target=${isFullscreen ? '#container' : '#divTwcMain'}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set positioning values for CSS-based centering
|
// Set positioning values for CSS-based centering
|
||||||
@@ -540,25 +542,39 @@ const resize = (force = false) => {
|
|||||||
marginTop = `-${wrapperHeight / 2}px`; // Pull back by half height
|
marginTop = `-${wrapperHeight / 2}px`; // Pull back by half height
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply shared mainContainer properties (same for both kiosk modes)
|
// Chrome fullscreen compatibility: apply transform to #container instead of #divTwcMain
|
||||||
mainContainer.style.setProperty('transform', `scale(${scale})`, 'important');
|
// This works around Chrome's restriction on styling fullscreen elements directly
|
||||||
mainContainer.style.setProperty('transform-origin', transformOrigin, 'important');
|
const container = document.querySelector('#container');
|
||||||
mainContainer.style.setProperty('width', `${wrapperWidth}px`, 'important');
|
const targetElement = isFullscreen ? container : mainContainer;
|
||||||
mainContainer.style.setProperty('height', `${wrapperHeight}px`, 'important');
|
|
||||||
mainContainer.style.setProperty('position', 'absolute', 'important');
|
// Reset the other element's styles to avoid conflicts
|
||||||
mainContainer.style.setProperty('left', leftPosition, 'important');
|
if (isFullscreen) {
|
||||||
mainContainer.style.setProperty('top', topPosition, 'important');
|
// Reset mainContainer styles when using container for fullscreen
|
||||||
|
clearElementStyles(mainContainer, SCALING_PROPERTIES.positioning);
|
||||||
|
} else {
|
||||||
|
// Reset container styles when using mainContainer for kiosk mode
|
||||||
|
clearElementStyles(container, SCALING_PROPERTIES.positioning);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply shared properties to the target element
|
||||||
|
targetElement.style.setProperty('transform', `scale(${scale})`, 'important');
|
||||||
|
targetElement.style.setProperty('transform-origin', transformOrigin, 'important');
|
||||||
|
targetElement.style.setProperty('width', `${wrapperWidth}px`, 'important');
|
||||||
|
targetElement.style.setProperty('height', `${wrapperHeight}px`, 'important');
|
||||||
|
targetElement.style.setProperty('position', 'absolute', 'important');
|
||||||
|
targetElement.style.setProperty('left', leftPosition, 'important');
|
||||||
|
targetElement.style.setProperty('top', topPosition, 'important');
|
||||||
|
|
||||||
// Apply or clear margin properties based on positioning method
|
// Apply or clear margin properties based on positioning method
|
||||||
if (marginLeft !== null) {
|
if (marginLeft !== null) {
|
||||||
mainContainer.style.setProperty('margin-left', marginLeft, 'important');
|
targetElement.style.setProperty('margin-left', marginLeft, 'important');
|
||||||
} else {
|
} else {
|
||||||
mainContainer.style.removeProperty('margin-left');
|
targetElement.style.removeProperty('margin-left');
|
||||||
}
|
}
|
||||||
if (marginTop !== null) {
|
if (marginTop !== null) {
|
||||||
mainContainer.style.setProperty('margin-top', marginTop, 'important');
|
targetElement.style.setProperty('margin-top', marginTop, 'important');
|
||||||
} else {
|
} else {
|
||||||
mainContainer.style.removeProperty('margin-top');
|
targetElement.style.removeProperty('margin-top');
|
||||||
}
|
}
|
||||||
|
|
||||||
applyScanlineScaling(scale);
|
applyScanlineScaling(scale);
|
||||||
|
|||||||
Reference in New Issue
Block a user