Files
yet-another-cad-viewer/frontend/viewer/lighting.ts

75 lines
2.4 KiB
TypeScript

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);
}