代码迁移
This commit is contained in:
111
src/Obj/Base/ParticleEffects/Flame/_element.js
Normal file
111
src/Obj/Base/ParticleEffects/Flame/_element.js
Normal file
@ -0,0 +1,111 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="minimumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="maximumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
export { html }
|
92
src/Obj/Base/ParticleEffects/Flame/eventBinding.js
Normal file
92
src/Obj/Base/ParticleEffects/Flame/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(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' || e.target.type == 'range') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
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)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
719
src/Obj/Base/ParticleEffects/Flame/index.js
Normal file
719
src/Obj/Base/ParticleEffects/Flame/index.js
Normal 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
|
111
src/Obj/Base/ParticleEffects/Fountain/_element.js
Normal file
111
src/Obj/Base/ParticleEffects/Fountain/_element.js
Normal file
@ -0,0 +1,111 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="minimumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="maximumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
export { html }
|
92
src/Obj/Base/ParticleEffects/Fountain/eventBinding.js
Normal file
92
src/Obj/Base/ParticleEffects/Fountain/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(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' || e.target.type == 'range') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
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)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
744
src/Obj/Base/ParticleEffects/Fountain/index.js
Normal file
744
src/Obj/Base/ParticleEffects/Fountain/index.js
Normal file
@ -0,0 +1,744 @@
|
||||
/**
|
||||
* 喷泉特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html } from "./_element";
|
||||
import EventBinding from './eventBinding'
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global'
|
||||
|
||||
class Fountain 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="#c1f7f24d" {string} 起始颜色
|
||||
* @param options.endColor="#ffffff00" {string} 结束颜色
|
||||
* @param options.startScale=1 {number} 初始比例
|
||||
* @param options.endScale=20 {number} 结束比例
|
||||
* @param options.minimumSpeed=9 {number} 最小初速度
|
||||
* @param options.maximumSpeed=9.5 {number} 最大初速度
|
||||
* @param options.minimumParticleLife=6 {number} 最小存在时间(秒)
|
||||
* @param options.maximumParticleLife=7 {number} 最大存在时间(秒)
|
||||
* @param options.emissionRate=20 {number} 发射速率(个/每秒)
|
||||
* @param options.particleSize=0.5{number} 粒子尺大小
|
||||
* @param options.gravity=-3.5{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 || "#c1f7f24d"
|
||||
this.options.endColor = options.endColor || "#ffffff00"
|
||||
this.options.startScale = options.startScale || 1
|
||||
this.options.endScale = options.endScale || 20
|
||||
this.options.minimumParticleLife = options.minimumParticleLife || 6
|
||||
this.options.maximumParticleLife = options.maximumParticleLife || 7
|
||||
this.options.minimumSpeed = options.minimumSpeed || 9
|
||||
this.options.maximumSpeed = options.maximumSpeed || 9.5
|
||||
this.options.emissionRate = options.emissionRate || 20
|
||||
this.options.particleSize = options.particleSize || 0.5
|
||||
this.options.gravity = (options.gravity || options.gravity === 0) ? options.gravity : -3.5
|
||||
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.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() {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
const scene = this.sdk.viewer.scene;
|
||||
let gravityScratch = new Cesium.Cartesian3();
|
||||
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/fountain.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
|
||||
// ),
|
||||
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.ConeEmitter(Cesium.Math.toRadians(0.2)),
|
||||
modelMatrix: matrix,
|
||||
emitterModelMatrix: computeEmitterodelMatrix(),// 发射器转换为世界坐标
|
||||
|
||||
// 增加重力场影像,
|
||||
updateCallback: applyGravity,
|
||||
})
|
||||
);
|
||||
let gravityVector = new Cesium.Cartesian3();
|
||||
let gravity = -3.5;// !!!重力方向向上向下 -(9.8*9.8)
|
||||
function applyGravity(p, dt) {
|
||||
p._billboard.id = _this.options.id
|
||||
let position = p.position;
|
||||
Cesium.Cartesian3.normalize(position, gravityVector);
|
||||
Cesium.Cartesian3.multiplyByScalar(gravityVector, gravity * dt, gravityVector);
|
||||
p.velocity = Cesium.Cartesian3.add(p.velocity, gravityVector, p.velocity);
|
||||
}
|
||||
|
||||
|
||||
// 计算粒子发射器的位置姿态
|
||||
function computeEmitterodelMatrix() {
|
||||
let hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0);//!!!发射粒子的方向
|
||||
let trs = new Cesium.TranslationRotationScale();
|
||||
trs.translation = Cesium.Cartesian3.fromElements(0, 0, 0);
|
||||
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
|
||||
let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
|
||||
return Matrix4
|
||||
}
|
||||
|
||||
|
||||
function computeModelMatrix(position) {
|
||||
let center = Cesium.Cartesian3.fromDegrees(120.40100613624982, 36.09030781, -5)
|
||||
let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
|
||||
return modelMatrix;
|
||||
}
|
||||
|
||||
// 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 = 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 = 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
|
||||
}
|
||||
|
||||
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.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.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 Fountain
|
111
src/Obj/Base/ParticleEffects/Smoke/_element.js
Normal file
111
src/Obj/Base/ParticleEffects/Smoke/_element.js
Normal file
@ -0,0 +1,111 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" maxlength="40" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="minimumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大初速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="maximumSpeed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
export { html }
|
92
src/Obj/Base/ParticleEffects/Smoke/eventBinding.js
Normal file
92
src/Obj/Base/ParticleEffects/Smoke/eventBinding.js
Normal file
@ -0,0 +1,92 @@
|
||||
class eventBinding {
|
||||
constructor() {
|
||||
this.element = {}
|
||||
}
|
||||
static event = {}
|
||||
|
||||
getEvent(name) {
|
||||
return eventBinding.event[name]
|
||||
}
|
||||
|
||||
getEventAll() {
|
||||
return eventBinding.event
|
||||
}
|
||||
|
||||
setEvent(name, event) {
|
||||
eventBinding.event[name] = event
|
||||
}
|
||||
|
||||
on(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' || e.target.type == 'range') {
|
||||
value = Number(value)
|
||||
}
|
||||
that[m.value] = value
|
||||
})
|
||||
if(elements[i].nodeName=='IMG') {
|
||||
elements[i].src = that[m.value]
|
||||
}
|
||||
else {
|
||||
elements[i].value = that[m.value]
|
||||
}
|
||||
}
|
||||
if(this.element[m.value]) {
|
||||
this.element[m.value].push(elements[i])
|
||||
}
|
||||
else {
|
||||
this.element[m.value] = [elements[i]]
|
||||
}
|
||||
removeName.push(m.name)
|
||||
break;
|
||||
}
|
||||
case '@click': {
|
||||
elements[i].addEventListener('click', (e) => {
|
||||
if (typeof (that.Dialog[m.value]) === 'function') {
|
||||
that.Dialog[m.value](e)
|
||||
}
|
||||
});
|
||||
removeName.push(m.name)
|
||||
// elements[i].attributes.removeNamedItem(m.name)
|
||||
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)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EventBinding = new eventBinding();
|
||||
export default EventBinding;
|
717
src/Obj/Base/ParticleEffects/Smoke/index.js
Normal file
717
src/Obj/Base/ParticleEffects/Smoke/index.js
Normal file
@ -0,0 +1,717 @@
|
||||
/**
|
||||
* 烟雾特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html, css } from "./_element";
|
||||
import EventBinding from './eventBinding'
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData } from '../../../../Global/MultiViewportMode'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../../Global/global'
|
||||
|
||||
class Smoke 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="#00000000" {string} 起始颜色
|
||||
* @param options.endColor="#0000001a" {string} 结束颜色
|
||||
* @param options.startScale=0.1 {number} 初始比例
|
||||
* @param options.endScale=10 {number} 结束比例
|
||||
* @param options.minimumSpeed=10 {number} 最小初速度
|
||||
* @param options.maximumSpeed=15 {number} 最大初速度
|
||||
* @param options.minimumParticleLife=6 {number} 最小存在时间(秒)
|
||||
* @param options.maximumParticleLife=7 {number} 最大存在时间(秒)
|
||||
* @param options.emissionRate=28 {number} 发射速率(个/每秒)
|
||||
* @param options.particleSize=2{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 || "#00000000"
|
||||
this.options.endColor = options.endColor || "#0000001a"
|
||||
this.options.startScale = options.startScale || 0.1
|
||||
this.options.endScale = options.endScale || 10
|
||||
this.options.minimumParticleLife = options.minimumParticleLife || 6
|
||||
this.options.maximumParticleLife = options.maximumParticleLife || 7
|
||||
this.options.minimumSpeed = options.minimumSpeed || 10
|
||||
this.options.maximumSpeed = options.maximumSpeed || 15
|
||||
this.options.emissionRate = options.emissionRate || 28
|
||||
this.options.particleSize = options.particleSize || 2
|
||||
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.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;
|
||||
var cartographic = Cesium.Cartographic.fromDegrees(this.options.lng, this.options.lat, this.options.alt);
|
||||
var 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.CircleEmitter(0.2),
|
||||
performance: false,
|
||||
modelMatrix: matrix,
|
||||
updateCallback: (r)=>{
|
||||
r._billboard.id = this.options.id
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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.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.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 Smoke
|
122
src/Obj/Base/ParticleEffects/Spout/_element.js
Normal file
122
src/Obj/Base/ParticleEffects/Spout/_element.js
Normal file
@ -0,0 +1,122 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input style="width: 175px;" class="input" type="text" @model="name">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">经度</span>
|
||||
<input class="input" type="number" title="" min="-180" max="180" @model="lng">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">高度</span>
|
||||
<div class="input-number input-number-unit-1">
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
<span class="unit">m</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">起始颜色</span>
|
||||
<div class="start_color"></div>
|
||||
</div>
|
||||
<div class="col" style="margin: 0;justify-content: flex-end;">
|
||||
<span class="label">结束颜色</span>
|
||||
<div class="end_color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>速度</span>
|
||||
<input type="range" max="30" min="0" step="0.1" @model="speed">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>发射速率(个/秒)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="emissionRate">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最小存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="minimumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>最大存在时间</span>
|
||||
<input type="range" max="100" min="0.01" step="0.1" @model="maximumParticleLife">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>起始比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="startScale">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>结束比例</span>
|
||||
<input type="range" max="10" min="0" step="0.1" @model="endScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>朝向</span>
|
||||
<input type="range" max="360" min="0.1" step="0.1" @model="heading">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>俯仰角度</span>
|
||||
<input type="range" max="360" min="0.1" step="0.1" @model="pitch">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<span>尺寸(像素)</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="particleSize">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
952
src/Obj/Base/ParticleEffects/Spout/index.js
Normal file
952
src/Obj/Base/ParticleEffects/Spout/index.js
Normal file
@ -0,0 +1,952 @@
|
||||
/**
|
||||
* 水柱特效
|
||||
*/
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html, css } from "./_element";
|
||||
import Base from "../../index";
|
||||
import MouseEvent from '../../../../Event/index'
|
||||
import { syncData } 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") {
|
||||
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() {
|
||||
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 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 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 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("*")
|
||||
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
|
Reference in New Issue
Block a user