Skip to content

Instantly share code, notes, and snippets.

@onsummer
Last active September 18, 2023 11:03
Show Gist options
  • Save onsummer/224885308ef8b739e3479c79d812087b to your computer and use it in GitHub Desktop.
Save onsummer/224885308ef8b739e3479c79d812087b to your computer and use it in GitHub Desktop.
「CesiumJS」Draw Dynamic Segment Line
const viewer = new Cesium.Viewer("cesiumContainer");
viewer.scene.globe.depthTestAgainstTerrain = true;
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
const getWC = (windowPosition) => {
return viewer.scene.pickPosition(windowPosition);
};
const FILL_COLOR = Cesium.Color.fromBytes(255, 101, 41, 255 * 0.6);
const OUTLINE_COLOR = Cesium.Color.fromBytes(255, 255, 255, 255 * 0.8);
const drawCacheA = {
startWC: null,
endWC: null,
};
const drawCacheB = {
startWC: null,
endWC: null,
};
let stage = 0;
let dynamicDrawing = false;
const getCallback = (lineCache) => {
return () => [lineCache.startWC, lineCache.endWC];
};
const removeLine = (line) => {
const lineCache = line === 'A' ? drawCacheA : drawCacheB;
viewer.entities.removeById(line + '-line');
};
const drawLine = (line) => {
const lineCache = line === 'A' ? drawCacheA : drawCacheB;
if (!(lineCache.startWC && lineCache.endWC)) {
return;
}
const cb = getCallback(lineCache);
if (viewer.entities.getById(line + '-line')) {
return;
}
viewer.entities.add({
id: line + '-line',
polyline: {
positions: new Cesium.CallbackProperty(cb, false),
width: 5,
clampToGround: true,
material: new Cesium.PolylineOutlineMaterialProperty({
color: FILL_COLOR,
outlineWidth: 2,
outlineColor: OUTLINE_COLOR,
}),
},
});
};
const onClick = ({ position }) => {
if (stage === 0) {
drawCacheA.startWC = getWC(position);
dynamicDrawing = true;
stage++;
} else if (stage === 1) {
drawCacheA.endWC = getWC(position);
drawCacheB.startWC = null;
drawCacheB.endWC = null;
dynamicDrawing = false;
removeLine('B');
drawLine('A');
stage++;
} else if (stage === 2) {
drawCacheB.startWC = getWC(position);
dynamicDrawing = true;
stage++;
} else {
drawCacheB.endWC = getWC(position);
drawCacheA.startWC = null;
drawCacheA.endWC = null;
dynamicDrawing = false;
removeLine('A');
drawLine('B');
stage = 0;
}
};
const onMouseMove = ({ endPosition }) => {
if (!dynamicDrawing) {
return;
}
const line = stage === 1 ? 'A' : 'B';
const lineCache = line === 'A' ? drawCacheA : drawCacheB;
lineCache.endWC = getWC(endPosition);
drawLine(line);
};
handler.setInputAction(onClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(onMouseMove, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
const viewer = new Cesium.Viewer("cesiumContainer", {
msaaSamples: 4,
});
const scene = viewer.scene;
scene.globe.depthTestAgainstTerrain = true;
const h = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
let stage = 0;
let dynamicDrawing = false;
const drawCache = {
startWC: null,
endWC: null,
segmentLinePrimitive: null,
};
const getWC = (windowPosition) => {
return scene.pickPosition(windowPosition);
};
const removePrimitive = () => {
if (
drawCache.segmentLinePrimitive &&
scene.groundPrimitives.contains(drawCache.segmentLinePrimitive)
) {
scene.groundPrimitives.remove(drawCache.segmentLinePrimitive);
}
};
const drawPrimitive = () => {
if (!drawCache.startWC || !drawCache.endWC) {
return;
}
const p = new Cesium.GroundPolylinePrimitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: [drawCache.startWC, drawCache.endWC],
width: 5.0,
vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
}),
}),
asynchronous: false,
appearance: new Cesium.PolylineMaterialAppearance({
material: Cesium.Material.fromType(
Cesium.Material.PolylineOutlineType
),
}),
});
drawCache.segmentLinePrimitive = scene.groundPrimitives.add(p);
};
const onClick = ({ position }) => {
if (stage === 0) {
removePrimitive();
drawCache.startWC = getWC(position);
dynamicDrawing = true;
stage++;
} else {
drawCache.endWC = getWC(position);
removePrimitive(); // 移除 mouse_move 残留那一个
drawPrimitive();
drawCache.startWC = null;
drawCache.endWC = null;
dynamicDrawing = false;
stage = 0;
}
};
const onMouseMouve = ({ endPosition }) => {
if (!dynamicDrawing) {
return;
}
removePrimitive();
drawCache.endWC = getWC(endPosition);
drawPrimitive();
};
h.setInputAction(onClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);
h.setInputAction(onMouseMouve, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment