Add Lifecycle Events

This commit is contained in:
ethan 2023-08-24 15:55:04 +08:00
parent de9292fd09
commit 15a9ae1e95
7 changed files with 118 additions and 18 deletions

View File

@ -103,7 +103,11 @@ buttonGroup.onclick = (evt) => {
geometry = new CesiumPlot.FreehandLine(Cesium, viewer); geometry = new CesiumPlot.FreehandLine(Cesium, viewer);
break; break;
case 'drawFreehandPolygon': case 'drawFreehandPolygon':
geometry = new CesiumPlot.FreehandPolygon(Cesium, viewer); geometry = new CesiumPlot.FreehandPolygon(Cesium, viewer, {
material: Cesium.Color.GREEN,
outlineMaterial: Cesium.Color.fromCssColorString('rgba(59, 178, 208, 1)'),
outlineWidth: 2,
});
break; break;
case 'hide': case 'hide':
geometry && geometry.hide(); geometry && geometry.hide();
@ -115,6 +119,25 @@ buttonGroup.onclick = (evt) => {
geometry && geometry.remove(); geometry && geometry.remove();
geometry = null; geometry = null;
break; break;
case 'addEvent':
if (geometry) {
geometry.on('drawStart', () => {
console.error('start');
});
geometry.on('drawUpdate', (cartesian: Cesium.Cartesian3) => {
console.error('update', cartesian);
});
geometry.on('drawEnd', (geometryPoints: any) => {
console.error('drawEnd', geometryPoints);
});
geometry.on('editStart', () => {
console.error('editStart');
});
geometry.on('editEnd', (geometryPoints: any) => {
console.error('editEnd', geometryPoints);
});
}
break;
default: default:
break; break;
} }

View File

@ -24,7 +24,7 @@
justify-content: center; justify-content: center;
} }
.button { .button-container button {
margin: 0 10px; margin: 0 10px;
padding: 6px 10px; padding: 6px 10px;
background-color: #3498db; background-color: #3498db;
@ -39,20 +39,21 @@
<div id="root"></div> <div id="root"></div>
<div id="cesiumContainer"></div> <div id="cesiumContainer"></div>
<div class="button-container" id="button-group"> <div class="button-container" id="button-group">
<button id="drawStraightArrow" class="button">细直箭头</button> <button id="drawStraightArrow">细直箭头</button>
<button id="drawCurvedArrow" class="button">曲线箭头</button> <button id="drawCurvedArrow">曲线箭头</button>
<button id="drawFineArrow" class="button">直箭头</button> <button id="drawFineArrow">直箭头</button>
<button id="drawAttackArrow" class="button">进攻方向箭头</button> <button id="drawAttackArrow">进攻方向箭头</button>
<button id="drawSwallowtailAttackArrow" class="button">进攻方向箭头(燕尾)</button> <button id="drawSwallowtailAttackArrow">进攻方向箭头(燕尾)</button>
<button id="drawSquadCombat" class="button">分队战斗方向</button> <button id="drawSquadCombat">分队战斗方向</button>
<button id="drawSwallowtailSquadCombat" class="button">分队战斗方向(燕尾)</button> <button id="drawSwallowtailSquadCombat">分队战斗方向(燕尾)</button>
<button id="drawAssaultDirection" class="button">突击方向</button> <button id="drawAssaultDirection">突击方向</button>
<button id="drawDoubleArrow" class="button">双箭头</button> <button id="drawDoubleArrow">双箭头</button>
<button id="drawFreehandLine" class="button">自由线</button> <button id="drawFreehandLine">自由线</button>
<button id="drawFreehandPolygon" class="button">自由面</button> <button id="drawFreehandPolygon">自由面</button>
<button id="hide" class="button">隐藏</button> <button id="hide">隐藏</button>
<button id="show" class="button">显示</button> <button id="show">显示</button>
<button id="remove" class="button">删除</button> <button id="remove">删除</button>
<button id="addEvent">绑定事件</button>
</div> </div>
<script> <script>
window.CESIUM_BASE_URL = './examples/cesium'; window.CESIUM_BASE_URL = './examples/cesium';

View File

@ -1,6 +1,7 @@
// @ts-ignore // @ts-ignore
import * as CesiumTypeOnly from '@examples/cesium'; import * as CesiumTypeOnly from '@examples/cesium';
import { State, GeometryStyle, PolygonStyle, LineStyle } from './interface'; import { State, GeometryStyle, PolygonStyle, LineStyle, EventType, EventListener } from './interface';
import EventDispatcher from './events';
export default class Base { export default class Base {
cesium: typeof CesiumTypeOnly; cesium: typeof CesiumTypeOnly;
@ -16,6 +17,7 @@ export default class Base {
freehand!: boolean; freehand!: boolean;
style: GeometryStyle | undefined; style: GeometryStyle | undefined;
outlineEntity: CesiumTypeOnly.Entity; outlineEntity: CesiumTypeOnly.Entity;
eventDispatcher: EventDispatcher;
constructor(cesium: CesiumTypeOnly, viewer: CesiumTypeOnly.Viewer, style?: GeometryStyle) { constructor(cesium: CesiumTypeOnly, viewer: CesiumTypeOnly.Viewer, style?: GeometryStyle) {
this.cesium = cesium; this.cesium = cesium;
@ -24,6 +26,7 @@ export default class Base {
this.mergeStyle(style); this.mergeStyle(style);
this.cartesianToLnglat = this.cartesianToLnglat.bind(this); this.cartesianToLnglat = this.cartesianToLnglat.bind(this);
this.pixelToCartesian = this.pixelToCartesian.bind(this); this.pixelToCartesian = this.pixelToCartesian.bind(this);
this.eventDispatcher = new EventDispatcher();
this.onClick(); this.onClick();
} }
@ -89,11 +92,18 @@ export default class Base {
return; return;
} }
this.addPoint(cartesian); this.addPoint(cartesian);
// Trigger 'drawStart' when the first point is being drawn.
if (this.getPoints().length === 1) {
this.eventDispatcher.dispatchEvent('drawStart');
}
this.eventDispatcher.dispatchEvent('drawUpdate', cartesian);
} else if (this.state === 'edit') { } else if (this.state === 'edit') {
//In edit mode, exit the editing state and delete control points when clicking outside the currently edited shape. //In edit mode, exit the editing state and delete control points when clicking outside the currently edited shape.
if (!hitEntities || activeEntity.id !== pickedObject.id.id) { if (!hitEntities || activeEntity.id !== pickedObject.id.id) {
this.setState('static'); this.setState('static');
this.removeControlPoints(); this.removeControlPoints();
// Trigger 'drawEnd' and return the geometry shape points when exiting the edit mode.
this.eventDispatcher.dispatchEvent('drawEnd', this.getPoints());
} }
} else if (this.state === 'static') { } else if (this.state === 'static') {
//When drawing multiple shapes, the click events for all shapes are triggered. Only when hitting a completed shape should it enter editing mode. //When drawing multiple shapes, the click events for all shapes are triggered. Only when hitting a completed shape should it enter editing mode.
@ -103,6 +113,7 @@ export default class Base {
// Hit Geometry Shape. // Hit Geometry Shape.
this.setState('edit'); this.setState('edit');
this.addControlPoints(); this.addControlPoints();
this.eventDispatcher.dispatchEvent('editStart');
} }
} }
} }
@ -140,6 +151,7 @@ export default class Base {
finishDrawing() { finishDrawing() {
this.removeMoveListener(); this.removeMoveListener();
this.setState('static'); this.setState('static');
this.eventDispatcher.dispatchEvent('drawEnd', this.getPoints());
} }
removeClickListener() { removeClickListener() {
@ -150,6 +162,10 @@ export default class Base {
this.eventHandler.removeInputAction(this.cesium.ScreenSpaceEventType.MOUSE_MOVE); this.eventHandler.removeInputAction(this.cesium.ScreenSpaceEventType.MOUSE_MOVE);
} }
removeDoubleClickListener() {
this.eventHandler.removeInputAction(this.cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
}
setGeometryPoints(geometryPoints: CesiumTypeOnly.Cartesian3[]) { setGeometryPoints(geometryPoints: CesiumTypeOnly.Cartesian3[]) {
this.geometryPoints = geometryPoints; this.geometryPoints = geometryPoints;
} }
@ -255,6 +271,7 @@ export default class Base {
let isDragging = false; let isDragging = false;
let draggedIcon: CesiumTypeOnly.Entity = null; let draggedIcon: CesiumTypeOnly.Entity = null;
let dragStartPosition: CesiumTypeOnly.Cartesian3;
this.controlPointsEventHandler = new this.cesium.ScreenSpaceEventHandler(this.viewer.canvas); this.controlPointsEventHandler = new this.cesium.ScreenSpaceEventHandler(this.viewer.canvas);
// Listen for left mouse button press events // Listen for left mouse button press events
@ -266,7 +283,9 @@ export default class Base {
if (pickedObject.id === this.controlPoints[i]) { if (pickedObject.id === this.controlPoints[i]) {
isDragging = true; isDragging = true;
draggedIcon = this.controlPoints[i]; draggedIcon = this.controlPoints[i];
draggedIcon.index = i; //Save the index of dragged points for dynamic updates during movement dragStartPosition = draggedIcon.position._value;
//Save the index of dragged points for dynamic updates during movement
draggedIcon.index = i;
break; break;
} }
} }
@ -288,6 +307,10 @@ export default class Base {
// Listen for left mouse button release events // Listen for left mouse button release events
this.controlPointsEventHandler.setInputAction(() => { this.controlPointsEventHandler.setInputAction(() => {
// Trigger 'drawUpdate' when there is a change in coordinates before and after dragging.
if (!this.cesium.Cartesian3.equals(dragStartPosition, draggedIcon.position._value)) {
this.eventDispatcher.dispatchEvent('drawUpdate', draggedIcon.position._value);
}
isDragging = false; isDragging = false;
draggedIcon = null; draggedIcon = null;
this.viewer.scene.screenSpaceCameraController.enableRotate = true; this.viewer.scene.screenSpaceCameraController.enableRotate = true;
@ -342,6 +365,17 @@ export default class Base {
} else if (this.type === 'line') { } else if (this.type === 'line') {
this.viewer.entities.remove(this.lineEntity); this.viewer.entities.remove(this.lineEntity);
} }
this.removeClickListener();
this.removeMoveListener();
this.removeDoubleClickListener();
}
on(eventType: EventType, listener: EventListener) {
this.eventDispatcher.on(eventType, listener);
}
off(eventType: EventType, listener: EventListener) {
this.eventDispatcher.off(eventType, listener);
} }
addPoint(cartesian: CesiumTypeOnly.Cartesian3) { addPoint(cartesian: CesiumTypeOnly.Cartesian3) {

37
src/events.ts Normal file
View File

@ -0,0 +1,37 @@
import { EventType, EventListener } from './interface';
export default class EventDispatcher {
listeners: Map<EventType, Set<EventListener>>;
constructor() {
this.listeners = new Map([
['drawStart', new Set()],
['drawUpdate', new Set()],
['drawEnd', new Set()],
['editStart', new Set()],
['editEnd', new Set()],
]);
}
on(event: EventType, listener: EventListener) {
if (!this.listeners.has(event)) {
console.warn("Event binding must be one of 'drawStart', 'drawUpdate', or 'drawEnd'.");
return;
}
this.listeners.get(event)!.add(listener);
}
off(event: EventType, listener: EventListener) {
if (this.listeners.has(event)) {
this.listeners.get(event)!.delete(listener);
}
}
dispatchEvent(event: EventType, eventData?: any) {
if (this.listeners.has(event)) {
this.listeners.get(event)!.forEach((listener) => {
listener(eventData);
});
}
}
}

View File

@ -14,3 +14,6 @@ export type LineStyle = {
export type State = 'drawing' | 'edit' | 'static'; export type State = 'drawing' | 'edit' | 'static';
export type GeometryStyle = PolygonStyle | LineStyle; export type GeometryStyle = PolygonStyle | LineStyle;
export type EventType = 'drawStart' | 'drawUpdate' | 'drawEnd' | 'editEnd' | 'editStart';
export type EventListener = (eventData?: any) => void;

View File

@ -37,6 +37,7 @@ export default class FreehandLine extends Base {
this.points.push(cartesian); this.points.push(cartesian);
this.setGeometryPoints(this.points); this.setGeometryPoints(this.points);
this.drawLine(); this.drawLine();
this.eventDispatcher.dispatchEvent('drawUpdate', cartesian);
} }
/** /**

View File

@ -38,6 +38,7 @@ export default class FreehandPolygon extends Base {
if (this.points.length > 2) { if (this.points.length > 2) {
this.setGeometryPoints(this.points); this.setGeometryPoints(this.points);
this.drawPolygon(); this.drawPolygon();
this.eventDispatcher.dispatchEvent('drawUpdate', cartesian);
} }
} }