User:Monster Domosed/common.js: Difference between revisions

Jump to navigation Jump to search
No edit summary
No edit summary
Line 18: Line 18:
     }
     }


    function updateButtonSize(button, wrapper) {
        const match = wrapper.className.match(/model_size_(\d+)/);
        if (!match) {
            return;
        }
        const size = parseInt(match[1], 10);
        // 14% of viewer size, minimum 28px, maximum 56px
        const buttonSize = Math.max(28, Math.min(56, Math.round(size * 0.14)));
        button.style.width = buttonSize + 'px';
        button.style.height = buttonSize + 'px';
    }


     function getHQUrl(fileName) {
     function getHQUrl(fileName) {
Line 45: Line 60:
     }
     }


    function switchQuality(viewer, icon, lqUrl, hqUrl) {
        const isLQ = viewer.src === lqUrl;


function switchQuality(viewer, icon, lqUrl, hqUrl) {
        const orbit = viewer.getCameraOrbit();
    const isLQ = viewer.src === lqUrl;
        const target = viewer.getCameraTarget();
        const fov = viewer.getFieldOfView();


    const orbit = viewer.getCameraOrbit();
        const oldTime = viewer.currentTime;
    const target = viewer.getCameraTarget();
        const oldAnimation = viewer.animationName;
    const fov = viewer.getFieldOfView();


    const oldTime = viewer.currentTime;
        viewer.setAttribute('camera-controls', 'false');
    const oldAnimation = viewer.animationName;


    viewer.setAttribute('camera-controls', 'false');
        let restored = false;


    let restored = false;
        function restoreCamera() {
            if (restored) {
                return;
            }


    function restoreCamera() {
            restored = true;
        if (restored) {
            return;
        }


        restored = true;
            requestAnimationFrame(function () {
                viewer.cameraOrbit =
                    orbit.theta + 'rad ' +
                    orbit.phi + 'rad ' +
                    orbit.radius + 'm';


        requestAnimationFrame(function () {
                viewer.cameraTarget =
            viewer.cameraOrbit =
                    target.x + 'm ' +
                orbit.theta + 'rad ' +
                    target.y + 'm ' +
                orbit.phi + 'rad ' +
                    target.z + 'm';
                orbit.radius + 'm';


            viewer.cameraTarget =
                viewer.fieldOfView = fov;
                target.x + 'm ' +
                target.y + 'm ' +
                target.z + 'm';


            viewer.fieldOfView = fov;
                if (oldAnimation) {
                    viewer.animationName = oldAnimation;
                }


            if (oldAnimation) {
                if (typeof oldTime === 'number') {
                viewer.animationName = oldAnimation;
                    viewer.currentTime = oldTime;
            }
                }


            if (typeof oldTime === 'number') {
                requestAnimationFrame(function () {
                viewer.currentTime = oldTime;
                    viewer.setAttribute('camera-controls', '');
            }


            requestAnimationFrame(function () {
                    if (viewer.hasAttribute('autoplay')) {
                viewer.setAttribute('camera-controls', '');
                        viewer.play();
                    }
                });
            });
        }


                if (viewer.hasAttribute('autoplay')) {
        viewer.addEventListener('load', restoreCamera, {
                    viewer.play();
             once: true
                }
             });
         });
         });
    }


    viewer.addEventListener('load', restoreCamera, {
         viewer.src = isLQ ? hqUrl : lqUrl;
         once: true
    });
 
    viewer.src = isLQ ? hqUrl : lqUrl;
 
    icon.src = isLQ ? HQ_ICON : LQ_ICON;
}


        icon.src = isLQ ? HQ_ICON : LQ_ICON;
    }


     function initViewer(viewer) {
     function initViewer(viewer) {
Line 128: Line 141:


         updateViewerSize(viewer, wrapper);
         updateViewerSize(viewer, wrapper);


         const fileMatch = src.match(/\/([^\/]+)-compressed\.glb$/);
         const fileMatch = src.match(/\/([^\/]+)-compressed\.glb$/);
Line 137: Line 149:


         const baseName = fileMatch[1];
         const baseName = fileMatch[1];


         getHQUrl(baseName)
         getHQUrl(baseName)
Line 145: Line 156:
                     return;
                     return;
                 }
                 }


                 const container = document.createElement('div');
                 const container = document.createElement('div');
Line 152: Line 162:
                 viewer.parentNode.insertBefore(container, viewer);
                 viewer.parentNode.insertBefore(container, viewer);
                 container.appendChild(viewer);
                 container.appendChild(viewer);


                 const button = document.createElement('button');
                 const button = document.createElement('button');
Line 158: Line 167:
                 button.type = 'button';
                 button.type = 'button';


                updateButtonSize(button, wrapper);


                 const icon = document.createElement('img');
                 const icon = document.createElement('img');
                 icon.src = LQ_ICON;
                 icon.src = LQ_ICON;
                 icon.alt = '';
                 icon.alt = '';


                 button.appendChild(icon);
                 button.appendChild(icon);
                 container.appendChild(button);
                 container.appendChild(button);


                 button.addEventListener('click', function () {
                 button.addEventListener('click', function () {
Line 179: Line 187:
             });
             });
     }
     }


     function scan() {
     function scan() {
         document.querySelectorAll('model-viewer').forEach(initViewer);
         document.querySelectorAll('model-viewer').forEach(initViewer);
     }
     }


     scan();
     scan();


     const observer = new MutationObserver(function () {
     const observer = new MutationObserver(function () {
         scan();
         scan();
     });
     });


     observer.observe(document.body, {
     observer.observe(document.body, {
Line 198: Line 202:
         subtree: true
         subtree: true
     });
     });


     window.addEventListener('resize', function () {
     window.addEventListener('resize', function () {
Line 204: Line 207:
             const wrapper = viewer.closest('[class*="model_size_"]');
             const wrapper = viewer.closest('[class*="model_size_"]');


             if (wrapper) {
             if (!wrapper) {
                 updateViewerSize(viewer, wrapper);
                 return;
            }
 
            updateViewerSize(viewer, wrapper);
 
            const button = viewer.parentNode.querySelector('.mv-quality-toggle');
 
            if (button) {
                updateButtonSize(button, wrapper);
             }
             }
         });
         });
Line 211: Line 222:


})();
})();