/** * 水柱特效 */ import Dialog from '../../../Element/Dialog'; import { html, css } from "./_element"; import Base from "../../index"; import MouseEvent from '../../../../Event/index' import { syncData, getSdk as get2DSdk } from '../../../../Global/MultiViewportMode' import MouseTip from '../../../../MouseTip' import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen' import { setActiveViewer, closeRotateAround, closeViewFollow } from '../../../../Global/global' class Spout extends Base { /** * @constructor * @description 水柱 * @param sdk * @param options {object} 粒子属性 * @param options.show=true {boolean} 显示/隐藏 * @param options.name {string} 名称 * @param options.url {string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement} 指定 Image、URL或Canvas 的属性 * @param options.startColor="#c1f7f2" {string} 起始颜色 * @param options.endColor="#ffffff00" {string} 结束颜色 * @param options.startScale=0.2 {number} 初始比例 * @param options.endScale=2 {number} 结束比例 * @param options.speed {number} 速度 * @param options.minimumParticleLife=12 {number} 最小存在时间(秒) * @param options.maximumParticleLife=12 {number} 最大存在时间(秒) * @param options.emissionRate=100 {number} 发射速率(个/每秒) * @param options.particleSize=1 {number} 粒子尺大小 * @param options.heading 朝向 * @param options.pitch 俯仰角度 * @param options.start {object} 开始位置 * @param options.start.lng 经度 * @param options.start.lat 纬度 * @param options.start.alt 高度 * @param options.end {object} 结束位置 * @param options.end.lng 经度 * @param options.end.lat 纬度 * @param options.end.alt 高度 * @param _Dialog {object} 弹框事件 * @param _Dialog.confirmCallBack {function} 弹框确认时的回调 * */ constructor(sdk, options, _Dialog = {}) { super(sdk, options); this.options.url = options.url this.options.startColor = options.startColor || "#c1f7f2" this.options.endColor = options.endColor || "#ffffff00" this.options.startScale = options.startScale || 0.2 this.options.endScale = options.endScale || 2 this.options.minimumParticleLife = options.minimumParticleLife || 12 this.options.maximumParticleLife = options.maximumParticleLife || 12 this.options.emissionRate = options.emissionRate || 100 this.options.particleSize = options.particleSize || 1 this.options.show = options.show === false ? false : true this._elms = {}; this.positionCallBack = null this.rotationCallback = null this.onClickCallback = null this._DialogObject = null this._element = null this.particleSystem this.sdk.addIncetance(this.options.id, this) this.add() this.operate = {} this.previous = { positions: { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt, } } this.Dialog = _Dialog this.event = new MouseEvent(this.sdk) } get type() { return "ParticleEffects" } get show() { return this.options.show } set show(v) { if (typeof v === "boolean") { let sdkD = get2DSdk().sdkD if (!this.isShowView || !sdkD) { this.options.show = v } if (!this.showView || this.showView == 3 || !sdkD) { if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) { this.entity.show = this.options.show } if (this.options.label && this.options.label.show) { this.label.show = this.options.show } } else { if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) { this.entity.show = false } if (this.options.label && this.options.label.show) { this.label.show = false } } if(this._DialogObject && this._DialogObject.showBtn) { this._DialogObject.showBtn.checked = v } syncData(this.sdk, this.options.id) syncSplitData(this.sdk, this.options.id) this.isShowView = false } else { console.error("参数必须为boolean") } } async add() { let _this = this this.originalOptions = this.deepCopyObj(this.options) const scene = this.sdk.viewer.scene; let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt); let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic); let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(1, 1, 1), matrix) let gravityVector = new Cesium.Cartesian3(); let gravity = -3.8;// 重力方向 let start = Cesium.Cartesian3.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt) let end = Cesium.Cartesian3.fromDegrees(this.options.end.lng, this.options.end.lat, this.options.end.alt) if (!this.options.heading && this.options.heading !== 0) { this.options.heading = getHeading(start, end) } let y0 = this.options.end.alt - this.options.start.alt let x0 = Cesium.Cartesian3.distance(start, Cesium.Cartesian3.fromDegrees(this.options.end.lng, this.options.end.lat, this.options.start.alt)) let tanA if (!y0) { tanA = 0 } else { tanA = 2 * y0 / x0 } let a = Math.atan(tanA) * (180 / Math.PI); let t = Math.sqrt((Math.abs(tanA) * x0) / -gravity) let speed = -gravity * t / Math.abs(Math.cos(a)) if (!this.options.pitch && this.options.pitch !== 0) { this.options.pitch = 90 - a } if (!this.options.speed && this.options.speed !== 0) { this.options.speed = speed } let cameraHeight = this.sdk.viewer.camera.positionCartographic.height; // // 计算发射参数 // function calculateLaunchParameters(height, distance, gravity) { // // 解决斜抛运动问题:y = h + x·tan(θ) - (g·x²)/(2·v₀²·cos²(θ)) // // 当 y = 0, x = distance 时,求解 v₀ 和 θ // // 简化计算,使用最优角度 θ = 45° // const angle = Cesium.Math.toRadians(45); // // 计算初始速度 // const velocity = Math.sqrt((gravity * distance * distance) / // (2 * (height + distance * Math.tan(angle)) * Math.pow(Math.cos(angle), 2))); // // 计算飞行时间 // const vy0 = velocity * Math.sin(angle); // const flightTime = (vy0 + Math.sqrt(vy0 * vy0 + 2 * gravity * height)) / gravity; // // 计算最大高度 // const maxHeight = height + (vy0 * vy0) / (2 * gravity); // return { velocity, angle, flightTime, maxHeight }; // } // let params = { // launchHeight: this.options.start.alt, // 发射高度 // targetDistance: Cesium.Cartesian3.distance(start, end), // 目标距离 // gravity: 9.8, // 重力 // } // // 计算初始速度和发射角度 // const { velocity, angle, flightTime, maxHeight } = calculateLaunchParameters( // params.launchHeight, // params.targetDistance, // params.gravity // ); // if (!this.options.speed && this.options.speed !== 0) { // this.options.speed = velocity*10 // } this.particleSystem = scene.primitives.add( new Cesium.ParticleSystem({ show: (cameraHeight >= 10000000) ? false : this.options.show, image: this.options.url || (this.getSourceRootPath() + '/img/particlesystem/smoke.png'), // 从绿色到白色淡出 startColor: Cesium.Color.fromCssColorString(this.options.startColor), //粒子出生时的颜色 endColor: Cesium.Color.fromCssColorString(this.options.endColor), //当粒子死亡时的颜色 startScale: this.options.startScale, //粒子出生时的比例 endScale: this.options.endScale, //粒子在死亡时的比例 minimumParticleLife: this.options.minimumParticleLife, //设置粒子寿命的可能持续时间的最小界限(以秒为单位) maximumParticleLife: this.options.maximumParticleLife, //设置粒子寿命的可能持续时间的最大界限(以秒为单位) minimumSpeed: this.options.speed,//设置以米/秒为单位的最小界限,超过该最小界限,随机选择粒子的实际速度。 maximumSpeed: this.options.speed,//设置以米/秒为单位的最大界限,超过该最大界限,随机选择粒子的实际速度。 // imageSize: new Cesium.Cartesian2( //如果设置该属性,将会覆盖 minimumImageSize和maximumImageSize属性,以像素为单位缩放image的大小 // this.options.imageSize || 10, // this.options.imageSize || 10 // ), lifetime: 0.5, imageSize: new Cesium.Cartesian2(this.options.particleSize, this.options.particleSize * 2), sizeInMeters: true, emissionRate: this.options.emissionRate, //每秒发射的粒子数。 loop: true, emitter: new Cesium.CircleEmitter(0.2), modelMatrix: matrix, emitterModelMatrix: computeEmitterModelMatrix(),// 发射器转换为世界坐标 // 增加重力场影像, updateCallback: applyGravity, }) ); function applyGravity(p, dt) { p._billboard.id = _this.options.id let position = p.position; Cesium.Cartesian3.normalize(position, gravityVector); // Cesium.Cartesian3.multiplyByScalar(gravityVector, -4.8 * dt, gravityVector); Cesium.Cartesian3.multiplyByScalar(gravityVector, gravity * dt, gravityVector); p.velocity = Cesium.Cartesian3.add(p.velocity, gravityVector, p.velocity); } // 计算粒子发射器的位置姿态 function computeEmitterModelMatrix() { let hpr = Cesium.HeadingPitchRoll.fromDegrees(_this.options.heading + 90, _this.options.pitch, 0);//!!!发射粒子的方向 let trs = new Cesium.TranslationRotationScale(); trs.translation = Cesium.Cartesian3.fromElements(0, 0, 1); trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr); let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs); return Matrix4 } // 根据两个坐标点,获取Heading(朝向) function getHeading(fromPosition, toPosition) { let finalPosition = new Cesium.Cartesian3(); let matrix4 = Cesium.Transforms.eastNorthUpToFixedFrame(fromPosition); Cesium.Matrix4.inverse(matrix4, matrix4); Cesium.Matrix4.multiplyByPoint(matrix4, toPosition, finalPosition); Cesium.Cartesian3.normalize(finalPosition, finalPosition); return Cesium.Math.toDegrees(Math.atan2(finalPosition.x, finalPosition.y)); } // this.entity.modelMatrix this.particleSystem.id = this.options.id this.entity = this.particleSystem // this.entity.modelMatrix = Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(100.0, 20.0)), new Cesium.Cartesian3(0.0, 0.0, 10000.0), new Cesium.Matrix4()) this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt } // this.editObj = new EditParticle(this.sdk, this.entity) syncData(this.sdk, this.options.id) if (this.options.show) { setSplitDirection(0, this.options.id) } // 监听相机高度 this.sdk.viewer.camera.changed.addEventListener(() => { if (this.entity && this.show) { let cameraHeight = this.sdk.viewer.camera.positionCartographic.height; if (cameraHeight >= 10000000) { this.entity.show = false } else { this.entity.show = true } } }); // this.translation = new Cesium.Cartesian3(); // this.rotation = new Cesium.Quaternion(); // this.hpr = new Cesium.HeadingPitchRoll(); // this.trs = new Cesium.TranslationRotationScale(); // this.emitterModelMatrix = new Cesium.Matrix4(); // this.hpr = Cesium.HeadingPitchRoll.fromDegrees(60, 0.0, 0.0, this.hpr); // this.trs.translation = Cesium.Cartesian3.fromElements(0, 0, 0, this.translation); // this.trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(this.hpr, this.rotation); // this.particleSystem.emitterModelMatrix = Cesium.Matrix4.fromTranslationRotationScale(this.trs, this.emitterModelMatrix); } async flyTo(options = {}) { setActiveViewer(0) closeRotateAround(this.sdk) closeViewFollow(this.sdk) if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) { let orientation = { heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0), pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0), roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0) } let lng = this.options.customView.relativePosition.lng let lat = this.options.customView.relativePosition.lat let alt = this.options.customView.relativePosition.alt let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt) let position = { lng: 0, lat: 0 } if (this.options.position) { position = { ...this.options.position } } else if (this.options.positions) { position = { ...this.options.positions[0] } } else if (this.options.line && this.options.line.positions) { position = { ...this.options.line.positions[0] } } else if (this.options.center) { position = { ...this.options.center } } else if (this.options.start) { position = { ...this.options.start } } else { if (this.options.hasOwnProperty('lng')) { position.lng = this.options.lng } if (this.options.hasOwnProperty('lat')) { position.lat = this.options.lat } if (this.options.hasOwnProperty('alt')) { position.alt = this.options.alt } } // 如果没有高度值,则获取紧贴高度计算 if (!position.hasOwnProperty('alt')) { position.alt = await this.getClampToHeight(position) } lng = this.options.customView.relativePosition.lng + position.lng lat = this.options.customView.relativePosition.lat + position.lat alt = this.options.customView.relativePosition.alt + position.alt destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt) this.sdk.viewer.camera.flyTo({ destination: destination, orientation: orientation }) } else { this.sdk.viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt + 500), orientation: options.orientation || { heading: Cesium.Math.toRadians(0.0), pitch: Cesium.Math.toRadians(-90.0), roll: Cesium.Math.toRadians(0.0) } }) } } get startColor() { return this.options.startColor } set startColor(v) { this.options.startColor = v this.particleSystem.startColor = Cesium.Color.fromCssColorString(v) if (this._elms.startColor) { this._elms.startColor.forEach((item, i) => { let picker = new YJColorPicker({ el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: v, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (c) => { this.startColor = c },//点击确认按钮事件回调 clear: () => { this.startColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.startColor[i] = picker }) } } get endColor() { return this.options.endColor } set endColor(v) { this.options.endColor = v this.particleSystem.endColor = Cesium.Color.fromCssColorString(v) if (this._elms.endColor) { this._elms.endColor.forEach((item, i) => { let picker = new YJColorPicker({ el: item.el, size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: v, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (c) => { this.endColor = c },//点击确认按钮事件回调 clear: () => { this.endColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) this._elms.endColor[i] = picker }) } } get speed() { return this.options.speed } set speed(v) { this.options.speed = Number(v) this.particleSystem.minimumSpeed = Number(v) this.particleSystem.maximumSpeed = Number(v) this._elms.speed && this._elms.speed.forEach((item) => { item.value = Number(v) }) } get minimumParticleLife() { return this.options.minimumParticleLife } set minimumParticleLife(v) { this.options.minimumParticleLife = Number(v) this.particleSystem.minimumParticleLife = Number(v) this._elms.minimumParticleLife && this._elms.minimumParticleLife.forEach((item) => { item.value = Number(v) }) } get maximumParticleLife() { return this.options.maximumParticleLife } set maximumParticleLife(v) { this.options.maximumParticleLife = Number(v) this.particleSystem.maximumParticleLife = Number(v) this._elms.maximumParticleLife && this._elms.maximumParticleLife.forEach((item) => { item.value = Number(v) }) } get startScale() { return this.options.startScale } set startScale(v) { this.options.startScale = Number(v) this.particleSystem.startScale = Number(v) this._elms.startScale && this._elms.startScale.forEach((item) => { item.value = Number(v) }) } get endScale() { return this.options.endScale } set endScale(v) { this.options.endScale = Number(v) this.particleSystem.endScale = Number(v) this._elms.endScale && this._elms.endScale.forEach((item) => { item.value = Number(v) }) } get emissionRate() { return this.options.emissionRate } set emissionRate(v) { this.options.emissionRate = Number(v) this.particleSystem.emissionRate = Number(v) this._elms.emissionRate && this._elms.emissionRate.forEach((item) => { item.value = Number(v) }) } get particleSize() { return this.options.particleSize } set particleSize(v) { this.options.particleSize = Number(v) this.particleSystem.minimumImageSize = new Cesium.Cartesian2(Number(v), Number(v) * 2) this.particleSystem.maximumImageSize = new Cesium.Cartesian2(Number(v), Number(v) * 2) this._elms.particleSize && this._elms.particleSize.forEach((item) => { item.value = Number(v) }) } get lng() { return this.options.start.lng } set lng(v) { this.options.start.lng = v let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt); let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic); this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt } this._elms.lng && this._elms.lng.forEach((item) => { item.value = v }) } get lat() { return this.options.start.lat } set lat(v) { this.options.start.lat = v let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt); let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic); this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt } this._elms.lat && this._elms.lat.forEach((item) => { item.value = v }) } get alt() { return this.options.start.alt } set alt(v) { this.options.start.alt = v let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt); let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic); this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt } this._elms.alt && this._elms.alt.forEach((item) => { item.value = v }) } get heading() { return this.options.heading } set heading(v) { this.options.heading = Number(v) let hpr = Cesium.HeadingPitchRoll.fromDegrees(this.options.heading + 90, this.options.pitch, 0);//!!!发射粒子的方向 let trs = new Cesium.TranslationRotationScale(); trs.translation = Cesium.Cartesian3.fromElements(0, 0, 1); trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr); let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs); this.particleSystem.emitterModelMatrix = Matrix4 this._elms.heading && this._elms.heading.forEach((item) => { item.value = Number(v) }) } get pitch() { return this.options.pitch } set pitch(v) { this.options.pitch = Number(v) let hpr = Cesium.HeadingPitchRoll.fromDegrees(this.options.heading + 90, this.options.pitch, 0);//!!!发射粒子的方向 let trs = new Cesium.TranslationRotationScale(); trs.translation = Cesium.Cartesian3.fromElements(0, 0, 1); trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr); let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs); this.particleSystem.emitterModelMatrix = Matrix4 this._elms.pitch && this._elms.pitch.forEach((item) => { item.value = Number(v) }) } /** * @description 编辑框 * @param state=false {boolean} 状态: true打开, false关闭 */ async edit(state = false) { let _this = this this.originalOptions = this.deepCopyObj(this.options) // let elms = this.sdk.viewer._container.getElementsByClassName('YJ-custom-base-dialog') // for (let i = elms.length - 1; i >= 0; i--) { // this.sdk.viewer._container.removeChild(elms[i]) // } if (this._DialogObject && this._DialogObject.close) { this._DialogObject.close() this._DialogObject = null } if (state) { this._DialogObject = await new Dialog(this.sdk, this.originalOptions, { title: '喷射水柱属性', left: '180px', top: '100px', confirmCallBack: (options) => { this.name = this.name.trim() if (!this.name) { this.name = '未命名对象' } this.originalOptions = this.deepCopyObj(this.options) this._DialogObject.close() this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.originalOptions) syncData(this.sdk, this.options.id) syncSplitData(this.sdk, this.options.id) }, resetCallBack: () => { this.reset() this.Dialog.resetCallBack && this.Dialog.resetCallBack() }, removeCallBack: () => { this.Dialog.removeCallBack && this.Dialog.removeCallBack() }, closeCallBack: () => { this.reset() // this.entity.style = new Cesium.Cesium3DTileStyle({ // color: "color('rgba(255,255,255," + this.newData.transparency + ")')", // show: true, // }); this.positionEditing = false this.Dialog.closeCallBack && this.Dialog.closeCallBack() }, showCallBack: (show) => { this.show = show this.Dialog.showCallBack && this.Dialog.showCallBack() }, translationalCallBack: () => { this.positionEditing = !this.positionEditing } }, true) this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' particle-effects' let contentElm = document.createElement('div'); contentElm.innerHTML = html() this._DialogObject.contentAppChild(contentElm) // 颜色组件 let startColorPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("start_color")[0], size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.startColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.startColor = color },//点击确认按钮事件回调 clear: () => { this.startColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) let endColorPicker = new YJColorPicker({ el: contentElm.getElementsByClassName("end_color")[0], size: 'mini',//颜色box类型 alpha: true,//是否开启透明度 defaultColor: this.endColor, disabled: false,//是否禁止打开颜色选择器 openPickerAni: 'opacity',//打开颜色选择器动画 sure: (color) => { this.endColor = color },//点击确认按钮事件回调 clear: () => { this.endColor = 'rgba(255,255,255,1)' },//点击清空按钮事件回调 }) let all_elm = contentElm.getElementsByTagName("*") Spout.EventBinding(this, all_elm) this._elms.startColor = [startColorPicker] this._elms.endColor = [endColorPicker] } else { // if (this._element_style) { // document.getElementsByTagName('head')[0].removeChild(this._element_style) // this._element_style = null // } // if (this._DialogObject && this._DialogObject.remove) { // this._DialogObject.remove() // this._DialogObject = null // } } } reset() { if (!this.entity) { return } this.name = this.originalOptions.name this.startColor = this.originalOptions.startColor this.endColor = this.originalOptions.endColor this.speed = this.originalOptions.speed this.minimumParticleLife = this.originalOptions.minimumParticleLife this.maximumParticleLife = this.originalOptions.maximumParticleLife this.startScale = this.originalOptions.startScale this.endScale = this.originalOptions.endScale this.emissionRate = this.originalOptions.emissionRate this.particleSize = this.originalOptions.particleSize this.lng = this.originalOptions.start.lng this.lat = this.originalOptions.start.lat this.alt = this.originalOptions.start.alt } async remove() { super.remove() this.sdk.viewer.scene.primitives.remove(this.entity); this.entity = null if (this._DialogObject && !this._DialogObject.isDestroy) { this._DialogObject.close() this._DialogObject = null } this.tip && this.tip.destroy() this.event && this.event.destroy() await this.sdk.removeIncetance(this.options.id) await syncData(this.sdk, this.options.id) } /**@desc 打开平移功能 * * @memberOf Source * @param status {boolean} * * */ set positionEditing(status) { if (!this.sdk || !this.sdk.viewer || !this.entity) { return } this.operate.positionEditing = status if (status === true) { this.tip && this.tip.destroy() this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk) this.picking = false this.previous = { positions: { ...this.entity.position } } let movPos this.event.mouse_move((movement, cartesian) => { movPos = movement.endPosition let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer) this.options.start.lng = positions.lng this.options.start.lat = positions.lat this.options.start.alt = positions.alt let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt); let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic); this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) this._elms.lng && this._elms.lng.forEach((item) => { item.value = this.options.start.lng }) this._elms.lat && this._elms.lat.forEach((item) => { item.value = this.options.start.lat }) this._elms.alt && this._elms.alt.forEach((item) => { item.value = this.options.start.alt }) this.tip.setPosition( cartesian, movement.endPosition.x, movement.endPosition.y ) }) this.event.mouse_left((movement, cartesian) => { if (!movPos || movPos.x !== movement.position.x || movPos.y !== movement.position.y - 2) { let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer) this.options.start.lng = positions.lng this.options.start.lat = positions.lat this.options.start.alt = positions.alt } this.entity.position = { lng: this.options.start.lng, lat: this.options.start.lat, alt: this.options.start.alt } this.previous = { positions: { ...this.entity.position } } this.event.mouse_move(() => { }) this.event.mouse_left(() => { }) this.event.mouse_right(() => { }) this.event.gesture_pinck_start(() => { }) this.event.gesture_pinck_end(() => { }) this.positionEditing = false }) this.event.mouse_right((movement, cartesian) => { this.options.start.lng = this.entity.position.lng this.options.start.lat = this.entity.position.lat this.options.start.alt = this.entity.position.alt this.positionEditing = false }) this.event.gesture_pinck_start((movement, cartesian) => { let startTime = new Date() this.event.gesture_pinck_end(() => { let endTime = new Date() if (endTime - startTime >= 500) { // 长按取消 this.options.lng = this.entity.position.lng this.options.lat = this.entity.position.lat this.options.alt = this.entity.position.alt this.positionEditing = false } else { let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer) this.options.lng = positions.lng this.options.lat = positions.lat this.options.alt = positions.alt this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt } this.previous = { positions: { ...this.entity.position } } this.event.mouse_move(() => { }) this.event.mouse_left(() => { }) this.event.mouse_right(() => { }) this.event.gesture_pinck_start(() => { }) this.event.gesture_pinck_end(() => { }) this.positionEditing = false } }) }) } else { this.picking = true if (this.event) { this.event.mouse_move(() => { }) this.event.mouse_left(() => { }) this.event.mouse_right(() => { }) this.event.gesture_pinck_start(() => { }) this.event.gesture_pinck_end(() => { }) } this.tip && this.tip.destroy() if (!this.sdk || !this.sdk.viewer || !this.entity) { return } this.options.start.lng = this.entity.position.lng this.options.start.lat = this.entity.position.lat this.options.start.alt = this.entity.position.alt let cartographic = Cesium.Cartographic.fromDegrees(this.options.start.lng, this.options.start.lat, this.options.start.alt); let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic); this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position) this._elms.lng && this._elms.lng.forEach((item) => { item.value = this.options.start.lng }) this._elms.lat && this._elms.lat.forEach((item) => { item.value = this.options.start.lat }) this._elms.alt && this._elms.alt.forEach((item) => { item.value = this.options.start.alt }) } } get positionEditing() { return this.operate.positionEditing } static EventBinding(that, elements) { for (let i = 0; i < elements.length; i++) { let Event = [] let isEvent = false let removeName = [] if (!elements[i] || !elements[i].attributes) { continue } for (let m of elements[i].attributes) { switch (m.name) { case '@model': { isEvent = true if (elements[i].type == 'checkbox') { Event.push((e) => { that[m.value] = e.target.checked }) elements[i].checked = that[m.value] } else { Event.push((e) => { let value = e.target.value if (e.target.type == 'number') { if (e.data != '.' && (e.data != '-' || e.target.value)) { value = Number(value) if ((e.target.max) && value > Number(e.target.max)) { value = Number(e.target.max) } if ((e.target.min) && value < Number(e.target.min)) { value = Number(e.target.min) } that[m.value] = value } } else { that[m.value] = value } }) if (elements[i].nodeName == 'IMG') { elements[i].src = that[m.value] } else { elements[i].value = that[m.value] } } if (that._elms[m.value]) { that._elms[m.value].push(elements[i]) } else { that._elms[m.value] = [elements[i]] } removeName.push(m.name) break; } case '@click': { elements[i].addEventListener('click', (e) => { if (typeof (that[m.value]) === 'function') { that[m.value](e) } }); removeName.push(m.name) // elements[i].attributes.removeNamedItem(m.name) break; } case '@change': { isEvent = true Event.push((e) => { let value = e.target.value if (e.target.type == 'number' && value != '') { value = Number(value) e.target.value = value } if (typeof (that[m.value]) === 'function') { that[m.value](e, value) } }) break; } } // elements[i].attributes[m] = undefined } for (let n = 0; n < removeName.length; n++) { elements[i].attributes.removeNamedItem(removeName[n]) } if (isEvent) { let ventType = 'input' if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') { ventType = 'change' } elements[i].addEventListener(ventType, (e) => { for (let t = 0; t < Event.length; t++) { Event[t](e) } }); } } } flicker() { } } export default Spout