show or hide with animation

This commit is contained in:
ethan 2024-03-16 22:03:36 +08:00
parent 6ca096dc8c
commit a3dec9df66
4 changed files with 254 additions and 15 deletions

82
package-lock.json generated
View File

@ -1,13 +1,19 @@
{
"name": "cesium-plot",
"version": "0.0.1",
"name": "cesium-plot-js",
"version": "0.0.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cesium-plot",
"version": "0.0.1",
"name": "cesium-plot-js",
"version": "0.0.4",
"dependencies": {
"lodash.clonedeep": "^4.5.0",
"lodash.merge": "^4.6.2"
},
"devDependencies": {
"@types/lodash.clonedeep": "^4.5.9",
"@types/lodash.merge": "^4.6.9",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"cesium": "1.99.0",
@ -570,6 +576,30 @@
"integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
"dev": true
},
"node_modules/@types/lodash": {
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz",
"integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==",
"dev": true
},
"node_modules/@types/lodash.clonedeep": {
"version": "4.5.9",
"resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.9.tgz",
"integrity": "sha512-19429mWC+FyaAhOLzsS8kZUsI+/GmBAQ0HFiCPsKGU+7pBXOQWhyrY6xNNDwUSX8SMZMJvuFVMF9O5dQOlQK9Q==",
"dev": true,
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/lodash.merge": {
"version": "4.6.9",
"resolved": "https://registry.npmjs.org/@types/lodash.merge/-/lodash.merge-4.6.9.tgz",
"integrity": "sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==",
"dev": true,
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/node": {
"version": "20.11.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
@ -1569,11 +1599,15 @@
"node": ">=10"
}
},
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"node_modules/long": {
"version": "5.2.3",
@ -2532,6 +2566,30 @@
"integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
"dev": true
},
"@types/lodash": {
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz",
"integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==",
"dev": true
},
"@types/lodash.clonedeep": {
"version": "4.5.9",
"resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.9.tgz",
"integrity": "sha512-19429mWC+FyaAhOLzsS8kZUsI+/GmBAQ0HFiCPsKGU+7pBXOQWhyrY6xNNDwUSX8SMZMJvuFVMF9O5dQOlQK9Q==",
"dev": true,
"requires": {
"@types/lodash": "*"
}
},
"@types/lodash.merge": {
"version": "4.6.9",
"resolved": "https://registry.npmjs.org/@types/lodash.merge/-/lodash.merge-4.6.9.tgz",
"integrity": "sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==",
"dev": true,
"requires": {
"@types/lodash": "*"
}
},
"@types/node": {
"version": "20.11.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
@ -3317,11 +3375,15 @@
"p-locate": "^5.0.0"
}
},
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
},
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"long": {
"version": "5.2.3",

View File

@ -27,11 +27,17 @@
"preview": "vite preview"
},
"devDependencies": {
"@types/lodash.clonedeep": "^4.5.9",
"@types/lodash.merge": "^4.6.9",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"cesium": "1.99.0",
"eslint": "^8.45.0",
"typescript": "^5.0.2",
"vite": "^4.4.5",
"cesium": "1.99.0"
"vite": "^4.4.5"
},
"dependencies": {
"lodash.clonedeep": "^4.5.0",
"lodash.merge": "^4.6.2"
}
}

View File

@ -42,7 +42,7 @@ export default class DoubleArrow extends Base {
} else if (this.points.length === 2) {
this.setGeometryPoints(this.points);
this.drawPolygon();
} else {
} else if (this.points.length === 4) {
this.finishDrawing();
}
}

View File

@ -3,6 +3,10 @@
import * as CesiumTypeOnly from 'cesium';
import { State, GeometryStyle, PolygonStyle, LineStyle, EventType, EventListener } from './interface';
import EventDispatcher from './events';
import cloneDeep from 'lodash.clonedeep';
import merge from 'lodash.merge';
export default class Base {
cesium: typeof CesiumTypeOnly;
@ -22,6 +26,8 @@ export default class Base {
dragEventHandler: CesiumTypeOnly.ScreenSpaceEventHandler;
entityId: string = '';
points: CesiumTypeOnly.Cartesian3[] = [];
isHidden: boolean = false;
styleCache: GeometryStyle | undefined;
constructor(cesium: CesiumTypeOnly, viewer: CesiumTypeOnly.Viewer, style?: GeometryStyle) {
this.cesium = cesium;
@ -53,6 +59,8 @@ export default class Base {
style,
);
}
//Cache the initial settings to avoid modification of properties due to reference type assignment.
this.styleCache = cloneDeep(this.style);
}
/**
@ -159,13 +167,17 @@ export default class Base {
}
finishDrawing() {
// Some polygons draw a separate line between the first two points before drawing the complete shape;
// this line should be removed after drawing is complete.
this.type === 'polygon' && this.lineEntity && this.viewer.entities.remove(this.lineEntity);
this.removeMoveListener();
// Editable upon initial drawing completion.
this.setState('edit');
this.addControlPoints();
this.draggable();
const entity = this.polygonEntity || this.lineEntity;
this.entityId = entity.id;
// this.entityId = `CesiumPlot-${entity.id}`;
/**
* "I've noticed that CallbackProperty can lead to significant performance issues.
* After drawing multiple shapes, the map becomes noticeably laggy. Using methods
@ -478,11 +490,170 @@ export default class Base {
}
}
showAnimation(duration: number = 1000, delay: number = 0, callback: (() => void) | undefined) {
if (this.state != 'static' || this.isHidden === false) {
//If not in a static state or already displayed, do not process.
return;
}
this.isHidden = false;
if (this.type === 'polygon') {
let alpha = 0.3;
const material = this.styleCache.material;
if (material.image) {
// With Texture
alpha = material.color.getValue().alpha;
} else {
alpha = material.alpha;
}
this.animateOpacity(this.polygonEntity, alpha, duration, delay, callback, this.state);
const outlineAlpha = this.styleCache?.outlineMaterial?.alpha;
this.animateOpacity(
this.outlineEntity,
outlineAlpha || 1.0,
duration,
delay,
undefined,
this.state,
);
} else if (this.type === 'line') {
const material = this.styleCache.material;
let alpha = 1.0;
if (material.image) {
// With Texture
alpha = material.color.alpha;
} else if (material.dashLength) {
// Dashed Line
const color = material.color.getValue();
alpha = color.alpha;
} else {
// Solid Color
alpha = this.styleCache?.material?.alpha;
}
this.animateOpacity(this.lineEntity, alpha, duration, delay, callback, this.state);
}
if (duration != 0) {
this.setState('animating');
}
}
hideAnimation(duration: number = 1000, delay: number = 0, callback: (() => void) | undefined) {
if (this.state != 'static' || this.isHidden === true) {
return;
}
if (this.type === 'polygon') {
this.animateOpacity(this.polygonEntity, 0.0, duration, delay, callback, this.state);
this.animateOpacity(this.outlineEntity, 0.0, duration, delay, undefined, this.state);
} else if (this.type === 'line') {
this.animateOpacity(this.lineEntity, 0.0, duration, delay, callback, this.state);
}
// if (this.state == 'edit') {
// this.controlPoints.forEach(p => {
// this.animateOpacity(p, 0.0, duration, delay, undefined, this.state);
// });
// }
if (duration != 0) {
this.setState('animating');
}
}
animateOpacity(
entity: CesiumTypeOnly.Entity,
targetAlpha: number,
duration: number,
delay: number,
callback?: () => void,
state?: State,
): void {
setTimeout(() => {
const graphics = entity.polygon || entity.polyline || entity.billboard;
let startAlpha: number;
let material = graphics.material;
if (material) {
if (material.image && material.color.alpha !== undefined) {
// Texture material, setting the alpha channel in the color of the custom ImageFlowMaterialProperty.
startAlpha = material.color.alpha;
} else {
startAlpha = material.color.getValue().alpha;
}
} else {
// billbord
const color = graphics.color.getValue();
startAlpha = color.alpha;
}
let startTime = 0;
const animate = (currentTime: number) => {
if (!startTime) {
startTime = currentTime;
}
const elapsedTime = currentTime - startTime;
if (elapsedTime < duration) {
const deltalpha = (elapsedTime / duration) * (targetAlpha - startAlpha);
const newAlpha = startAlpha + deltalpha;
if (material) {
if (material.image && material.color.alpha !== undefined) {
// Texture Material
material.color.alpha = newAlpha;
} else {
// Solid Color
const newColor = material.color.getValue().withAlpha(newAlpha);
material.color.setValue(newColor);
}
} else {
// billbord
const color = graphics.color.getValue();
const newColor = color.withAlpha(newAlpha);
graphics.color.setValue(newColor);
}
requestAnimationFrame(animate);
} else {
// Animation Ended
callback && callback();
const restoredState = state ? state : 'static';
if (targetAlpha === 0) {
this.isHidden = true;
}
// if (duration == 0) {
this.setState('drawing');
if (material) {
if (material.image && material.color.alpha !== undefined) {
// Texture Material
material.color.alpha = targetAlpha;
} else {
// Solid Color
const newColor = material.color.getValue().withAlpha(targetAlpha);
material.color.setValue(newColor);
}
} else {
// billbord
const color = graphics.color.getValue();
const newColor = color.withAlpha(targetAlpha);
graphics.color.setValue(newColor);
}
requestAnimationFrame(() => {
this.setState(restoredState);
});
// } else {
// this.setState(restoredState);
// }
}
};
requestAnimationFrame(animate);
}, delay);
}
remove() {
if (this.type === 'polygon') {
this.viewer.entities.remove(this.polygonEntity);
this.viewer.entities.remove(this.outlineEntity);
this.lineEntity && this.viewer.entities.remove(this.lineEntity);
this.polygonEntity = null;
this.outlineEntity = null;
this.lineEntity = null;