vue-cesium
Version:
Vue 3.x components for CesiumJS.
599 lines (596 loc) • 22.2 kB
JavaScript
import { ref } from 'vue';
import CameraFlightPath from '../compass/CameraFlightPath.mjs';
import { $, getInstanceListener } from '../../../utils/private/vm.mjs';
import '../../../utils/util.mjs';
import { isObject } from '@vue/shared';
"use strict";
function useCompass(props, { emit }, vcInstance) {
const vectorScratch = {};
const oldTransformScratch = {};
const newTransformScratch = {};
const centerScratch = {};
let unsubscribeFromPostRender;
let unsubscribeFromClockTick;
let rotateEastMouseUpFunction;
let rotateEastTickFunction;
const heading = ref(0);
let isrotateEasting = false;
let rotateEastLastTimestamp = 0;
let rotateMouseUpFunction;
let rotateMouseMoveFunction;
let isRotating = false;
let rotateInitialCursorAngle = 0;
let rotateFrame = {};
let rotateIsLook = false;
let rotateInitialCameraAngle = 0;
let rotateInitialCameraDistance = {};
let screenSpaceEventHandler;
let tiltMouseMoveFunction;
let tiltMouseUpFunction;
let isTilting = false;
let tiltFrame = {};
let tiltInitialCursorAngle = 0;
const tiltbarLeft = ref(56);
const tiltbarTop = ref(3);
let clickStartPosition;
const tooltipRef = ref(null);
const handleMouseDown = (e) => {
var _a;
if (e.stopPropagation)
e.stopPropagation();
if (e.preventDefault)
e.preventDefault();
(_a = $(tooltipRef)) == null ? void 0 : _a.hide();
const { Cartesian2, SceneMode, Math: CesiumMath } = Cesium;
const scene = vcInstance.viewer.scene;
if (scene.mode === SceneMode.MORPHING) {
return true;
}
const compassElement = e.currentTarget;
const compassRectangle = e.currentTarget.getBoundingClientRect();
const center = new Cartesian2((compassRectangle.right - compassRectangle.left) / 2, (compassRectangle.bottom - compassRectangle.top) / 2);
let clickLocation;
if (e instanceof MouseEvent) {
clickLocation = new Cartesian2(e.clientX - compassRectangle.left, e.clientY - compassRectangle.top);
clickStartPosition = new Cartesian2(e.clientX, e.clientY);
} else if (e instanceof TouchEvent) {
clickLocation = new Cartesian2(e.changedTouches[0].clientX - compassRectangle.left, e.changedTouches[0].clientY - compassRectangle.top);
clickStartPosition = new Cartesian2(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
}
const vector = Cartesian2.subtract(clickLocation, center, vectorScratch);
const distanceFromCenter = Cartesian2.magnitude(vector);
if (distanceFromCenter > 30 && distanceFromCenter < 45) {
rotate(compassElement, vector);
} else if (!(distanceFromCenter > 50 && distanceFromCenter < 70)) {
rotateEast(compassElement, vector);
} else {
const angle = CesiumMath.PI_OVER_TWO - Math.atan2(-vector.y, vector.x);
angle >= 0 && angle <= CesiumMath.PI_OVER_TWO && tilt(compassElement, vector);
}
};
const handleMouseUp = (event) => {
const { Cartesian2, Math: CesiumMath } = Cesium;
const compassRectangle = event.currentTarget.getBoundingClientRect();
const center = new Cartesian2((compassRectangle.right - compassRectangle.left) / 2, (compassRectangle.bottom - compassRectangle.top) / 2);
const clickLocation = event.type === "mouseup" ? new Cartesian2(event.clientX - compassRectangle.left, event.clientY - compassRectangle.top) : new Cartesian2(event.changedTouches[0].clientX - compassRectangle.left, event.changedTouches[0].clientY - compassRectangle.top);
const vector = Cartesian2.subtract(clickLocation, center, vectorScratch);
const magnitude = Cartesian2.magnitude(vector);
if (magnitude > 30 && magnitude < 45) {
const angle = CesiumMath.toDegrees(Math.atan2(-vector.y, vector.x));
const clickStartPositionUp = event.type === "mouseup" ? new Cartesian2(event.clientX, event.clientY) : new Cartesian2(event.changedTouches[0].clientX, event.changedTouches[0].clientY);
const dX = clickStartPositionUp.x - clickStartPosition.x;
const dY = clickStartPositionUp.y - clickStartPosition.y;
const distance = Math.sqrt(dX * dX + dY * dY);
if (distance > 5) {
return;
}
const headingDegree = CesiumMath.toDegrees(heading.value);
const m = Math.abs(angle - headingDegree);
const scene = vcInstance.viewer.scene;
if (angle > 0 && headingDegree > 0 && headingDegree < 90 && m > 80 && m < 100 || m > 260 && m < 280) {
scene.camera.flyTo({
destination: scene.camera.position,
orientation: {
heading: 0,
pitch: scene.camera.pitch
}
});
}
}
};
const handleDoubleClick = (e) => {
const { Cartesian2, Cartesian3, defined, Matrix4, Ray, SceneMode, Transforms } = Cesium;
const { viewer } = vcInstance;
const scene = viewer.scene;
const camera = scene.camera;
const sscc = scene.screenSpaceCameraController;
if (scene.mode === SceneMode.MORPHING || !sscc.enableInputs) {
return true;
}
if (scene.mode === SceneMode.COLUMBUS_VIEW && !sscc.enableTranslate) {
return;
}
if (scene.mode === SceneMode.SCENE3D || scene.mode === SceneMode.COLUMBUS_VIEW) {
if (!sscc.enableLook) {
return;
}
if (scene.mode === SceneMode.SCENE3D) {
if (!sscc.enableRotate) {
return;
}
}
}
const windowPosition = new Cartesian2();
windowPosition.x = scene.canvas.clientWidth / 2;
windowPosition.y = scene.canvas.clientHeight / 2;
const pickRayScratch = new Ray();
const ray = camera.getPickRay(windowPosition, pickRayScratch);
const center = scene.globe.pick(ray, scene, centerScratch);
if (!defined(center)) {
viewer.camera.flyHome();
return;
}
const listener = getInstanceListener(vcInstance, "compassEvt");
listener && emit("compassEvt", {
type: "reset",
camera: viewer.camera,
status: "start",
target: e.currentTarget
});
const rotateFrame2 = Transforms.eastNorthUpToFixedFrame(center || new Cartesian3(), viewer.scene.globe.ellipsoid);
const lookVector = Cartesian3.subtract(center || new Cartesian3(), camera.position, new Cartesian3());
const flight = CameraFlightPath.createTween(scene, {
destination: Matrix4.multiplyByPoint(rotateFrame2, new Cartesian3(0, 0, Cartesian3.magnitude(lookVector)), new Cartesian3()),
direction: Matrix4.multiplyByPointAsVector(rotateFrame2, new Cartesian3(0, 0, -1), new Cartesian3()),
up: Matrix4.multiplyByPointAsVector(rotateFrame2, new Cartesian3(0, 1, 0), new Cartesian3()),
duration: props.duration,
complete: () => {
listener && emit("compassEvt", {
type: "reset",
camera: viewer.camera,
status: "end",
target: e.currentTarget
});
},
cancel: () => {
listener && emit("compassEvt", {
type: "reset",
camera: viewer.camera,
status: "cancel",
target: e.currentTarget
});
}
});
scene.tweens.add(flight);
};
const viewerChange = () => {
const { defined } = Cesium;
if (defined(vcInstance.viewer)) {
if (unsubscribeFromPostRender) {
unsubscribeFromPostRender();
unsubscribeFromPostRender = void 0;
}
unsubscribeFromPostRender = vcInstance.viewer.scene.postRender.addEventListener(function() {
if (heading.value !== vcInstance.viewer.scene.camera.heading) {
heading.value = vcInstance.viewer.scene.camera.heading;
}
});
} else {
if (unsubscribeFromPostRender) {
unsubscribeFromPostRender();
unsubscribeFromPostRender = void 0;
}
}
};
const rotateEast = (compassElement, cursorVector) => {
const { defined, getTimestamp, SceneMode, Math: CesiumMath, ScreenSpaceEventType } = Cesium;
const scene = vcInstance.viewer.scene;
const sscc = scene.screenSpaceCameraController;
switch (scene.mode) {
case SceneMode.COLUMBUS_VIEW:
if (sscc.enableLook) {
break;
}
if (!sscc.enableTranslate || !sscc.enableTilt) {
return;
}
break;
case SceneMode.SCENE3D:
if (sscc.enableLook) {
break;
}
if (!sscc.enableTilt || !sscc.enableRotate) {
return;
}
break;
case Cesium.SceneMode.SCENE2D:
if (!sscc.enableTranslate) {
return;
}
break;
}
screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.LEFT_UP);
if (defined(rotateEastTickFunction)) {
vcInstance.viewer.clock.onTick.removeEventListener(rotateEastTickFunction);
}
;
rotateEastMouseUpFunction = void 0;
rotateEastTickFunction = void 0;
isrotateEasting = true;
rotateEastLastTimestamp = getTimestamp();
let angle = CesiumMath.PI_OVER_TWO - Math.atan2(-cursorVector.y, cursorVector.x);
const quarterPI = Math.PI / 4;
let roateDirection = 0;
const roateType = {
LEFT: 1,
RIGHT: 2,
UP: 3,
DOWN: 4
};
roateDirection = angle >= -quarterPI && quarterPI >= angle ? roateType.DOWN : angle >= quarterPI && 3 * quarterPI >= angle ? roateType.RIGHT : angle >= 3 * quarterPI && 5 * quarterPI >= angle ? roateType.UP : roateType.LEFT;
const listener = getInstanceListener(vcInstance, "compassEvt");
let type = `rotateEast`;
switch (roateDirection) {
case roateType.LEFT:
type = "rotateWest";
break;
case roateType.RIGHT:
type = "rotateEast";
break;
case roateType.UP:
type = "rotateNorth";
break;
case roateType.DOWN:
type = "rotateSouth";
}
listener && emit("compassEvt", {
type,
camera: scene.camera,
status: "start",
target: compassElement
});
rotateEastTickFunction = function(e) {
const scene2 = vcInstance.viewer.scene;
const camera = scene2.camera;
const timestamp = getTimestamp();
angle = 20 * Math.abs(camera.positionCartographic.height / 6378317) * 5e-4;
switch (roateDirection) {
case roateType.LEFT:
camera.rotateLeft(angle);
break;
case roateType.RIGHT:
camera.rotateRight(angle);
break;
case roateType.UP:
camera.rotate(camera.right, -angle);
break;
case roateType.DOWN:
camera.rotate(camera.right, angle);
}
rotateEastLastTimestamp = timestamp;
listener && emit("compassEvt", {
type,
camera: scene2.camera,
status: "changing",
target: compassElement
});
};
rotateEastMouseUpFunction = function(e) {
isrotateEasting = false;
screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.LEFT_UP);
defined(rotateEastTickFunction) && vcInstance.viewer.clock.onTick.removeEventListener(rotateEastTickFunction);
rotateEastMouseUpFunction = void 0;
rotateEastTickFunction = void 0;
listener && emit("compassEvt", {
type,
camera: scene.camera,
status: "end",
target: compassElement
});
};
screenSpaceEventHandler.setInputAction(rotateEastMouseUpFunction, ScreenSpaceEventType.LEFT_UP);
unsubscribeFromClockTick = vcInstance.viewer.clock.onTick.addEventListener(rotateEastTickFunction);
};
const rotate = (compassElement, cursorVector) => {
if (!props.enableCompassOuterRing) {
return;
}
const scene = vcInstance.viewer.scene;
let camera = scene.camera;
const sscc = scene.screenSpaceCameraController;
if (scene.mode === Cesium.SceneMode.MORPHING || scene.mode === Cesium.SceneMode.SCENE2D || !sscc.enableInputs) {
return;
}
if (!sscc.enableLook && (scene.mode === Cesium.SceneMode.COLUMBUS_VIEW || scene.mode === Cesium.SceneMode.SCENE3D && !sscc.enableRotate)) {
return;
}
document.removeEventListener("mousemove", rotateMouseMoveFunction, false);
document.removeEventListener("touchmove", rotateMouseMoveFunction, false);
document.removeEventListener("mouseup", rotateMouseUpFunction, false);
document.removeEventListener("touchend", rotateMouseUpFunction, false);
const { Cartesian2, Cartesian3, defined, Math: CesiumMath, Matrix4, Ray, Transforms } = Cesium;
rotateMouseMoveFunction = void 0;
rotateMouseUpFunction = void 0;
const listener = getInstanceListener(vcInstance, "compassEvt");
listener && emit("compassEvt", {
type: "rotate",
camera: scene.camera,
status: "start",
target: compassElement
});
isRotating = true;
rotateInitialCursorAngle = Math.atan2(-cursorVector.y, cursorVector.x);
const windowPosition = new Cartesian2();
windowPosition.x = scene.canvas.clientWidth / 2;
windowPosition.y = scene.canvas.clientHeight / 2;
const pickRayScratch = new Ray();
const ray = camera.getPickRay(windowPosition, pickRayScratch);
const viewCenter = scene.globe.pick(ray, scene, centerScratch);
if (!defined(viewCenter)) {
rotateFrame = Transforms.eastNorthUpToFixedFrame(camera.positionWC, scene.globe.ellipsoid, newTransformScratch);
rotateIsLook = true;
} else {
rotateFrame = Transforms.eastNorthUpToFixedFrame(viewCenter || new Cartesian3(), scene.globe.ellipsoid, newTransformScratch);
rotateIsLook = false;
}
let oldTransform = Matrix4.clone(camera.transform, oldTransformScratch);
camera.lookAtTransform(rotateFrame);
rotateInitialCameraAngle = Math.atan2(camera.position.y, camera.position.x);
rotateInitialCameraDistance = Cartesian3.magnitude(new Cartesian3(camera.position.x, camera.position.y, 0));
camera.lookAtTransform(oldTransform);
rotateMouseMoveFunction = function(e) {
const compassRectangle = compassElement.getBoundingClientRect();
const center = new Cartesian2((compassRectangle.right - compassRectangle.left) / 2, (compassRectangle.bottom - compassRectangle.top) / 2);
let clickLocation;
if (e instanceof MouseEvent) {
clickLocation = new Cartesian2(e.clientX - compassRectangle.left, e.clientY - compassRectangle.top);
} else if (e instanceof TouchEvent) {
clickLocation = new Cartesian2(e.changedTouches[0].clientX - compassRectangle.left, e.changedTouches[0].clientY - compassRectangle.top);
}
const vector = Cartesian2.subtract(clickLocation, center, vectorScratch);
const angle = Math.atan2(-vector.y, vector.x);
const angleDifference = angle - rotateInitialCursorAngle;
const newCameraAngle = CesiumMath.zeroToTwoPi(rotateInitialCameraAngle - angleDifference);
camera = vcInstance.viewer.scene.camera;
oldTransform = Matrix4.clone(camera.transform, oldTransformScratch);
camera.lookAtTransform(rotateFrame);
const currentCameraAngle = Math.atan2(camera.position.y, camera.position.x);
camera.rotateRight(newCameraAngle - currentCameraAngle);
camera.lookAtTransform(oldTransform);
listener && emit("compassEvt", {
type: "rotate",
camera: scene.camera,
status: "changing",
target: compassElement
});
};
rotateMouseUpFunction = function(e) {
isRotating = false;
document.removeEventListener("mousemove", rotateMouseMoveFunction, false);
document.removeEventListener("touchmove", rotateMouseMoveFunction, false);
document.removeEventListener("mouseup", rotateMouseUpFunction, false);
document.removeEventListener("touchend", rotateMouseUpFunction, false);
rotateMouseMoveFunction = void 0;
rotateMouseUpFunction = void 0;
listener && emit("compassEvt", {
type: "rotate",
camera: scene.camera,
status: "end",
target: compassElement
});
};
document.addEventListener("mousemove", rotateMouseMoveFunction, false);
document.addEventListener("touchmove", rotateMouseMoveFunction, false);
document.addEventListener("mouseup", rotateMouseUpFunction, false);
document.addEventListener("touchend", rotateMouseUpFunction, false);
};
const tilt = (compassElement, cursorVector) => {
const { Cartesian2, defined, Math: CesiumMath, Matrix4, ScreenSpaceEventType, Transforms } = Cesium;
screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.LEFT_UP);
tiltMouseMoveFunction = void 0;
tiltMouseUpFunction = void 0;
tiltInitialCursorAngle = CesiumMath.PI_OVER_TWO - Math.atan2(-cursorVector.y, cursorVector.x);
tiltInitialCursorAngle = tiltInitialCursorAngle < 0 ? 0 : tiltInitialCursorAngle;
tiltInitialCursorAngle = tiltInitialCursorAngle > CesiumMath.PI_OVER_TWO ? CesiumMath.PI_OVER_TWO : tiltInitialCursorAngle;
isTilting = true;
const scene = vcInstance.viewer.scene;
const camera = scene.camera;
const windowPosition = new Cartesian2();
windowPosition.x = scene.canvas.clientWidth / 2;
windowPosition.y = scene.canvas.clientHeight / 2;
let pickPosition = camera.pickEllipsoid(windowPosition, scene.globe.ellipsoid);
if (!defined(pickPosition)) {
for (; windowPosition.y < scene.canvas.clientHeight; ) {
windowPosition.y += 5;
pickPosition = camera.pickEllipsoid(windowPosition, scene.globe.ellipsoid);
}
}
const listener = getInstanceListener(vcInstance, "compassEvt");
listener && emit("compassEvt", {
type: "tilt",
camera: scene.camera,
status: "start",
target: compassElement
});
isObject(pickPosition) && defined(pickPosition) && (tiltFrame = Transforms.eastNorthUpToFixedFrame(pickPosition, scene.globe.ellipsoid));
tiltMouseMoveFunction = (e) => {
isTilting = true;
const compassRectangle = compassElement.getBoundingClientRect();
const center = new Cesium.Cartesian2(
(compassRectangle.right - compassRectangle.left) / 2,
(compassRectangle.bottom - compassRectangle.top) / 2
);
const endPosition = Cartesian2.clone(e.endPosition);
const vector = Cartesian2.subtract(endPosition, center, vectorScratch);
let angle = CesiumMath.PI_OVER_TWO - Math.atan2(-vector.y, vector.x);
angle = angle < 0 ? 0 : angle;
angle = angle > CesiumMath.PI_OVER_TWO ? CesiumMath.PI_OVER_TWO : angle;
const camera2 = vcInstance.viewer.scene.camera;
const oldTransform = Matrix4.clone(camera2.transform, oldTransformScratch);
camera2.lookAtTransform(tiltFrame);
const rotateUpAngle = angle - tiltInitialCursorAngle;
camera2.rotateUp(rotateUpAngle);
tiltInitialCursorAngle = angle;
camera2.lookAtTransform(oldTransform);
let level = Math.ceil(angle / (Math.PI / 40));
level = level > 19 ? 19 : level;
const position = getPoints()[level];
tiltbarLeft.value = position.x;
tiltbarTop.value = position.y;
listener && emit("compassEvt", {
type: "tilt",
camera: scene.camera,
status: "changing",
target: compassElement
});
};
tiltMouseUpFunction = function(e) {
isTilting = false;
screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.LEFT_UP);
tiltMouseMoveFunction = void 0;
tiltMouseUpFunction = void 0;
listener && emit("compassEvt", {
type: "tilt",
camera: scene.camera,
status: "end",
target: compassElement
});
};
screenSpaceEventHandler.setInputAction(tiltMouseMoveFunction, ScreenSpaceEventType.MOUSE_MOVE);
screenSpaceEventHandler.setInputAction(tiltMouseUpFunction, ScreenSpaceEventType.LEFT_UP);
};
const onTooltipBeforeShow = (e) => {
if (rotateMouseMoveFunction !== void 0) {
e.cancel = true;
}
};
const getTiltbarPosition = () => {
const { Math: CesiumMath } = Cesium;
const pitch = CesiumMath.PI_OVER_TWO + vcInstance.viewer.scene.camera.pitch;
const length = Math.PI / 2 / 20;
let level = Math.floor(pitch / length);
level = level > 19 ? 19 : level;
level = level < 0 ? 0 : level;
tiltbarLeft.value = getPoints()[level].x;
tiltbarTop.value = getPoints()[level].y;
};
const load = async (viewer, el) => {
vcInstance.viewer = viewer;
heading.value = viewer.scene.camera.heading;
viewerChange();
screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(el);
getTiltbarPosition();
return true;
};
const unload = async () => {
document.removeEventListener("mousemove", rotateMouseMoveFunction, false);
document.removeEventListener("touchmove", rotateMouseMoveFunction, false);
document.removeEventListener("mouseup", rotateMouseUpFunction, false);
document.removeEventListener("touchend", rotateMouseUpFunction, false);
unsubscribeFromClockTick && unsubscribeFromClockTick();
unsubscribeFromPostRender && unsubscribeFromPostRender();
screenSpaceEventHandler == null ? void 0 : screenSpaceEventHandler.destroy();
return true;
};
return {
heading,
handleDoubleClick,
handleMouseDown,
handleMouseUp,
onTooltipBeforeShow,
viewerChange,
load,
unload,
tiltbarLeft,
tiltbarTop,
tooltipRef
};
}
function getPoints() {
return [
{
x: 56,
y: 3
},
{
x: 59,
y: 4
},
{
x: 64,
y: 5
},
{
x: 69,
y: 6
},
{
x: 74,
y: 7
},
{
x: 79,
y: 9
},
{
x: 84,
y: 12
},
{
x: 89,
y: 15
},
{
x: 92,
y: 19
},
{
x: 94,
y: 20
},
{
x: 99,
y: 25
},
{
x: 104,
y: 34
},
{
x: 106,
y: 40
},
{
x: 107,
y: 44
},
{
x: 107,
y: 46
},
{
x: 107,
y: 48
},
{
x: 107,
y: 50
},
{
x: 107,
y: 52
},
{
x: 107,
y: 54
},
{
x: 107,
y: 56
}
];
}
export { useCompass as default };
//# sourceMappingURL=use-compass.mjs.map