代码迁移

This commit is contained in:
zh
2025-07-03 13:54:01 +08:00
parent b04de8a084
commit 2a4da33e62
985 changed files with 358292 additions and 13 deletions

View File

@ -0,0 +1,719 @@
/**
* 火焰特效
*/
import Dialog from '../../../Element/Dialog';
import { html } from "./_element";
import EventBinding from './eventBinding'
import Base from "../../index";
import MouseEvent from '../../../../Event/index'
import { syncPrimitives } from '../../../../Global/MultiViewportMode'
import { syncData } from '../../../../Global/MultiViewportMode'
import MouseTip from '../../../../MouseTip'
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global'
class Flame 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="#ff0000" {string} 起始颜色
* @param options.endColor="#fff000" {string} 结束颜色
* @param options.startScale=0.5 {number} 初始比例
* @param options.endScale=2 {number} 结束比例
* @param options.minimumSpeed=1 {number} 最小初速度
* @param options.maximumSpeed=30 {number} 最大初速度
* @param options.minimumParticleLife=1 {number} 最小存在时间(秒)
* @param options.maximumParticleLife=2 {number} 最大存在时间(秒)
* @param options.emissionRate=60 {number} 发射速率(个/每秒)
* @param options.particleSize=10 {number} 粒子尺大小
* @param options.lng 经度
* @param options.lat 纬度
* @param options.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 || "#ff0000"
this.options.endColor = options.endColor || "#fff000"
this.options.startScale = options.startScale || 0.5
this.options.endScale = options.endScale || 2
this.options.minimumParticleLife = options.minimumParticleLife || 1
this.options.maximumParticleLife = options.maximumParticleLife || 2
this.options.minimumSpeed = options.minimumSpeed || 1
this.options.maximumSpeed = options.maximumSpeed || 30
this.options.emissionRate = options.emissionRate || 60
this.options.particleSize = options.particleSize || 10
this.options.show = options.show === false ? false : true
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._elms = {};
this.previous = {
positions: {
lng: this.options.lng,
lat: this.options.lat,
alt: this.options.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") {
this.options.show = v
if (this.entity && this.sdk.viewer.camera.positionCartographic.height < 10000000) {
this.entity.show = v
}
if (this._DialogObject && this._DialogObject.showBtn) {
this._DialogObject.showBtn.checked = v
}
if (this.options.label && this.options.label.show) {
this.label.show = v
}
syncData(this.sdk, this.options.id)
syncSplitData(this.sdk, this.options.id)
} else {
console.error("参数必须为boolean")
}
}
async add() {
this.originalOptions = this.deepCopyObj(this.options)
const scene = this.sdk.viewer.scene;
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.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 cameraHeight = this.sdk.viewer.camera.positionCartographic.height
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.minimumSpeed,//设置以米/秒为单位的最小界限,超过该最小界限,随机选择粒子的实际速度。
maximumSpeed: this.options.maximumSpeed,//设置以米/秒为单位的最大界限,超过该最大界限,随机选择粒子的实际速度。
// imageSize: new Cesium.Cartesian2( //如果设置该属性,将会覆盖 minimumImageSize和maximumImageSize属性以像素为单位缩放image的大小
// this.options.imageSize || 10,
// this.options.imageSize || 10
// ),
minimumImageSize: new Cesium.Cartesian2(
this.options.particleSize,
this.options.particleSize
),
maximumImageSize: new Cesium.Cartesian2(
this.options.particleSize,
this.options.particleSize
),
sizeInMeters: true,
emissionRate: this.options.emissionRate, //每秒发射的粒子数。
lifetime: 0.5,
loop: true,
emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(30.0)),
modelMatrix: matrix,
updateCallback: (r) => {
r._billboard.id = this.options.id
}
})
);
// 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.lng, lat: this.options.lat, alt: this.options.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
}
}
});
}
async flyTo(options = {}) {
if (this._error) {
return
}
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.center) {
position = { ...this.options.center }
}
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.lng, this.options.lat, this.options.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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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 minimumSpeed() {
return this.options.minimumSpeed
}
set minimumSpeed(v) {
this.options.minimumSpeed = v
this.particleSystem.minimumSpeed = v
this._elms.minimumSpeed && this._elms.minimumSpeed.forEach((item) => {
item.value = v
})
}
get maximumSpeed() {
return this.options.maximumSpeed
}
set maximumSpeed(v) {
this.options.maximumSpeed = v
this.particleSystem.maximumSpeed = v
this._elms.maximumSpeed && this._elms.maximumSpeed.forEach((item) => {
item.value = v
})
}
get minimumParticleLife() {
return this.options.minimumParticleLife
}
set minimumParticleLife(v) {
this.options.minimumParticleLife = v
this.particleSystem.minimumParticleLife = v
this._elms.minimumParticleLife && this._elms.minimumParticleLife.forEach((item) => {
item.value = v
})
}
get maximumParticleLife() {
return this.options.maximumParticleLife
}
set maximumParticleLife(v) {
this.options.maximumParticleLife = v
this.particleSystem.maximumParticleLife = v
this._elms.maximumParticleLife && this._elms.maximumParticleLife.forEach((item) => {
item.value = v
})
}
get startScale() {
return this.options.startScale
}
set startScale(v) {
this.options.startScale = v
this.particleSystem.startScale = v
this._elms.startScale && this._elms.startScale.forEach((item) => {
item.value = v
})
}
get endScale() {
return this.options.endScale
}
set endScale(v) {
this.options.endScale = v
this.particleSystem.endScale = v
this._elms.endScale && this._elms.endScale.forEach((item) => {
item.value = v
})
}
get emissionRate() {
return this.options.emissionRate
}
set emissionRate(v) {
this.options.emissionRate = v
this.particleSystem.emissionRate = v
this._elms.emissionRate && this._elms.emissionRate.forEach((item) => {
item.value = v
})
}
get particleSize() {
return this.options.particleSize
}
set particleSize(v) {
this.options.particleSize = v
this.particleSystem.minimumImageSize = new Cesium.Cartesian2(v, v)
this.particleSystem.maximumImageSize = new Cesium.Cartesian2(v, v)
this._elms.particleSize && this._elms.particleSize.forEach((item) => {
item.value = v
})
}
get lng() {
return this.options.lng
}
set lng(v) {
this.options.lng = v
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
this._elms.lng && this._elms.lng.forEach((item) => {
item.value = v
})
}
get lat() {
return this.options.lat
}
set lat(v) {
this.options.lat = v
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
this._elms.lat && this._elms.lat.forEach((item) => {
item.value = v
})
}
get alt() {
return this.options.alt
}
set alt(v) {
this.options.alt = v
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
let position = this.sdk.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic);
this.entity.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position)
this.entity.position = { lng: this.options.lng, lat: this.options.lat, alt: this.options.alt }
this._elms.alt && this._elms.alt.forEach((item) => {
item.value = 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 ewPlugins('colorpicker', {
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 ewPlugins('colorpicker', {
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("*")
EventBinding.on(this, all_elm)
this._elms = EventBinding.element
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.minimumSpeed = this.originalOptions.minimumSpeed
this.maximumSpeed = this.originalOptions.maximumSpeed
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.lng
this.lat = this.originalOptions.lat
this.alt = this.originalOptions.alt
syncPrimitives(this.entity)
}
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.lng = positions.lng
this.options.lat = positions.lat
this.options.alt = positions.alt
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.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.lng
})
this._elms.lat && this._elms.lat.forEach((item) => {
item.value = this.options.lat
})
this._elms.alt && this._elms.alt.forEach((item) => {
item.value = this.options.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.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
})
this.event.mouse_right((movement, cartesian) => {
this.options.lng = this.entity.position.lng
this.options.lat = this.entity.position.lat
this.options.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.tip && this.tip.destroy()
if(!this.sdk || !this.sdk.viewer || !this.entity) {
return
}
this.options.lng = this.entity.position.lng
this.options.lat = this.entity.position.lat
this.options.alt = this.entity.position.alt
let cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.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.lng
})
this._elms.lat && this._elms.lat.forEach((item) => {
item.value = this.options.lat
})
this._elms.alt && this._elms.alt.forEach((item) => {
item.value = this.options.alt
})
}
}
get positionEditing() {
return this.operate.positionEditing
}
flicker() { }
}
export default Flame