| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826 |
- <template>
- <div id="draw-panel" class="sm-panel" v-drag>
- <div class="sm-function-module-sub-section" style="margin:0" v-stopdrag>
- <div class="sm-half-L">
- <label style="width:auto">
- <input type="radio" value="single" v-model="drawMode" />
- 单个
- </label>
- <label style="width:auto">
- <input type="radio" value="continuous" v-model="drawMode" />
- 连续
- </label>
- </div>
- <div class="sm-half-L symbolic">
- <div
- v-for="model in basicGeometries"
- :key="model.type"
- class="symbolic-box"
- style="width: 40px;"
- :class="{ 'theme-border-color': selectedModel && selectedModel.type === model.type }"
- @click="selectModel(model)"
- >
- <img :src="model.thumbnail" alt="" class="model-thumbnail" />
- <label style="width:100%">{{ model.name }}</label>
- </div>
- </div>
- <div class="sm-half-L">
- <label style="width: 35%;">颜色</label>
- <el-color-picker v-model="selectedColor" size="mini" style="width:63%"></el-color-picker>
- </div>
- <div class="sm-half-L">
- <label style="width: 35%;">透明度</label>
- <el-slider v-model="selectedOpacity" :min="0" :max="1" :step="0.1" style="width:63%"></el-slider>
- </div>
- <div class="sm-half-L" v-if="selectedEntity">
- <label style="width: 35%;">位置 X</label>
- <input type="number" class="sm-input" style="width:63%" step="0.1" v-model="position.x" />
- </div>
- <div class="sm-half-L" v-if="selectedEntity">
- <label style="width: 35%;">位置 Y</label>
- <input type="number" class="sm-input" style="width:63%" step="0.1" v-model="position.y" />
- </div>
- <div class="sm-half-L" v-if="selectedEntity">
- <label style="width: 35%;">位置 Z</label>
- <input type="number" class="sm-input" style="width:63%" step="0.1" v-model="position.z" />
- </div>
- <div class="sm-half-L" v-if="selectedEntity" style="display: flex; align-items: center;">
- <label style="width: 35%;">旋转</label>
- <div style="width:63%; display: flex; gap: 4px;">
- <input type="number" class="sm-input" style="flex: 1; width: 45px;" step="1" v-model="rotation.x" />
- <input type="number" class="sm-input" style="flex: 1; width: 45px;" step="1" v-model="rotation.y" />
- <input type="number" class="sm-input" style="flex: 1; width: 45px;" step="1" v-model="rotation.z" />
- </div>
- </div>
- <div class="sm-half-L" v-if="selectedEntity" style="display: flex; align-items: center;">
- <label style="width: 35%;">缩放</label>
- <div style="width:63%; display: flex; gap: 4px;">
- <input type="number" class="sm-input" style="flex: 1; width: 45px;" step="0.1" min="0.1" v-model="scale.x" />
- <input type="number" class="sm-input" style="flex: 1; width: 45px;" step="0.1" min="0.1" v-model="scale.y" />
- <input type="number" class="sm-input" style="flex: 1; width: 45px;" step="0.1" min="0.1" v-model="scale.z" />
- </div>
- </div>
- <div class="boxchild">
- <button class="tbtn" type="button" v-on:click="startDraw">{{ isDrawing ? '停止绘制' : '绘制' }}</button>
- <button class="tbtn tbtn-margin-left" type="button" v-on:click="clear">清除</button>
- <button class="tbtn tbtn-margin-left" type="button" v-on:click="close">关闭</button>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { ref, onMounted, onUnmounted, reactive, watch } from 'vue';
- import { ElMessage } from 'element-plus';
- export default {
- name: 'Sm3dDrawSolidFigure',
- emits: ['close'],
- setup(props, { emit }) {
- // 基础几何体模型
- const basicGeometries = ref([
- {
- type: 'box',
- name: '立方体',
- thumbnail: '/img/componentsImg/draw-solid-figuree.png',
- dimensions: { x: 1, y: 1, z: 1 }
- },
- {
- type: 'cylinder',
- name: '圆柱体',
- thumbnail: '/img/componentsImg/draw-solid-figuree.png',
- dimensions: { length: 1, radius: 0.5 }
- },
- {
- type: 'sphere',
- name: '球体',
- thumbnail: '/img/componentsImg/draw-solid-figuree.png',
- dimensions: { radius: 0.5 }
- },
- {
- type: 'cone',
- name: '圆锥体',
- thumbnail: '/img/componentsImg/draw-solid-figuree.png',
- dimensions: { length: 1, radius: 0.5 }
- }
- ]);
- // 选中的实体
- const selectedEntity = ref(null);
- // 选中实体的属性
- const selectedColor = ref('#409eff');
- const selectedOpacity = ref(0.8);
- const position = reactive({ x: 0, y: 0, z: 0 });
- const rotation = reactive({ x: 0, y: 0, z: 0 });
- const scale = reactive({ x: 1, y: 1, z: 1 });
- // 绘制模式
- const drawMode = ref('single');
- // 选中的模型类型
- const selectedModel = ref(null);
- // 绘制状态
- const isDrawing = ref(false);
- // 绘制激活标志,用于区分是否正在进行绘制(避免与选中实体冲突)
- let isDrawHandlerActive = false;
- // 防止循环更新的标志
- let isUpdatingProperties = false;
- let viewer = null;
- let currentEditor = null;
- const close = () => {
- // 通知父组件关闭此组件
- emit('close', 'Sm3dDrawSolidFigure');
- };
- // 选择模型类型
- const selectModel = (model) => {
- selectedModel.value = model;
- ElMessage.success(`已选择 ${model.name}`);
- };
- // 开始绘制
- const startDraw = () => {
- console.log('startDraw called, isDrawing:', isDrawing.value, 'selectedModel:', selectedModel.value);
- if (!selectedModel.value) {
- ElMessage.warning('请先选择模型类型');
- return;
- }
- isDrawing.value = !isDrawing.value;
- console.log('After toggle, isDrawing:', isDrawing.value);
- if (isDrawing.value) {
- // 清除之前选中的实体的高亮
- if (selectedEntity.value) {
- removeHighlight(selectedEntity.value);
- if (currentEditor) {
- currentEditor.deactivate();
- currentEditor = null;
- }
- selectedEntity.value = null;
- }
- isDrawHandlerActive = true;
- viewer.enableCursorStyle = false;
- viewer._element.style.cursor = 'crosshair';
- ElMessage.success(`开始${drawMode.value === 'single' ? '单个' : '连续'}绘制模式`);
- } else {
- ElMessage.info('已停止绘制');
- selectedModel.value = null;
- isDrawHandlerActive = false;
- viewer.enableCursorStyle = true;
- viewer._element.style.cursor = 'default';
- }
- };
- // 清除所有模型
- const clear = () => {
- if (viewer) {
- viewer.entities.removeAll();
- selectedEntity.value = null;
- selectedModel.value = null;
- isDrawing.value = false;
- if (currentEditor) {
- currentEditor.deactivate();
- currentEditor = null;
- }
- ElMessage.success('已清除所有模型');
- }
- };
- // 左键点击处理
- const onLeftClick = (movement) => {
- console.log('=== Left click ===');
- console.log('isDrawing:', isDrawing.value);
- console.log('selectedModel:', selectedModel.value);
- console.log('drawMode:', drawMode.value);
- // 绘制模式
- if (isDrawing.value === true && selectedModel.value !== null) {
- console.log('Entering DRAW mode');
- let position = viewer.scene.pickPosition(movement.position);
- console.log('Position:', position, 'defined:', Cesium.defined(position));
- if (!Cesium.defined(position)) {
- console.warn('Cannot get position');
- return;
- }
- createGeometry(position, selectedModel.value);
- console.log('Geometry created, drawMode:', drawMode.value);
- if (drawMode.value === 'single') {
- console.log('Single mode - stopping draw');
- isDrawing.value = false;
- isDrawHandlerActive = false;
- selectedModel.value = null;
- viewer.enableCursorStyle = true;
- viewer._element.style.cursor = 'default';
- ElMessage.info('已完成单个绘制');
- } else {
- console.log('Continuous mode - continuing');
- }
- return;
- }
- console.log('Entering SELECT mode');
- // 非绘制模式:选择实体
- let pickedObject = viewer.scene.pick(movement.position);
- console.log('Picked object:', pickedObject);
- if (Cesium.defined(pickedObject) && pickedObject.id) {
- selectEntity(pickedObject.id);
- } else if (isDrawing.value === false) {
- clearSelection();
- }
- };
- // 右键点击处理
- const onRightClick = (movement) => {
- console.log('=== Right click ===');
- console.log('isDrawing:', isDrawing.value);
- console.log('drawMode:', drawMode.value);
- console.log('Condition result:', isDrawing.value === true && drawMode.value === 'continuous');
- if (isDrawing.value === true && drawMode.value === 'continuous') {
- console.log('Stopping continuous draw');
- isDrawing.value = false;
- isDrawHandlerActive = false;
- selectedModel.value = null;
- viewer.enableCursorStyle = true;
- viewer._element.style.cursor = 'default';
- ElMessage.info('已结束连续绘制');
- }
- };
- // 阻止右键默认菜单
- const onContextMenu = (event) => {
- if (isDrawing.value) {
- event.preventDefault();
- }
- };
- // 键盘事件处理函数
- const handleKeyDown = (event) => {
- if (event.key === 'Enter') {
- event.preventDefault();
- }
- };
- // 初始化场景事件
- const initSceneEvents = () => {
- if (!viewer) return;
- // 左键点击 - 绘制或选择
- viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
- viewer.screenSpaceEventHandler.setInputAction(onLeftClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- // 右键点击 - 结束连续绘制
- viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
- viewer.screenSpaceEventHandler.setInputAction(onRightClick, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
- // 阻止右键默认菜单
- viewer._element.addEventListener('contextmenu', onContextMenu);
- // 键盘事件
- document.addEventListener('keydown', handleKeyDown);
- };
- // 清理事件
- const cleanupEvents = () => {
- if (viewer) {
- viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
- viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
- viewer._element.removeEventListener('contextmenu', onContextMenu);
- viewer.enableCursorStyle = true;
- viewer._element.style.cursor = 'default';
- }
- document.removeEventListener('keydown', handleKeyDown);
- if (currentEditor) {
- currentEditor.deactivate();
- currentEditor = null;
- }
- isDrawing.value = false;
- isDrawHandlerActive = false;
- };
- // 选择实体
- const selectEntity = (entity) => {
- if (selectedEntity.value) {
- removeHighlight(selectedEntity.value);
- if (currentEditor) {
- currentEditor.deactivate();
- currentEditor = null;
- }
- }
- selectedEntity.value = entity;
- updateSelectedEntityProperties();
- addHighlight(entity);
- addEditor(entity);
- };
- // 清除选择
- const clearSelection = () => {
- if (selectedEntity.value) {
- removeHighlight(selectedEntity.value);
- if (currentEditor) {
- currentEditor.deactivate();
- currentEditor = null;
- }
- selectedEntity.value = null;
- }
- };
- // 添加模型高亮效果
- const addHighlight = (entity) => {
- if (!entity) return;
- // 保存原始状态(只在第一次保存)
- if (entity.box) {
- if (entity.originalOutline === undefined) {
- entity.originalOutline = entity.box.outline;
- entity.originalOutlineColor = entity.box.outlineColor;
- }
- entity.box.outline = true;
- entity.box.outlineColor = new Cesium.Color(1, 1, 0, 1);
- } else if (entity.cylinder) {
- if (entity.originalOutline === undefined) {
- entity.originalOutline = entity.cylinder.outline;
- entity.originalOutlineColor = entity.cylinder.outlineColor;
- }
- entity.cylinder.outline = true;
- entity.cylinder.outlineColor = new Cesium.Color(1, 1, 0, 1);
- } else if (entity.ellipsoid) {
- if (entity.originalOutline === undefined) {
- entity.originalOutline = entity.ellipsoid.outline;
- entity.originalOutlineColor = entity.ellipsoid.outlineColor;
- }
- entity.ellipsoid.outline = true;
- entity.ellipsoid.outlineColor = new Cesium.Color(1, 1, 0, 1);
- }
- };
- // 移除模型高亮效果
- const removeHighlight = (entity) => {
- if (!entity) return;
- if (entity.box) {
- if (entity.originalOutline !== undefined) {
- entity.box.outline = entity.originalOutline;
- entity.box.outlineColor = entity.originalOutlineColor;
- } else {
- entity.box.outline = false;
- }
- } else if (entity.cylinder) {
- if (entity.originalOutline !== undefined) {
- entity.cylinder.outline = entity.originalOutline;
- entity.cylinder.outlineColor = entity.originalOutlineColor;
- } else {
- entity.cylinder.outline = false;
- }
- } else if (entity.ellipsoid) {
- if (entity.originalOutline !== undefined) {
- entity.ellipsoid.outline = entity.originalOutline;
- entity.ellipsoid.outlineColor = entity.originalOutlineColor;
- } else {
- entity.ellipsoid.outline = false;
- }
- }
- };
- // 添加操作轴编辑器
- const addEditor = (entity) => {
- if (!entity) return;
- // 清除之前的编辑器
- if (currentEditor) {
- currentEditor.deactivate();
- currentEditor = null;
- }
- };
- // 创建几何体
- const createGeometry = (position, model) => {
- if (!viewer) return;
- const color = Cesium.Color.fromCssColorString(selectedColor.value).withAlpha(selectedOpacity.value);
- let entity;
- switch (model.type) {
- case 'box':
- entity = viewer.entities.add({
- position: position,
- box: {
- dimensions: new Cesium.Cartesian3(model.dimensions.x, model.dimensions.y, model.dimensions.z),
- material: new Cesium.ColorMaterialProperty(color)
- },
- modelType: model.type,
- modelName: model.name,
- originalDimensions: new Cesium.Cartesian3(model.dimensions.x, model.dimensions.y, model.dimensions.z),
- _rotation: { x: 0, y: 0, z: 0 },
- _scale: { x: 1, y: 1, z: 1 }
- });
- break;
- case 'sphere':
- entity = viewer.entities.add({
- position: position,
- ellipsoid: {
- radii: new Cesium.Cartesian3(model.dimensions.radius, model.dimensions.radius, model.dimensions.radius),
- material: new Cesium.ColorMaterialProperty(color)
- },
- modelType: model.type,
- modelName: model.name,
- originalDimensions: new Cesium.Cartesian3(model.dimensions.radius, model.dimensions.radius, model.dimensions.radius),
- _rotation: { x: 0, y: 0, z: 0 },
- _scale: { x: 1, y: 1, z: 1 }
- });
- break;
- case 'cylinder':
- entity = viewer.entities.add({
- position: position,
- cylinder: {
- length: model.dimensions.length,
- topRadius: model.dimensions.radius,
- bottomRadius: model.dimensions.radius,
- material: new Cesium.ColorMaterialProperty(color)
- },
- modelType: model.type,
- modelName: model.name,
- originalDimensions: {
- length: model.dimensions.length,
- topRadius: model.dimensions.radius,
- bottomRadius: model.dimensions.radius
- },
- _rotation: { x: 0, y: 0, z: 0 },
- _scale: { x: 1, y: 1, z: 1 }
- });
- break;
- case 'ellipsoid':
- entity = viewer.entities.add({
- position: position,
- ellipsoid: {
- radii: new Cesium.Cartesian3(model.dimensions.x, model.dimensions.y, model.dimensions.z),
- material: new Cesium.ColorMaterialProperty(color)
- },
- modelType: model.type,
- modelName: model.name,
- originalDimensions: new Cesium.Cartesian3(model.dimensions.x, model.dimensions.y, model.dimensions.z),
- _rotation: { x: 0, y: 0, z: 0 },
- _scale: { x: 1, y: 1, z: 1 }
- });
- break;
- case 'cone':
- entity = viewer.entities.add({
- position: position,
- cylinder: {
- length: model.dimensions.length,
- topRadius: 0,
- bottomRadius: model.dimensions.radius,
- material: new Cesium.ColorMaterialProperty(color)
- },
- modelType: model.type,
- modelName: model.name,
- originalDimensions: {
- length: model.dimensions.length,
- topRadius: 0,
- bottomRadius: model.dimensions.radius
- },
- _rotation: { x: 0, y: 0, z: 0 },
- _scale: { x: 1, y: 1, z: 1 }
- });
- break;
- default:
- return;
- }
- if (entity) {
- ElMessage.success(`${model.name} 创建成功`);
- // 清除之前的高亮和编辑器
- if (selectedEntity.value) {
- removeHighlight(selectedEntity.value);
- if (currentEditor) {
- currentEditor.deactivate();
- currentEditor = null;
- }
- }
- selectedEntity.value = entity;
- updateSelectedEntityProperties();
- // 添加高亮效果
- addHighlight(entity);
- // 添加操作轴
- addEditor(entity);
- return entity;
- }
- return null;
- };
- // 更新选中实体的属性
- const updateSelectedEntityProperties = () => {
- if (!selectedEntity.value) return;
- console.log('Updating properties for entity:', selectedEntity.value);
- // 获取实体
- const entity = selectedEntity.value;
- // 设置标志,防止循环更新
- isUpdatingProperties = true;
- // 更新位置(经纬度保留6位小数,高度保留6位小数)
- const cartesian = entity.position.getValue(viewer.clock.currentTime);
- if (cartesian) {
- const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
- position.x = Number(Cesium.Math.toDegrees(cartographic.longitude).toFixed(6));
- position.y = Number(Cesium.Math.toDegrees(cartographic.latitude).toFixed(6));
- position.z = Number(cartographic.height.toFixed(6));
- }
- // 更新颜色和透明度
- let material = null;
- if (entity.box) {
- material = entity.box.material;
- } else if (entity.cylinder) {
- material = entity.cylinder.material;
- } else if (entity.ellipsoid) {
- material = entity.ellipsoid.material;
- }
- if (material) {
- let color = null;
- if (material.color) {
- if (typeof material.color.getValue === 'function') {
- color = material.color.getValue(viewer.clock.currentTime);
- } else {
- color = material.color;
- }
- }
- if (color instanceof Cesium.Color) {
- selectedColor.value = color.toCssColorString();
- selectedOpacity.value = Number(color.alpha.toFixed(2));
- } else if (material instanceof Cesium.Color) {
- selectedColor.value = material.toCssColorString();
- selectedOpacity.value = Number(material.alpha.toFixed(2));
- }
- }
- // 更新旋转(保留2位小数)
- if (entity._rotation) {
- // 优先使用保存的旋转值
- rotation.x = Number(entity._rotation.x.toFixed(2));
- rotation.y = Number(entity._rotation.y.toFixed(2));
- rotation.z = Number(entity._rotation.z.toFixed(2));
- } else if (entity.orientation) {
- try {
- const orientation = entity.orientation.getValue ? entity.orientation.getValue(viewer.clock.currentTime) : entity.orientation;
- if (orientation) {
- const hpr = Cesium.HeadingPitchRoll.fromQuaternion(orientation);
- rotation.x = Number(Cesium.Math.toDegrees(hpr.pitch).toFixed(2));
- rotation.y = Number(Cesium.Math.toDegrees(hpr.heading).toFixed(2));
- rotation.z = Number(Cesium.Math.toDegrees(hpr.roll).toFixed(2));
- // 保存初始旋转值
- entity._rotation = { x: rotation.x, y: rotation.y, z: rotation.z };
- }
- } catch (error) {
- console.error('Error updating rotation:', error);
- }
- } else {
- rotation.x = 0;
- rotation.y = 0;
- rotation.z = 0;
- // 保存初始旋转值
- entity._rotation = { x: 0, y: 0, z: 0 };
- }
- // 更新缩放 - 从实体保存的原始尺寸计算(保留2位小数)
- if (entity._scale) {
- // 优先使用保存的缩放值
- scale.x = Number(entity._scale.x.toFixed(2));
- scale.y = Number(entity._scale.y.toFixed(2));
- scale.z = Number(entity._scale.z.toFixed(2));
- } else if (entity.box) {
- if (entity.originalDimensions) {
- const currentDimensions = entity.box.dimensions.getValue ? entity.box.dimensions.getValue(viewer.clock.currentTime) : entity.box.dimensions;
- if (currentDimensions && entity.originalDimensions) {
- scale.x = Number((currentDimensions.x / entity.originalDimensions.x).toFixed(2));
- scale.y = Number((currentDimensions.y / entity.originalDimensions.y).toFixed(2));
- scale.z = Number((currentDimensions.z / entity.originalDimensions.z).toFixed(2));
- // 保存缩放值
- entity._scale = { x: scale.x, y: scale.y, z: scale.z };
- }
- } else {
- scale.x = 1;
- scale.y = 1;
- scale.z = 1;
- // 保存缩放值
- entity._scale = { x: 1, y: 1, z: 1 };
- }
- } else if (entity.cylinder) {
- if (entity.originalDimensions) {
- const currentLength = entity.cylinder.length.getValue ? entity.cylinder.length.getValue(viewer.clock.currentTime) : entity.cylinder.length;
- const currentTopRadius = entity.cylinder.topRadius.getValue ? entity.cylinder.topRadius.getValue(viewer.clock.currentTime) : entity.cylinder.topRadius;
- const currentBottomRadius = entity.cylinder.bottomRadius.getValue ? entity.cylinder.bottomRadius.getValue(viewer.clock.currentTime) : entity.cylinder.bottomRadius;
- if (currentLength && entity.originalDimensions.length) {
- // X轴向控制一个方向的半径,Y轴向控制另一个方向的半径,Z轴向控制高度
- scale.x = Number((currentTopRadius / entity.originalDimensions.topRadius).toFixed(2));
- scale.y = Number((currentBottomRadius / entity.originalDimensions.bottomRadius).toFixed(2));
- scale.z = Number((currentLength / entity.originalDimensions.length).toFixed(2));
- // 保存缩放值
- entity._scale = { x: scale.x, y: scale.y, z: scale.z };
- }
- } else {
- scale.x = 1;
- scale.y = 1;
- scale.z = 1;
- // 保存缩放值
- entity._scale = { x: 1, y: 1, z: 1 };
- }
- } else if (entity.ellipsoid) {
- if (entity.originalDimensions) {
- const currentRadii = entity.ellipsoid.radii.getValue ? entity.ellipsoid.radii.getValue(viewer.clock.currentTime) : entity.ellipsoid.radii;
- if (currentRadii && entity.originalDimensions) {
- scale.x = Number((currentRadii.x / entity.originalDimensions.x).toFixed(2));
- scale.y = Number((currentRadii.y / entity.originalDimensions.y).toFixed(2));
- scale.z = Number((currentRadii.z / entity.originalDimensions.z).toFixed(2));
- // 保存缩放值
- entity._scale = { x: scale.x, y: scale.y, z: scale.z };
- }
- } else {
- scale.x = 1;
- scale.y = 1;
- scale.z = 1;
- // 保存缩放值
- entity._scale = { x: 1, y: 1, z: 1 };
- }
- }
- // 重置标志
- isUpdatingProperties = false;
- console.log('Updated properties:', {
- selectedColor: selectedColor.value,
- selectedOpacity: selectedOpacity.value,
- rotation: rotation,
- scale: scale
- });
- };
- // 监听属性变化,更新实体
- watch(selectedColor, (newColor) => {
- if (!selectedEntity.value) return;
- const color = Cesium.Color.fromCssColorString(newColor).withAlpha(selectedOpacity.value);
- const material = new Cesium.ColorMaterialProperty(color);
- if (selectedEntity.value.box) {
- selectedEntity.value.box.material = material;
- } else if (selectedEntity.value.cylinder) {
- selectedEntity.value.cylinder.material = material;
- } else if (selectedEntity.value.ellipsoid) {
- selectedEntity.value.ellipsoid.material = material;
- }
- });
- watch(selectedOpacity, (newOpacity) => {
- if (!selectedEntity.value) return;
- const color = Cesium.Color.fromCssColorString(selectedColor.value).withAlpha(newOpacity);
- const material = new Cesium.ColorMaterialProperty(color);
- if (selectedEntity.value.box) {
- selectedEntity.value.box.material = material;
- } else if (selectedEntity.value.cylinder) {
- selectedEntity.value.cylinder.material = material;
- } else if (selectedEntity.value.ellipsoid) {
- selectedEntity.value.ellipsoid.material = material;
- }
- });
- watch(position, (newPosition) => {
- if (!selectedEntity.value) return;
- const cartesian = Cesium.Cartesian3.fromDegrees(newPosition.x, newPosition.y, newPosition.z);
- selectedEntity.value.position = cartesian;
- }, { deep: true });
- watch(scale, (newScale) => {
- if (!selectedEntity.value) return;
- console.log('Scale changed:', newScale, 'Entity:', selectedEntity.value);
- // 保存缩放值到实体对象中(使用对象字面量创建新对象,避免引用问题)
- selectedEntity.value._scale = { x: newScale.x, y: newScale.y, z: newScale.z };
- // 保存原始尺寸,避免累积缩放
- if (selectedEntity.value.box) {
- // 保存原始尺寸
- if (!selectedEntity.value.originalDimensions) {
- selectedEntity.value.originalDimensions = selectedEntity.value.box.dimensions.getValue(viewer.clock.currentTime);
- }
- const originalDimensions = selectedEntity.value.originalDimensions;
- selectedEntity.value.box.dimensions = new Cesium.Cartesian3(originalDimensions.x * newScale.x, originalDimensions.y * newScale.y, originalDimensions.z * newScale.z);
- } else if (selectedEntity.value.cylinder) {
- // 保存原始尺寸
- if (!selectedEntity.value.originalDimensions) {
- selectedEntity.value.originalDimensions = {
- length: selectedEntity.value.cylinder.length.getValue(viewer.clock.currentTime),
- topRadius: selectedEntity.value.cylinder.topRadius.getValue(viewer.clock.currentTime),
- bottomRadius: selectedEntity.value.cylinder.bottomRadius.getValue(viewer.clock.currentTime)
- };
- }
- const originalDimensions = selectedEntity.value.originalDimensions;
- // X轴向控制一个方向的半径,Y轴向控制另一个方向的半径,Z轴向控制高度
- selectedEntity.value.cylinder.length = originalDimensions.length * newScale.z;
- selectedEntity.value.cylinder.topRadius = originalDimensions.topRadius * newScale.x;
- selectedEntity.value.cylinder.bottomRadius = originalDimensions.bottomRadius * newScale.y;
- } else if (selectedEntity.value.ellipsoid) {
- // 保存原始尺寸
- if (!selectedEntity.value.originalDimensions) {
- selectedEntity.value.originalDimensions = selectedEntity.value.ellipsoid.radii.getValue(viewer.clock.currentTime);
- }
- const originalDimensions = selectedEntity.value.originalDimensions;
- selectedEntity.value.ellipsoid.radii = new Cesium.Cartesian3(originalDimensions.x * newScale.x, originalDimensions.y * newScale.y, originalDimensions.z * newScale.z);
- }
- }, { deep: true });
- // 监听旋转变化,更新实体
- watch(rotation, (newRotation) => {
- if (!selectedEntity.value || isUpdatingProperties) return;
- // 计算旋转矩阵
- const heading = Cesium.Math.toRadians(newRotation.y);
- const pitch = Cesium.Math.toRadians(newRotation.x);
- const roll = Cesium.Math.toRadians(newRotation.z);
- const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
- const orientation = Cesium.Transforms.headingPitchRollQuaternion(
- selectedEntity.value.position.getValue(viewer.clock.currentTime),
- hpr
- );
- selectedEntity.value.orientation = orientation;
- // 保存原始旋转值到实体
- selectedEntity.value._rotation = { ...newRotation };
- }, { deep: true });
- onMounted(() => {
- console.log('Sm3dDrawSolidFigure mounted, viewer:', window.viewer);
- viewer = window.viewer;
- if (viewer) {
- console.log('Initializing scene events...');
- initSceneEvents();
- } else {
- console.error('Viewer not found!');
- }
- });
- onUnmounted(() => {
- // 清理事件
- cleanupEvents();
- });
- return {
- basicGeometries,
- selectedEntity,
- selectedColor,
- selectedOpacity,
- position,
- rotation,
- scale,
- drawMode,
- selectedModel,
- isDrawing,
- close,
- selectModel,
- startDraw,
- clear
- };
- }
- };
- </script>
- <style scoped>
- .model-thumbnail {
- width: 30px;
- height: 30px;
- object-fit: cover;
- margin-bottom: 5px;
- }
- .symbolic-box {
- text-align: center;
- cursor: pointer;
- padding: 5px;
- border-radius: 4px;
- transition: all 0.3s;
- }
- .symbolic-box:hover {
- background-color: #f0f0f0;
- }
- .symbolic-box.theme-border-color {
- background-color: #ecf5ff;
- border: 1px solid #409eff;
- box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
- }
- .symbolic-box label {
- font-size: 12px;
- color: #606266;
- display: block;
- margin-top: 5px;
- }
- .symbolic-box.theme-border-color label {
- color: #409eff;
- font-weight: 500;
- }
- </style>
|