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

Jump to navigation Jump to search
No edit summary
No edit summary
Line 5: Line 5:
     const HQ_ICON = '/images/1/10/HQ_icon.png';
     const HQ_ICON = '/images/1/10/HQ_icon.png';


     function getSize(wrapper) {
     function getSize(element) {
         const match = wrapper.className.match(/model_size_(\d+)/);
         const match = element.className.match(/model_size_(\d+)/);
         return match ? parseInt(match[1], 10) : 500;
         return match ? parseInt(match[1], 10) : 500;
    }
    function updateViewerSize(viewer, wrapper) {
        const size = getSize(wrapper);
        viewer.style.width = size + 'px';
        viewer.style.height = size + 'px';
    }
    function updateQualityButtonSize(button, wrapper) {
        const size = getSize(wrapper);
        const buttonSize = Math.max(28, Math.min(56, Math.round(size * 0.14)));
        button.style.width = buttonSize + 'px';
        button.style.height = buttonSize + 'px';
     }
     }


Line 36: Line 20:


         return fetch(apiUrl)
         return fetch(apiUrl)
             .then(function (response) {
             .then(response => response.json())
                return response.json();
             .then(data => {
            })
             .then(function (data) {
                 const page = Object.values(data.query.pages)[0];
                 const page = Object.values(data.query.pages)[0];


Line 50: Line 32:
     }
     }


     function addQualityButton(wrapper, viewer, lqUrl, hqUrl) {
     function addQualityButton(container, viewer, lqUrl, hqUrl) {
         if (!hqUrl || lqUrl === hqUrl) {
         if (!hqUrl || lqUrl === hqUrl) {
             return;
             return;
Line 58: Line 40:
         button.className = 'mv-quality-toggle';
         button.className = 'mv-quality-toggle';
         button.type = 'button';
         button.type = 'button';
        updateQualityButtonSize(button, wrapper);


         const icon = document.createElement('img');
         const icon = document.createElement('img');
Line 66: Line 46:


         button.appendChild(icon);
         button.appendChild(icon);
        const buttonSize = Math.max(
            28,
            Math.min(56, Math.round(container.offsetWidth * 0.14))
        );
        button.style.width = buttonSize + 'px';
        button.style.height = buttonSize + 'px';


         button.addEventListener('click', function () {
         button.addEventListener('click', function () {
Line 74: Line 62:
         });
         });


         wrapper.appendChild(button);
         container.appendChild(button);
     }
     }


     function loadModel(wrapper) {
     function loadModel(preview) {
         if (wrapper.dataset.loaded) {
         if (preview.dataset.loaded) {
             return;
             return;
         }
         }


         wrapper.dataset.loaded = '1';
         preview.dataset.loaded = '1';
 
        const fileName = preview.dataset.model;
        const size = getSize(preview);


         Promise.all([
         Promise.all([
             getFileUrl(wrapper.dataset.lq),
             getFileUrl(fileName + '-compressed.glb'),
             getFileUrl(wrapper.dataset.hq)
             getFileUrl(fileName + '.glb')
         ]).then(function (urls) {
         ]).then(function (urls) {
             const lqUrl = urls[0] || urls[1];
             const lqUrl = urls[0] || urls[1];
             const hqUrl = urls[1];
             const hqUrl = urls[1];
Line 96: Line 86:
             }
             }


             wrapper.innerHTML = '';
             const container = document.createElement('div');
            container.className = 'model-viewer-container';
 
            container.style.width = size + 'px';
            container.style.height = size + 'px';


             const viewer = document.createElement('model-viewer');
             const viewer = document.createElement('model-viewer');


             viewer.src = lqUrl;
             viewer.src = lqUrl;
             viewer.setAttribute('camera-controls', '');
             viewer.setAttribute('camera-controls', '');
             viewer.setAttribute('touch-action', 'pan-y');
             viewer.setAttribute('touch-action', 'pan-y');
            viewer.setAttribute('loading', 'lazy');


             updateViewerSize(viewer, wrapper);
             container.appendChild(viewer);
 
             preview.replaceWith(container);
             wrapper.appendChild(viewer);


             viewer.addEventListener('load', function () {
             viewer.addEventListener('load', function () {
                 addQualityButton(wrapper, viewer, lqUrl, hqUrl);
                 addQualityButton(
                    container,
                    viewer,
                    lqUrl,
                    hqUrl
                );
             });
             });
         });
         });
     }
     }


     function initPlaceholder(wrapper) {
     function initPreview(preview) {
         if (wrapper.dataset.initialized) {
         if (preview.dataset.initialized) {
             return;
             return;
         }
         }


         wrapper.dataset.initialized = '1';
         preview.dataset.initialized = '1';
 
        wrapper.style.position = 'relative';


         const button = document.createElement('button');
         const button = document.createElement('button');


        button.className = 'model-load-button';
         button.type = 'button';
         button.type = 'button';
        button.className = 'model-load-button';
button.className = 'model-load-button';
button.type = 'button';


         button.addEventListener('click', function () {
         button.addEventListener('click', function () {
             loadModel(wrapper);
             loadModel(preview);
         });
         });


         wrapper.appendChild(button);
         preview.appendChild(button);
     }
     }


     function scan() {
     function scan() {
         document
         document
             .querySelectorAll('.model-placeholder')
             .querySelectorAll('.model-preview')
             .forEach(initPlaceholder);
             .forEach(initPreview);
     }
     }


Line 152: Line 142:
         childList: true,
         childList: true,
         subtree: true
         subtree: true
    });
    window.addEventListener('resize', function () {
        document.querySelectorAll('model-viewer').forEach(function (viewer) {
            const wrapper = viewer.closest('.model-placeholder');
            if (!wrapper) {
                return;
            }
            updateViewerSize(viewer, wrapper);
            const button = wrapper.querySelector('.mv-quality-toggle');
            if (button) {
                updateQualityButtonSize(button, wrapper);
            }
        });
     });
     });