import {ModelViewerElement} from '@google/model-viewer'; import {$scene} from "@google/model-viewer/lib/model-viewer-base"; import {settings} from "../misc/settings.ts"; export async function setupLighting(modelViewer: ModelViewerElement) { modelViewer[$scene].environmentIntensity = (await settings()).environmentIntensity; // Code is mostly copied from the example at: https://modelviewer.dev/examples/stagingandcameras/#turnSkybox let lastX: number; let panning = false; let skyboxAngle = 0; let radiansPerPixel: number; const startPan = () => { const orbit = modelViewer.getCameraOrbit(); const {radius} = orbit; radiansPerPixel = -1 * radius / modelViewer.getBoundingClientRect().height; modelViewer.interactionPrompt = 'none'; }; const updatePan = (thisX: number) => { const delta = (thisX - lastX) * radiansPerPixel; lastX = thisX; skyboxAngle += delta; const orbit = modelViewer.getCameraOrbit(); orbit.theta += delta; modelViewer.cameraOrbit = orbit.toString(); modelViewer.resetTurntableRotation(skyboxAngle); modelViewer.jumpCameraToGoal(); } modelViewer.addEventListener('mousedown', (event) => { panning = event.metaKey || event.shiftKey; if (!panning) return; lastX = event.clientX; startPan(); event.stopPropagation(); }, true); modelViewer.addEventListener('touchstart', (event) => { const {targetTouches, touches} = event; panning = targetTouches.length === 2 && targetTouches.length === touches.length; if (!panning) return; lastX = 0.5 * (targetTouches[0].clientX + targetTouches[1].clientX); startPan(); }, true); self.addEventListener('mousemove', (event) => { if (!panning) return; updatePan(event.clientX); event.stopPropagation(); }, true); modelViewer.addEventListener('touchmove', (event) => { if (!panning || event.targetTouches.length !== 2) return; const {targetTouches} = event; const thisX = 0.5 * (targetTouches[0].clientX + targetTouches[1].clientX); updatePan(thisX); }, true); self.addEventListener('mouseup', (event) => { panning = false; }, true); modelViewer.addEventListener('touchend', (event) => { panning = false; }, true); }