mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-11 05:42:22 +00:00
Move Ctrl+wheel and trackpad pinch zoom into the Cesium renderer
installTrackpadPinchZoom and its pinch scaling move unchanged from src/app/viewer.js to src/render/cesium/ctrlWheelZoom.js, where the input port's ctrlWheelZoom will turn it on and off. The application scene imports it from there; the application/viewer export no longer carries this undocumented helper.
This commit is contained in:
1 parent
60a3a2808e
commit
21f284f79c
6 files changed
+112
-103
No files matched your search
@@ -50,6 +50,7 @@
|
|||||||
"src/queries/heights.js",
|
"src/queries/heights.js",
|
||||||
"src/render/cesium/internals.js",
|
"src/render/cesium/internals.js",
|
||||||
"src/render/cesium/cameraInput.js",
|
"src/render/cesium/cameraInput.js",
|
||||||
|
"src/render/cesium/ctrlWheelZoom.js",
|
||||||
"src/render/cesium/cameraInput.test.mjs",
|
"src/render/cesium/cameraInput.test.mjs",
|
||||||
"src/render/input/router.js",
|
"src/render/input/router.js",
|
||||||
"src/render/input/router.test.mjs",
|
"src/render/input/router.test.mjs",
|
||||||
|
|||||||
@@ -2448,6 +2448,7 @@
|
|||||||
"src/app/surfaceServices.js",
|
"src/app/surfaceServices.js",
|
||||||
"src/app/tools.js",
|
"src/app/tools.js",
|
||||||
"src/app/viewer.js",
|
"src/app/viewer.js",
|
||||||
|
"src/render/cesium/ctrlWheelZoom.js",
|
||||||
"src/sky/starrySky.js",
|
"src/sky/starrySky.js",
|
||||||
"src/sky/stars.js",
|
"src/sky/stars.js",
|
||||||
"src/app/atmosphereCompat.js",
|
"src/app/atmosphereCompat.js",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import test from 'node:test';
|
|||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import { spawnSync } from 'node:child_process';
|
import { spawnSync } from 'node:child_process';
|
||||||
import { createApplication } from './application.js';
|
import { createApplication } from './application.js';
|
||||||
import { installTrackpadPinchZoom } from './viewer.js';
|
import { installTrackpadPinchZoom } from '../render/cesium/ctrlWheelZoom.js';
|
||||||
|
|
||||||
const phases = ['Scene', 'Controls', 'Data', 'Tools'];
|
const phases = ['Scene', 'Controls', 'Data', 'Tools'];
|
||||||
function fixture(overrides = {}) {
|
function fixture(overrides = {}) {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { createApplicationOperations } from './operations.js';
|
import { createApplicationOperations } from './operations.js';
|
||||||
import * as Cesium from 'cesium';
|
import * as Cesium from 'cesium';
|
||||||
import { installTrackpadPinchZoom } from '../app/viewer.js';
|
import { installTrackpadPinchZoom } from '../render/cesium/ctrlWheelZoom.js';
|
||||||
import {
|
import {
|
||||||
cesiumRenderer,
|
cesiumRenderer,
|
||||||
cesiumViewerOf,
|
cesiumViewerOf,
|
||||||
|
|||||||
@@ -2,107 +2,6 @@ import * as Cesium from 'cesium';
|
|||||||
import { applyModelAtmosphereWorkaround } from './atmosphereCompat.js';
|
import { applyModelAtmosphereWorkaround } from './atmosphereCompat.js';
|
||||||
import { StarrySky } from '../sky/starrySky.js';
|
import { StarrySky } from '../sky/starrySky.js';
|
||||||
|
|
||||||
const PINCH_ZOOM_MULTIPLIER = 8;
|
|
||||||
const MAX_PINCH_PIXEL_DELTA = 120;
|
|
||||||
|
|
||||||
function boundedPinchDelta(delta) {
|
|
||||||
if (!Number.isFinite(delta) || delta === 0) return delta;
|
|
||||||
return (
|
|
||||||
Math.sign(delta) *
|
|
||||||
Math.min(Math.abs(delta) * PINCH_ZOOM_MULTIPLIER, MAX_PINCH_PIXEL_DELTA)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add browser trackpad pinch to Cesium's zoom inputs and return its disposer.
|
|
||||||
* Browsers expose this gesture as a small pixel-mode Ctrl+wheel event.
|
|
||||||
*/
|
|
||||||
export function installTrackpadPinchZoom(
|
|
||||||
viewer,
|
|
||||||
{ createWheelEvent = (type, init) => new WheelEvent(type, init) } = {},
|
|
||||||
) {
|
|
||||||
const controller = viewer?.scene?.screenSpaceCameraController;
|
|
||||||
const container = viewer?.container;
|
|
||||||
const canvas = viewer?.canvas;
|
|
||||||
if (!controller || !container || !canvas)
|
|
||||||
throw new TypeError('A complete Cesium viewer is required');
|
|
||||||
|
|
||||||
const originalZoomEventTypes = controller.zoomEventTypes;
|
|
||||||
const zoomEventTypes = Array.isArray(originalZoomEventTypes)
|
|
||||||
? originalZoomEventTypes
|
|
||||||
: originalZoomEventTypes === undefined
|
|
||||||
? []
|
|
||||||
: [originalZoomEventTypes];
|
|
||||||
const alreadyHandlesControlWheel = zoomEventTypes.some(
|
|
||||||
(binding) =>
|
|
||||||
binding?.eventType === Cesium.CameraEventType.WHEEL &&
|
|
||||||
binding?.modifier === Cesium.KeyboardEventModifier.CTRL,
|
|
||||||
);
|
|
||||||
const configuredZoomEventTypes = alreadyHandlesControlWheel
|
|
||||||
? originalZoomEventTypes
|
|
||||||
: [
|
|
||||||
...zoomEventTypes,
|
|
||||||
{
|
|
||||||
eventType: Cesium.CameraEventType.WHEEL,
|
|
||||||
modifier: Cesium.KeyboardEventModifier.CTRL,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
if (!alreadyHandlesControlWheel)
|
|
||||||
controller.zoomEventTypes = configuredZoomEventTypes;
|
|
||||||
|
|
||||||
const relayedEvents = new WeakSet();
|
|
||||||
const relayPinch = (event) => {
|
|
||||||
if (
|
|
||||||
!event.ctrlKey ||
|
|
||||||
relayedEvents.has(event) ||
|
|
||||||
event.deltaMode !== 0 ||
|
|
||||||
!Number.isFinite(event.deltaY) ||
|
|
||||||
event.deltaY === 0
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
let relayed;
|
|
||||||
try {
|
|
||||||
relayed = createWheelEvent('wheel', {
|
|
||||||
deltaX: event.deltaX,
|
|
||||||
deltaY: boundedPinchDelta(event.deltaY),
|
|
||||||
deltaZ: event.deltaZ,
|
|
||||||
deltaMode: event.deltaMode,
|
|
||||||
screenX: event.screenX,
|
|
||||||
screenY: event.screenY,
|
|
||||||
clientX: event.clientX,
|
|
||||||
clientY: event.clientY,
|
|
||||||
ctrlKey: true,
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true,
|
|
||||||
view: globalThis.window,
|
|
||||||
});
|
|
||||||
} catch {
|
|
||||||
// The registered Ctrl+wheel binding can still consume the original.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
relayedEvents.add(relayed);
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
canvas.dispatchEvent(relayed);
|
|
||||||
};
|
|
||||||
container.addEventListener('wheel', relayPinch, {
|
|
||||||
capture: true,
|
|
||||||
passive: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
let active = true;
|
|
||||||
return () => {
|
|
||||||
if (!active) return;
|
|
||||||
active = false;
|
|
||||||
container.removeEventListener('wheel', relayPinch, true);
|
|
||||||
if (
|
|
||||||
!alreadyHandlesControlWheel &&
|
|
||||||
controller.zoomEventTypes === configuredZoomEventTypes
|
|
||||||
)
|
|
||||||
controller.zoomEventTypes = originalZoomEventTypes;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cesium.Viewer options of the standard globe viewer. */
|
/** Cesium.Viewer options of the standard globe viewer. */
|
||||||
export function applicationViewerOptions(creditContainer) {
|
export function applicationViewerOptions(creditContainer) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* @module render/cesium/ctrlWheelZoom
|
||||||
|
* @description Ctrl+wheel zoom on a Cesium scene: a Ctrl+wheel binding among
|
||||||
|
* the camera controller's zoom inputs, and browser trackpad pinches (small
|
||||||
|
* pixel-mode Ctrl+wheel events) relayed at a usable speed.
|
||||||
|
*/
|
||||||
|
import * as Cesium from 'cesium';
|
||||||
|
|
||||||
|
const PINCH_ZOOM_MULTIPLIER = 8;
|
||||||
|
const MAX_PINCH_PIXEL_DELTA = 120;
|
||||||
|
|
||||||
|
function boundedPinchDelta(delta) {
|
||||||
|
if (!Number.isFinite(delta) || delta === 0) return delta;
|
||||||
|
return (
|
||||||
|
Math.sign(delta) *
|
||||||
|
Math.min(Math.abs(delta) * PINCH_ZOOM_MULTIPLIER, MAX_PINCH_PIXEL_DELTA)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add browser trackpad pinch to Cesium's zoom inputs and return its disposer.
|
||||||
|
* Browsers expose this gesture as a small pixel-mode Ctrl+wheel event.
|
||||||
|
*/
|
||||||
|
export function installTrackpadPinchZoom(
|
||||||
|
viewer,
|
||||||
|
{ createWheelEvent = (type, init) => new WheelEvent(type, init) } = {},
|
||||||
|
) {
|
||||||
|
const controller = viewer?.scene?.screenSpaceCameraController;
|
||||||
|
const container = viewer?.container;
|
||||||
|
const canvas = viewer?.canvas;
|
||||||
|
if (!controller || !container || !canvas)
|
||||||
|
throw new TypeError('A complete Cesium viewer is required');
|
||||||
|
|
||||||
|
const originalZoomEventTypes = controller.zoomEventTypes;
|
||||||
|
const zoomEventTypes = Array.isArray(originalZoomEventTypes)
|
||||||
|
? originalZoomEventTypes
|
||||||
|
: originalZoomEventTypes === undefined
|
||||||
|
? []
|
||||||
|
: [originalZoomEventTypes];
|
||||||
|
const alreadyHandlesControlWheel = zoomEventTypes.some(
|
||||||
|
(binding) =>
|
||||||
|
binding?.eventType === Cesium.CameraEventType.WHEEL &&
|
||||||
|
binding?.modifier === Cesium.KeyboardEventModifier.CTRL,
|
||||||
|
);
|
||||||
|
const configuredZoomEventTypes = alreadyHandlesControlWheel
|
||||||
|
? originalZoomEventTypes
|
||||||
|
: [
|
||||||
|
...zoomEventTypes,
|
||||||
|
{
|
||||||
|
eventType: Cesium.CameraEventType.WHEEL,
|
||||||
|
modifier: Cesium.KeyboardEventModifier.CTRL,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (!alreadyHandlesControlWheel)
|
||||||
|
controller.zoomEventTypes = configuredZoomEventTypes;
|
||||||
|
|
||||||
|
const relayedEvents = new WeakSet();
|
||||||
|
const relayPinch = (event) => {
|
||||||
|
if (
|
||||||
|
!event.ctrlKey ||
|
||||||
|
relayedEvents.has(event) ||
|
||||||
|
event.deltaMode !== 0 ||
|
||||||
|
!Number.isFinite(event.deltaY) ||
|
||||||
|
event.deltaY === 0
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
let relayed;
|
||||||
|
try {
|
||||||
|
relayed = createWheelEvent('wheel', {
|
||||||
|
deltaX: event.deltaX,
|
||||||
|
deltaY: boundedPinchDelta(event.deltaY),
|
||||||
|
deltaZ: event.deltaZ,
|
||||||
|
deltaMode: event.deltaMode,
|
||||||
|
screenX: event.screenX,
|
||||||
|
screenY: event.screenY,
|
||||||
|
clientX: event.clientX,
|
||||||
|
clientY: event.clientY,
|
||||||
|
ctrlKey: true,
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
view: globalThis.window,
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// The registered Ctrl+wheel binding can still consume the original.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
relayedEvents.add(relayed);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
canvas.dispatchEvent(relayed);
|
||||||
|
};
|
||||||
|
container.addEventListener('wheel', relayPinch, {
|
||||||
|
capture: true,
|
||||||
|
passive: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
let active = true;
|
||||||
|
return () => {
|
||||||
|
if (!active) return;
|
||||||
|
active = false;
|
||||||
|
container.removeEventListener('wheel', relayPinch, true);
|
||||||
|
if (
|
||||||
|
!alreadyHandlesControlWheel &&
|
||||||
|
controller.zoomEventTypes === configuredZoomEventTypes
|
||||||
|
)
|
||||||
|
controller.zoomEventTypes = originalZoomEventTypes;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in new issue
Block a user