代码迁移
This commit is contained in:
57
src/Obj/Base/TextObject/3DText/_element.js
Normal file
57
src/Obj/Base/TextObject/3DText/_element.js
Normal file
@ -0,0 +1,57 @@
|
||||
function html() {
|
||||
return `
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<input class="input" type="text" @model="text">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">文字厚度</span>
|
||||
<input class="input" type="number" title="" min="0" max="9999999" @model="extrudedHeight">
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">纬度</span>
|
||||
<input class="input" type="number" title="" min="-90" max="90" @model="lat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label" style="flex: 0 0 70px;">高度</span>
|
||||
<input class="input" type="number" title="" min="-9999999" max="999999999" @model="alt">
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
function css() {
|
||||
return `
|
||||
.YJ-custom-base-dialog>.content {
|
||||
width: 600px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .col {
|
||||
margin: 0 10px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .col:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .col:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content>div>.row .label {
|
||||
flex: 0 0 42px;
|
||||
}
|
||||
.YJ-custom-base-dialog>.content .DIV-cy-tab-content-pane .input-select {
|
||||
width: 100px;
|
||||
}
|
||||
`
|
||||
}
|
||||
export { html, css }
|
536
src/Obj/Base/TextObject/3DText/index.js
Normal file
536
src/Obj/Base/TextObject/3DText/index.js
Normal file
@ -0,0 +1,536 @@
|
||||
// 3D文字(未完成)
|
||||
import Base from "../../index";
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import { html, css } from "./_element";
|
||||
import MouseEvent from '../../../../Event'
|
||||
import { FontLoader } from '../../../../../static/3rdparty/three/jsm/loaders/FontLoader.js';
|
||||
import { TextGeometry } from '../../../../../static/3rdparty/three/jsm/geometries/TextGeometry.js';
|
||||
import * as variable from '../../../../../static/3rdparty/three/fonts/FZZongYi-M05S_regular.typeface.json'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
class Text3D extends Base {
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.positions = options.positions = options.positions || {}
|
||||
this.options.positions.lng = options.positions.lng
|
||||
this.options.positions.lat = options.positions.lat
|
||||
this.options.positions.alt = options.positions.alt
|
||||
this.options.color = options.color || "#00d9ff"
|
||||
this.options.text = options.text || "未命名对象"
|
||||
this.options.extrudedHeight = options.extrudedHeight || 10
|
||||
this.operate = {}
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {};
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
Text3D.create(this)
|
||||
}
|
||||
|
||||
get text() {
|
||||
return this.options.text
|
||||
}
|
||||
|
||||
set text(v) {
|
||||
this.options.text = v
|
||||
this.update()
|
||||
this._elms.text && this._elms.text.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
set color(v) {
|
||||
this.options.color = v
|
||||
this.entity.appearance.material = new Cesium.Material({
|
||||
fabric: {
|
||||
type: 'Color',
|
||||
uniforms: {
|
||||
color: Cesium.Color.fromCssColorString(this.options.color)
|
||||
}
|
||||
}
|
||||
})
|
||||
if (this._elms.color) {
|
||||
this._elms.color.forEach((item, i) => {
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.color = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color[i] = colorPicker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get extrudedHeight() {
|
||||
return this.options.extrudedHeight
|
||||
}
|
||||
set extrudedHeight(v) {
|
||||
this.options.extrudedHeight = v
|
||||
this.update()
|
||||
this._elms.extrudedHeight && this._elms.extrudedHeight.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.positions.lng
|
||||
}
|
||||
set lng(v) {
|
||||
this.options.positions.lng = v
|
||||
this.update()
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.positions.lat
|
||||
}
|
||||
set lat(v) {
|
||||
this.options.positions.lat = v
|
||||
this.update()
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get alt() {
|
||||
return this.options.positions.alt
|
||||
}
|
||||
set alt(v) {
|
||||
this.options.positions.alt = v
|
||||
this.update()
|
||||
this._elms.alt && this._elms.alt.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
static create(that) {
|
||||
const loader = new FontLoader();
|
||||
let textGeo = new TextGeometry(that.options.text, {
|
||||
font: loader.parse(variable.default),
|
||||
height: 0,
|
||||
size: 1,
|
||||
depth: 0,
|
||||
curveSegments: 2,
|
||||
bevelEnabled: false
|
||||
});
|
||||
if(!textGeo || !textGeo.attributes) {
|
||||
return
|
||||
}
|
||||
let data = textGeo.attributes.position.array
|
||||
let fromDegreesArray = []
|
||||
for (let i = 0; i < data.length; i += 3) {
|
||||
fromDegreesArray.push(data[i] + that.lng, data[i + 1] + that.lat, data[i + 2])
|
||||
}
|
||||
const instances = []
|
||||
for (let i = 0; i < fromDegreesArray.length; i += 9) {
|
||||
let instance = new Cesium.GeometryInstance({
|
||||
geometry: new Cesium.PolygonGeometry({
|
||||
polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([fromDegreesArray[i], fromDegreesArray[i + 1], fromDegreesArray[i + 2], fromDegreesArray[i + 3], fromDegreesArray[i + 4], fromDegreesArray[i + 5], fromDegreesArray[i + 6], fromDegreesArray[i + 7], fromDegreesArray[i + 8]])),
|
||||
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
|
||||
extrudedHeight: that.alt + that.extrudedHeight,
|
||||
height: that.alt
|
||||
})
|
||||
});
|
||||
instances.push(instance)
|
||||
}
|
||||
that.entity = that.sdk.viewer.scene.primitives.add(new Cesium.Primitive({
|
||||
// allowPicking: false,
|
||||
asynchronous: false,
|
||||
releaseGeometryInstances: false,
|
||||
geometryInstances: instances,
|
||||
appearance: new Cesium.EllipsoidSurfaceAppearance({
|
||||
material: new Cesium.Material({
|
||||
fabric: {
|
||||
type: 'Color',
|
||||
uniforms: {
|
||||
color: Cesium.Color.fromCssColorString(that.options.color)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}));
|
||||
if(that.options.show) {
|
||||
|
||||
setSplitDirection(0, that.options.id)
|
||||
}
|
||||
|
||||
// setTimeout(() => {
|
||||
// let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(100, 20, 0))
|
||||
// that.entity.modelMatrix = Cesium.Matrix4.multiply(that.entity.modelMatrix, m, new Cesium.Matrix4())
|
||||
// }, 5000);
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._element_style = null
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
this._element_style = document.createElement('style');
|
||||
this._element_style.type = 'text/css';
|
||||
this._element_style.setAttribute('data-name', 'YJ_style_dialog');
|
||||
this._element_style.innerHTML = css();
|
||||
|
||||
this._DialogObject = await new Dialog(this.sdk, this.options, {
|
||||
title: '编辑属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.text = this.text.trim()
|
||||
if (!this.text) {
|
||||
this.text = '未命名对象'
|
||||
}
|
||||
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.positionEditing = false
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.options.show = show
|
||||
this.originalOptions.show = show
|
||||
this.show = show
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
this.positionEditing = !this.positionEditing
|
||||
},
|
||||
})
|
||||
document.getElementsByTagName('head')[0].appendChild(this._element_style);
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html(this)
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
// setTimeout(() => {
|
||||
// this.attributeLink = this.options.attribute.link.content
|
||||
// this.cameraSelect()
|
||||
// }, 500);
|
||||
|
||||
// 创建标签页
|
||||
// let tabsElm = new cy_tabs('radar-scan-edit-tabs')
|
||||
// 颜色组件
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.color,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.color = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let labelColorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelColor")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.labelColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.labelColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.labelColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let lineColorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelLineColor")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.labelLineColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.labelLineColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.labelLineColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let labelBackgroundColorStartPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelBackgroundColorStart")[0],
|
||||
size: 'mini',
|
||||
alpha: true,
|
||||
defaultColor: this.labelBackgroundColorStart,
|
||||
disabled: false,
|
||||
openPickerAni: 'opacity',
|
||||
sure: (color) => {
|
||||
this.labelBackgroundColorStart = color
|
||||
},
|
||||
clear: () => {
|
||||
this.labelBackgroundColorStart = 'rgba(255,255,255,1)'
|
||||
},
|
||||
})
|
||||
let labelBackgroundColorEndPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelBackgroundColorEnd")[0],
|
||||
size: 'mini',
|
||||
alpha: true,
|
||||
defaultColor: this.labelBackgroundColorEnd,
|
||||
disabled: false,
|
||||
openPickerAni: 'opacity',
|
||||
sure: (color) => {
|
||||
this.labelBackgroundColorEnd = color
|
||||
},
|
||||
clear: () => {
|
||||
this.labelBackgroundColorEnd = 'rgba(255,255,255,1)'
|
||||
},
|
||||
})
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
Text3D.EventBinding(this, all_elm)
|
||||
this._elms.color = [colorPicker]
|
||||
this._elms.labelColor = [labelColorPicker]
|
||||
this._elms.labelLineColor = [lineColorPicker]
|
||||
this._elms.labelBackgroundColorStart = [labelBackgroundColorStartPicker]
|
||||
this._elms.labelBackgroundColorEnd = [labelBackgroundColorEndPicker]
|
||||
} 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@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.picking = false
|
||||
this.previous = {
|
||||
positions: { ...this.options.positions }
|
||||
}
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.positions.lng = positions.lng
|
||||
this.options.positions.lat = positions.lat
|
||||
this.options.positions.alt = positions.alt
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
let positions = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.positions.lng = positions.lng
|
||||
this.options.positions.lat = positions.lat
|
||||
this.options.positions.alt = positions.alt
|
||||
this.previous = {
|
||||
positions: { ...this.options.positions }
|
||||
}
|
||||
this.update()
|
||||
this.event.mouse_move(() => { })
|
||||
this.event.mouse_left(() => { })
|
||||
this.event.mouse_right(() => { })
|
||||
this.positionEditing = false
|
||||
})
|
||||
this.event.mouse_right((movement, cartesian) => {
|
||||
this.positionEditing = false
|
||||
})
|
||||
}
|
||||
else {
|
||||
this.picking = true
|
||||
this.event.mouse_move(() => { })
|
||||
this.event.mouse_left(() => { })
|
||||
this.event.mouse_right(() => { })
|
||||
this.options.positions.lng = this.previous.positions.lng
|
||||
this.options.positions.lat = this.previous.positions.lat
|
||||
this.options.positions.alt = this.previous.positions.alt
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this.operate.positionEditing
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.entity) {
|
||||
let modelMatrix = this.entity.modelMatrix
|
||||
const loader = new FontLoader();
|
||||
let textGeo = new TextGeometry(this.options.text, {
|
||||
font: loader.parse(variable.default),
|
||||
height: 0,
|
||||
size: 1,
|
||||
depth: 0,
|
||||
curveSegments: 2,
|
||||
bevelEnabled: false
|
||||
});
|
||||
if(!textGeo ||!textGeo.attributes) {
|
||||
return
|
||||
}
|
||||
let data = textGeo.attributes.position.array
|
||||
let fromDegreesArray = []
|
||||
for (let i = 0; i < data.length; i += 3) {
|
||||
fromDegreesArray.push(data[i] + this.lng, data[i + 1] + this.lat, data[i + 2])
|
||||
}
|
||||
const instances = []
|
||||
for (let i = 0; i < fromDegreesArray.length; i += 9) {
|
||||
var instance = new Cesium.GeometryInstance({
|
||||
geometry: new Cesium.PolygonGeometry({
|
||||
polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([fromDegreesArray[i], fromDegreesArray[i + 1], fromDegreesArray[i + 2], fromDegreesArray[i + 3], fromDegreesArray[i + 4], fromDegreesArray[i + 5], fromDegreesArray[i + 6], fromDegreesArray[i + 7], fromDegreesArray[i + 8]])),
|
||||
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
|
||||
extrudedHeight: this.alt + this.extrudedHeight,
|
||||
height: this.alt
|
||||
})
|
||||
});
|
||||
instances.push(instance)
|
||||
}
|
||||
this.sdk.viewer.scene.primitives.remove(this.entity)
|
||||
this.entity = this.sdk.viewer.scene.primitives.add(new Cesium.Primitive({
|
||||
// allowPicking: false,
|
||||
asynchronous: false,
|
||||
releaseGeometryInstances: false,
|
||||
geometryInstances: instances,
|
||||
appearance: new Cesium.EllipsoidSurfaceAppearance({
|
||||
material: new Cesium.Material({
|
||||
fabric: {
|
||||
type: 'Color',
|
||||
uniforms: {
|
||||
color: Cesium.Color.fromCssColorString(this.options.color)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}));
|
||||
this.entity.modelMatrix = modelMatrix
|
||||
// this.lng = this.options.positions.lng
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Text3D
|
67
src/Obj/Base/TextObject/GroundText/_element.js
Normal file
67
src/Obj/Base/TextObject/GroundText/_element.js
Normal file
@ -0,0 +1,67 @@
|
||||
function html() {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<textarea @model="text"></textarea>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="label">颜色</span>
|
||||
<div class="color"></div>
|
||||
</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>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">旋转角度</span>
|
||||
<input type="range" max="360" min="0" step="1" @model="angle">
|
||||
<div class="input-number input-number-unit" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0" max="360" step="1" @model="angle">
|
||||
<span class="unit">°</span>
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">调整大小</span>
|
||||
<input type="range" max="100000" min="0" step="0.01" @model="scale">
|
||||
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0" max="100000" step="0.01" @model="scale">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">滚动速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="speed">
|
||||
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
|
||||
<input class="input" type="number" title="" min="0" max="100" step="1" @model="speed">
|
||||
<span class="arrow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
661
src/Obj/Base/TextObject/GroundText/index.js
Normal file
661
src/Obj/Base/TextObject/GroundText/index.js
Normal file
@ -0,0 +1,661 @@
|
||||
import Dialog from '../../../Element/Dialog'
|
||||
import EventBinding from '../../../Element/Dialog/eventBinding'
|
||||
import { html } 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 GroundText extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 贴地文字
|
||||
* @param options {object} 属性
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.text {string} 文字
|
||||
* @param options.angle=0 {number} 旋转角度
|
||||
* @param options.scale=1 {number} 比例
|
||||
* @param {object} options.position 经纬度{lon,lat}
|
||||
* @param {object} options.positions 经纬度集[{lon,lat}]仅在未定义 position 时有效
|
||||
* @param _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options)
|
||||
this.options.text = options.text || '未命名对象'
|
||||
let textArray = this.options.text.split('\n')
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
if (textArray[i].length > 80) {
|
||||
textArray[i] = textArray[i].slice(0, 80 - textArray[i].length)
|
||||
}
|
||||
}
|
||||
if (textArray.length > 70) {
|
||||
textArray.splice(70 - textArray.length)
|
||||
}
|
||||
this.options.text = textArray.join('\n')
|
||||
this.options.name = this.options.text
|
||||
this.options.show =
|
||||
options.show || options.show === false ? options.show : true
|
||||
this.options.angle = options.angle || 0
|
||||
this.options.scale =
|
||||
options.scale || options.scale === 0 ? options.scale : 1
|
||||
this.options.fontSize = options.fontSize || 20
|
||||
this.options.duration =
|
||||
options.duration || options.duration === 0 ? options.duration : 50000
|
||||
this.options.speed =
|
||||
options.speed || options.speed === 0 ? options.speed : 1
|
||||
this.options.color = options.color || '#FFC107'
|
||||
this.options.position = options.position
|
||||
|
||||
if (!this.options.position && this.options.positions) {
|
||||
this.options.position = { lng: (this.options.positions[0].lng + this.options.positions[1].lng) / 2, lat: (this.options.positions[0].lat + this.options.positions[1].lat) / 2 }
|
||||
let point1 = turf.point([this.options.positions[0].lng, this.options.positions[0].lat]);
|
||||
let point2 = turf.point([this.options.positions[1].lng, this.options.positions[1].lat]);
|
||||
|
||||
let options = { units: 'miles' };
|
||||
let distance1 = turf.rhumbDistance(point1, point2, options);
|
||||
|
||||
|
||||
// 计算两点与x轴正方向的夹角(弧度)
|
||||
function calculateAngle(pointA, pointB) {
|
||||
let dx = pointB[0] - pointA[0];
|
||||
let dy = pointB[1] - pointA[1];
|
||||
return Math.atan2(dy, dx);
|
||||
}
|
||||
|
||||
let angleRadians = calculateAngle([this.options.positions[0].lng, this.options.positions[0].lat], [this.options.positions[1].lng, this.options.positions[1].lat]);
|
||||
this.options.angle = (360+Cesium.Math.toDegrees(angleRadians))%360
|
||||
|
||||
let gap =
|
||||
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
|
||||
0.0001
|
||||
let canvas = this.getcanvas()
|
||||
let ratio = canvas.height / canvas.width
|
||||
let lng1 = this.options.position.lng - 0.0001 / ratio
|
||||
let lat1 = this.options.position.lat - gap
|
||||
let lng2 = this.options.position.lng + 0.0001 / ratio
|
||||
let lat2 = this.options.position.lat + gap
|
||||
let lng = (lng1 + lng2) / 2
|
||||
let lat = (lat1 + lat2) / 2
|
||||
|
||||
let from = turf.point([lng1, lat]);
|
||||
let to = turf.point([lng2, lat]);
|
||||
let distance2 = turf.rhumbDistance(from, to, options);
|
||||
let latRadians = Cesium.Math.toRadians(this.options.position.lat)
|
||||
distance2 = distance2 * (1+(Math.abs(Math.sin(angleRadians)*Math.tan(latRadians)*Math.sin(latRadians)*Math.sin(latRadians))))
|
||||
this.options.scale = distance1 / distance2
|
||||
}
|
||||
|
||||
this.entity
|
||||
this._positionEditing = false
|
||||
this.Dialog = _Dialog
|
||||
this._EventBinding = new EventBinding()
|
||||
this._elms = {}
|
||||
this.previous = {
|
||||
position: { ...this.options.position }
|
||||
}
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.create()
|
||||
}
|
||||
|
||||
get lng() {
|
||||
return this.options.position.lng
|
||||
}
|
||||
|
||||
set lng(v) {
|
||||
this.options.position.lng = v
|
||||
this._elms.lng && this._elms.lng.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get lat() {
|
||||
return this.options.position.lat
|
||||
}
|
||||
|
||||
set lat(v) {
|
||||
this.options.position.lat = v
|
||||
this._elms.lat && this._elms.lat.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get text() {
|
||||
return this.options.text
|
||||
}
|
||||
|
||||
set text(v) {
|
||||
this.options.text = v
|
||||
let textArray = this.options.text.split('\n')
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
if (textArray[i].length > 80) {
|
||||
let _error = '行超过80个字符,请按回车(Enter)后,继续输入'
|
||||
window.ELEMENT && window.ELEMENT.Message({
|
||||
message: _error,
|
||||
type: 'warning',
|
||||
duration: 1000
|
||||
});
|
||||
textArray[i] = textArray[i].slice(0, 80 - textArray[i].length)
|
||||
}
|
||||
}
|
||||
if (textArray.length > 70) {
|
||||
textArray.splice(70 - textArray.length)
|
||||
let _error = '超过最大输入字符'
|
||||
window.ELEMENT && window.ELEMENT.Message({
|
||||
message: _error,
|
||||
type: 'warning',
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
this.options.text = textArray.join('\n')
|
||||
if (this.entity) {
|
||||
let canvas = this.getcanvas()
|
||||
let ratio = canvas.height / canvas.width
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false,
|
||||
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
|
||||
})
|
||||
this.entity.rectangle.coordinates = new Cesium.CallbackProperty(() => {
|
||||
let gap =
|
||||
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
|
||||
(0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat - gap,
|
||||
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat + gap
|
||||
]
|
||||
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
|
||||
}, false)
|
||||
}
|
||||
this._elms.text &&
|
||||
this._elms.text.forEach(item => {
|
||||
item.value = this.options.text
|
||||
})
|
||||
}
|
||||
|
||||
get angle() {
|
||||
return this.options.angle
|
||||
}
|
||||
|
||||
set angle(v) {
|
||||
this.options.angle = v
|
||||
this._elms.angle &&
|
||||
this._elms.angle.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get scale() {
|
||||
return this.options.scale
|
||||
}
|
||||
|
||||
set scale(v) {
|
||||
this.options.scale = v
|
||||
this._elms.scale &&
|
||||
this._elms.scale.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get duration() {
|
||||
return this.options.duration
|
||||
}
|
||||
|
||||
set duration(v) {
|
||||
this.options.duration = v
|
||||
let canvas = this.getcanvas()
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false,
|
||||
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
|
||||
})
|
||||
this._elms.duration &&
|
||||
this._elms.duration.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
get speed() {
|
||||
return this.options.speed
|
||||
}
|
||||
|
||||
set speed(v) {
|
||||
this.options.speed = v
|
||||
let canvas = this.getcanvas()
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false,
|
||||
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
|
||||
})
|
||||
this._elms.speed &&
|
||||
this._elms.speed.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
set color(v) {
|
||||
this.options.color = v
|
||||
let canvas = this.getcanvas()
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false,
|
||||
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
|
||||
})
|
||||
if (this._elms.color) {
|
||||
this._elms.color.forEach((item, i) => {
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: item.el,
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: c => {
|
||||
this.color = c
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color[i] = colorPicker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
// let gap = Math.abs(Math.cos(Math.PI/180 * this.options.position.lat)) * (0.0001*this.options.scale)
|
||||
// let fromDegreesArray = [
|
||||
// this.options.position.lng - 0.05, this.options.position.lat - 0.05,
|
||||
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
|
||||
// this.options.position.lng + 0.05, this.options.position.lat + 0.05,
|
||||
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
|
||||
// ]
|
||||
let canvas = this.getcanvas()
|
||||
let ratio = canvas.height / canvas.width
|
||||
|
||||
this.entity = this.sdk.viewer.entities.add({
|
||||
id: this.options.id,
|
||||
show: this.options.show,
|
||||
rectangle: {
|
||||
coordinates: new Cesium.CallbackProperty(() => {
|
||||
let gap =
|
||||
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
|
||||
(0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat - gap,
|
||||
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
|
||||
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat + gap
|
||||
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
|
||||
]
|
||||
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
|
||||
}, false),
|
||||
material: new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false,
|
||||
is2D: this.sdk.viewer.scene.mode === Cesium.SceneMode.SCENE2D ? true : false
|
||||
}),
|
||||
rotation: new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Math.toRadians(this.options.angle)
|
||||
}, false),
|
||||
stRotation: new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Math.toRadians(this.options.angle)
|
||||
}, false)
|
||||
}
|
||||
})
|
||||
if (this.sdk.viewer._element.className === 'cesium-viewer 2d') {
|
||||
this.entity.rectangle.height = 10
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
if (this.options.show) {
|
||||
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
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.text = this.text.trim()
|
||||
if (!this.text) {
|
||||
this.text = '未命名对象'
|
||||
}
|
||||
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.positionEditing = false
|
||||
// this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
|
||||
// show: true,
|
||||
// });
|
||||
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 + ' ground-text'
|
||||
let contentElm = document.createElement('div')
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
let all_elm = contentElm.getElementsByTagName('*')
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
|
||||
// 颜色组件
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName('color')[0],
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: this.color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
this.color = color
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color = [colorPicker]
|
||||
} else {
|
||||
if (this._DialogObject && this._DialogObject.remove) {
|
||||
this._DialogObject.remove()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this._positionEditing = status
|
||||
this.previous = {
|
||||
position: { ...this.options.position }
|
||||
}
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.lng = position.lng
|
||||
this.lat = position.lat
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.lng = position.lng
|
||||
this.lat = position.lat
|
||||
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.lng = this.previous.position.lng
|
||||
this.lat = this.previous.position.lat
|
||||
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.lng = this.previous.position.lng
|
||||
this.lat = this.previous.position.lat
|
||||
this.positionEditing = false
|
||||
}
|
||||
else {
|
||||
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.lng = position.lng
|
||||
this.lat = position.lat
|
||||
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 {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this._positionEditing
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞到
|
||||
*/
|
||||
async flyTo(options = {}) {
|
||||
let canvas = this.getcanvas()
|
||||
let ratio = canvas.height / canvas.width
|
||||
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.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 {
|
||||
let gap =
|
||||
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
|
||||
(0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
[
|
||||
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat - gap
|
||||
],
|
||||
[
|
||||
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat + gap
|
||||
]
|
||||
]
|
||||
let height = await this.getClampToHeight(this.options.position)
|
||||
let positionArray = []
|
||||
for (let i = 0; i < fromDegreesArray.length; i++) {
|
||||
let a = Cesium.Cartesian3.fromDegrees(...fromDegreesArray[i], height)
|
||||
positionArray.push(a.x, a.y, a.z)
|
||||
}
|
||||
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||
this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||
offset: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.options = this.deepCopyObj(this.originalOptions)
|
||||
this.text = this.originalOptions.text
|
||||
this.angle = this.originalOptions.angle
|
||||
this.scale = this.originalOptions.scale
|
||||
this.color = this.originalOptions.color
|
||||
}
|
||||
|
||||
async remove() {
|
||||
this.event && this.event.destroy()
|
||||
this.tip && this.tip.destroy()
|
||||
this.sdk.viewer.entities.remove(this.entity)
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
getcanvas() {
|
||||
const canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
let textArray = this.options.text.split('\n')
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
if (textArray[i].length > 80) {
|
||||
textArray[i] = textArray[i].slice(0, 80 - textArray[i].length)
|
||||
}
|
||||
}
|
||||
if (textArray.length > 70) {
|
||||
textArray.splice(70 - textArray.length)
|
||||
}
|
||||
this.options.text = textArray.join('\n')
|
||||
let maxWidth = 0
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
ctx.font = 200 + 'px serif'
|
||||
const width = ctx.measureText(textArray[i]).width
|
||||
if (maxWidth < width) {
|
||||
maxWidth = width
|
||||
}
|
||||
}
|
||||
canvas.width = maxWidth
|
||||
canvas.height = 220 * textArray.length
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
ctx.font = 200 + 'px serif'
|
||||
ctx.fillStyle = 'rgba(255, 255, 255, 0)'
|
||||
ctx.fillRect(0, 0, maxWidth + 30, 210)
|
||||
ctx.fillStyle = this.options.color
|
||||
ctx.font = '200px serif'
|
||||
ctx.fillText(textArray[i], 0, 210 * (i + 1))
|
||||
}
|
||||
|
||||
return canvas
|
||||
}
|
||||
}
|
||||
|
||||
export default GroundText
|
486
src/Obj/Base/TextObject/GroundText/index2.js
Normal file
486
src/Obj/Base/TextObject/GroundText/index2.js
Normal file
@ -0,0 +1,486 @@
|
||||
import Dialog from '../../../Element/Dialog'
|
||||
import EventBinding from '../../../Element/Dialog/eventBinding'
|
||||
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 } from '../../../../Global/SplitScreen'
|
||||
|
||||
class GroundText extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 贴地文字
|
||||
* @param options {object} 属性
|
||||
* @param options.show=true {boolean} 显示/隐藏
|
||||
* @param options.text {string} 文字
|
||||
* @param options.angle=0 {number} 旋转角度
|
||||
* @param options.scale=1 {number} 比例
|
||||
* @param {object} options.position 经纬度和高度{lon,lat,alt}
|
||||
* @param {Array.<object>} options.positions 矩形坐标数组 [最西端的经度,最南端的纬度,最东经度,最北纬度]
|
||||
* @param _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
constructor(sdk, options = {}, _Dialog = {}) {
|
||||
super(sdk, options)
|
||||
this.options.text = options.text || '未命名对象'
|
||||
this.options.name = this.options.text
|
||||
this.options.show =
|
||||
options.show || options.show === false ? options.show : true
|
||||
this.options.angle = options.angle || 0
|
||||
this.options.scale =
|
||||
options.scale || options.scale === 0 ? options.scale : 1
|
||||
this.options.fontSize = options.fontSize || 20
|
||||
this.options.duration =
|
||||
options.duration || options.duration === 0 ? options.duration : 50000
|
||||
this.options.speed =
|
||||
options.speed || options.speed === 0 ? options.speed : 1
|
||||
this.options.color = options.color || '#FFC107'
|
||||
this.options.position = options.position
|
||||
this.entity
|
||||
this._positionEditing = false
|
||||
this.Dialog = _Dialog
|
||||
this._EventBinding = new EventBinding()
|
||||
this._elms = {}
|
||||
this.previous = {
|
||||
position: { ...this.options.position }
|
||||
}
|
||||
this.event = new MouseEvent(this.sdk)
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
this.create()
|
||||
}
|
||||
|
||||
get text() {
|
||||
return this.options.text
|
||||
}
|
||||
|
||||
set text(v) {
|
||||
this.options.text = v
|
||||
if (this.entity) {
|
||||
let canvas = this.getcanvas()
|
||||
let ratio = canvas.height / canvas.width
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false
|
||||
})
|
||||
this.entity.rectangle.coordinates = new Cesium.CallbackProperty(() => {
|
||||
let gap =
|
||||
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
|
||||
(0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat - gap,
|
||||
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat + gap
|
||||
]
|
||||
return Cesium.Rectangle.fromDegrees(...fromDegreesArray)
|
||||
}, false)
|
||||
}
|
||||
this._elms.text &&
|
||||
this._elms.text.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get angle() {
|
||||
return this.options.angle
|
||||
}
|
||||
|
||||
set angle(v) {
|
||||
this.options.angle = v
|
||||
this._elms.angle &&
|
||||
this._elms.angle.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get scale() {
|
||||
return this.options.scale
|
||||
}
|
||||
|
||||
set scale(v) {
|
||||
this.options.scale = v
|
||||
this._elms.scale &&
|
||||
this._elms.scale.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get duration() {
|
||||
return this.options.duration
|
||||
}
|
||||
|
||||
set duration(v) {
|
||||
this.options.duration = v
|
||||
let canvas = this.getcanvas()
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false
|
||||
})
|
||||
this._elms.duration &&
|
||||
this._elms.duration.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
get speed() {
|
||||
return this.options.speed
|
||||
}
|
||||
|
||||
set speed(v) {
|
||||
this.options.speed = v
|
||||
let canvas = this.getcanvas()
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false
|
||||
})
|
||||
this._elms.speed &&
|
||||
this._elms.speed.forEach(item => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
set color(v) {
|
||||
this.options.color = v
|
||||
let canvas = this.getcanvas()
|
||||
this.entity.rectangle.material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL('image/png'),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1.0, 1.0),
|
||||
duration: this.options.duration / this.options.speed,
|
||||
fltr: false
|
||||
})
|
||||
if (this._elms.color) {
|
||||
this._elms.color.forEach((item, i) => {
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: item.el,
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: c => {
|
||||
this.color = c
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color[i] = colorPicker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
// let gap = Math.abs(Math.cos(Math.PI/180 * this.options.position.lat)) * (0.0001*this.options.scale)
|
||||
// let fromDegreesArray = [
|
||||
// this.options.position.lng - 0.05, this.options.position.lat - 0.05,
|
||||
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
|
||||
// this.options.position.lng + 0.05, this.options.position.lat + 0.05,
|
||||
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
|
||||
// ]
|
||||
let canvas = this.getcanvas()
|
||||
let ratio = canvas.height / canvas.width
|
||||
let height = ((this.options.positions[2] - this.options.positions[0])/2) * ratio
|
||||
this.options.positions[1] = this.options.positions[3] - height
|
||||
this.entity = this.sdk.viewer.entities.add({
|
||||
id: this.options.id,
|
||||
show: this.options.show,
|
||||
rectangle: {
|
||||
coordinates: new Cesium.CallbackProperty(() => {
|
||||
let gap =
|
||||
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
|
||||
(0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat - gap,
|
||||
// this.options.position.lng + 0.05, this.options.position.lat - 0.05,
|
||||
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat + gap
|
||||
// this.options.position.lng - 0.05, this.options.position.lat + 0.05,
|
||||
]
|
||||
return Cesium.Rectangle.fromDegrees(...this.options.positions)
|
||||
}, false),
|
||||
outline: true,
|
||||
outlineColor: Cesium.Color.RED,
|
||||
outlineWidth: 10,
|
||||
|
||||
rotation: new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Math.toRadians(this.options.angle)
|
||||
}, false),
|
||||
stRotation: new Cesium.CallbackProperty(() => {
|
||||
return Cesium.Math.toRadians(this.options.angle)
|
||||
}, false)
|
||||
}
|
||||
})
|
||||
if (this.sdk.viewer._element.className === 'cesium-viewer 2d') {
|
||||
this.entity.rectangle.height = 1000000
|
||||
}
|
||||
syncData(this.sdk, this.options.id)
|
||||
if(this.options.show) {
|
||||
setSplitDirection(0, this.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._element_style = null
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
this._element_style = document.createElement('style')
|
||||
this._element_style.type = 'text/css'
|
||||
this._element_style.setAttribute('data-name', 'YJ_style_dialog')
|
||||
this._element_style.innerHTML = css()
|
||||
|
||||
this._DialogObject = await new Dialog(
|
||||
this.sdk,
|
||||
this.originalOptions,
|
||||
{
|
||||
title: '编辑属性',
|
||||
left: '180px',
|
||||
top: '100px',
|
||||
confirmCallBack: options => {
|
||||
this.text = this.text.trim()
|
||||
if (!this.text) {
|
||||
this.text = '未命名对象'
|
||||
}
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
this._DialogObject.close()
|
||||
this.Dialog.confirmCallBack &&
|
||||
this.Dialog.confirmCallBack(this.originalOptions)
|
||||
syncData(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.positionEditing = false
|
||||
// this.entity.style = new Cesium.Cesium3DTileStyle({
|
||||
// color: "color('rgba(255,255,255," + this.newData.transparency + ")')",
|
||||
// show: true,
|
||||
// });
|
||||
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
},
|
||||
showCallBack: show => {
|
||||
this.show = show
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
translationalCallBack: () => {
|
||||
this.positionEditing = !this.positionEditing
|
||||
}
|
||||
},
|
||||
true
|
||||
)
|
||||
document.getElementsByTagName('head')[0].appendChild(this._element_style)
|
||||
let contentElm = document.createElement('div')
|
||||
contentElm.innerHTML = html()
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
let all_elm = contentElm.getElementsByTagName('*')
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
|
||||
// 颜色组件
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName('color')[0],
|
||||
size: 'mini', //颜色box类型
|
||||
alpha: true, //是否开启透明度
|
||||
defaultColor: this.color,
|
||||
disabled: false, //是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity', //打开颜色选择器动画
|
||||
sure: color => {
|
||||
this.color = color
|
||||
}, //点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
} //点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color = [colorPicker]
|
||||
} 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@desc 打开平移功能
|
||||
*
|
||||
* @memberOf Source
|
||||
* @param status {boolean}
|
||||
*
|
||||
* */
|
||||
set positionEditing(status) {
|
||||
if (!this.sdk || !this.sdk.viewer || !this.entity) {
|
||||
return
|
||||
}
|
||||
this._positionEditing = status
|
||||
this.previous = {
|
||||
position: { ...this.options.position }
|
||||
}
|
||||
if (status === true) {
|
||||
this.tip && this.tip.destroy()
|
||||
this.tip = new MouseTip('点击鼠标左键确认,右键取消', this.sdk)
|
||||
this.event.mouse_move((movement, cartesian) => {
|
||||
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.position.lng = position.lng
|
||||
this.options.position.lat = position.lat
|
||||
this.options.position.alt = position.alt
|
||||
this.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
this.event.mouse_left((movement, cartesian) => {
|
||||
let position = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||
this.options.position.lng = position.lng
|
||||
this.options.position.lat = position.lat
|
||||
this.options.position.alt = position.alt
|
||||
this.event.mouse_move(() => {})
|
||||
this.event.mouse_left(() => {})
|
||||
this.event.mouse_right(() => {})
|
||||
this.positionEditing = false
|
||||
})
|
||||
this.event.mouse_right((movement, cartesian) => {
|
||||
this.options.position.lng = this.previous.position.lng
|
||||
this.options.position.lat = this.previous.position.lat
|
||||
this.options.position.alt = this.previous.position.alt
|
||||
this.positionEditing = false
|
||||
})
|
||||
} else {
|
||||
if (this.event) {
|
||||
this.event.mouse_move(() => { })
|
||||
this.event.mouse_left(() => { })
|
||||
this.event.mouse_right(() => { })
|
||||
}
|
||||
this.tip && this.tip.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
get positionEditing() {
|
||||
return this._positionEditing
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞到
|
||||
*/
|
||||
async flyTo(options = {}) {
|
||||
let canvas = this.getcanvas()
|
||||
let ratio = canvas.height / canvas.width
|
||||
if (this.options.customView) {
|
||||
this.sdk.viewer.camera.flyTo({
|
||||
destination: this.options.customView.position,
|
||||
orientation: this.options.customView.orientation
|
||||
})
|
||||
} else {
|
||||
let gap =
|
||||
Math.abs(Math.cos((Math.PI / 180) * this.options.position.lat)) *
|
||||
(0.0001 * this.options.scale)
|
||||
let fromDegreesArray = [
|
||||
[
|
||||
this.options.position.lng - (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat - gap
|
||||
],
|
||||
[
|
||||
this.options.position.lng + (0.0001 * this.options.scale) / ratio,
|
||||
this.options.position.lat + gap
|
||||
]
|
||||
]
|
||||
let height = await this.getClampToHeight(this.options.position)
|
||||
let positionArray = []
|
||||
for (let i = 0; i < fromDegreesArray.length; i++) {
|
||||
let a = Cesium.Cartesian3.fromDegrees(...fromDegreesArray[i], height)
|
||||
positionArray.push(a.x, a.y, a.z)
|
||||
}
|
||||
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||
this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||
offset: options.orientation || {
|
||||
heading: Cesium.Math.toRadians(0.0),
|
||||
pitch: Cesium.Math.toRadians(-90.0),
|
||||
roll: Cesium.Math.toRadians(0.0)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.options = this.deepCopyObj(this.originalOptions)
|
||||
this.text = this.originalOptions.text
|
||||
this.angle = this.originalOptions.angle
|
||||
this.scale = this.originalOptions.scale
|
||||
this.color = this.originalOptions.color
|
||||
}
|
||||
|
||||
async remove() {
|
||||
this.event && this.event.destroy()
|
||||
this.tip && this.tip.destroy()
|
||||
this.sdk.viewer.entities.remove(this.entity)
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
getcanvas() {
|
||||
const canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
let textArray = this.options.text.split('\n')
|
||||
let maxWidth = 0
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
ctx.font = 200 + 'px serif'
|
||||
const width = ctx.measureText(textArray[i]).width
|
||||
if (maxWidth < width) {
|
||||
maxWidth = width
|
||||
}
|
||||
}
|
||||
canvas.width = maxWidth
|
||||
canvas.height = 220 * textArray.length
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
ctx.font = 200 + 'px serif'
|
||||
ctx.fillStyle = 'rgba(255, 255, 255, 0)'
|
||||
ctx.fillRect(0, 0, maxWidth + 30, 210)
|
||||
ctx.fillStyle = this.options.color
|
||||
ctx.font = '200px serif'
|
||||
ctx.fillText(textArray[i], 0, 210 * (i + 1))
|
||||
}
|
||||
|
||||
return canvas
|
||||
}
|
||||
}
|
||||
|
||||
export default GroundText
|
30
src/Obj/Base/TextObject/StandText/_element.js
Normal file
30
src/Obj/Base/TextObject/StandText/_element.js
Normal file
@ -0,0 +1,30 @@
|
||||
function html(that) {
|
||||
return `
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">名称</span>
|
||||
<textarea @model="text"></textarea>
|
||||
</div>
|
||||
<div class="col" style="margin-right: 20px;">
|
||||
<span class="label">颜色</span>
|
||||
<div class="color"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
<div class="div-item">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<span class="label">滚动速度</span>
|
||||
<input type="range" max="100" min="0" step="1" @model="speed">
|
||||
<input style="font-size: 13px;width: 100px;margin-left: 10px;" type="number" title="" min="0" max="100" @model="speed">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="custom-divider"></span>
|
||||
`
|
||||
}
|
||||
|
||||
export { html }
|
783
src/Obj/Base/TextObject/StandText/index.js
Normal file
783
src/Obj/Base/TextObject/StandText/index.js
Normal file
@ -0,0 +1,783 @@
|
||||
import Dialog from '../../../Element/Dialog';
|
||||
import EventBinding from '../../../Element/Dialog/eventBinding';
|
||||
import cy_tabs from "../../../Element/cy_html_tabs";
|
||||
import richText from "../../../Element/richText";
|
||||
import { html } from "./_element";
|
||||
import Base from "../../index";
|
||||
import LabelObject from '../../LabelObject'
|
||||
import MouseEvent from '../../../../Event'
|
||||
import MouseTip from '../../../../MouseTip'
|
||||
import { syncData } from '../../../../Global/MultiViewportMode'
|
||||
import { setSplitDirection, syncSplitData, setActiveId } from '../../../../Global/SplitScreen'
|
||||
|
||||
class StandText extends Base {
|
||||
/**
|
||||
* @constructor
|
||||
* @param sdk
|
||||
* @description 立体文字
|
||||
* @param options {object}
|
||||
* @param options.text {string} 文字
|
||||
* @param options.color="#FFC107" {string} 颜色
|
||||
* @param options.speed=1 {number} 文字移动速度
|
||||
* @param {Array.<object>} positions 经纬度和高度的列表,值交替 [{lon,lat,alt},...]
|
||||
* @param _Dialog {object} 弹框事件
|
||||
* @param _Dialog.confirmCallBack {function} 弹框确认时的回调
|
||||
* */
|
||||
constructor(sdk, options, _Dialog = {}) {
|
||||
super(sdk, options);
|
||||
this.options.text = options.text || "未命名对象"
|
||||
let textArray = this.options.text.split('\n')
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
if (textArray[i].length > 80) {
|
||||
textArray[i] = textArray[i].slice(0, 80-textArray[i].length)
|
||||
}
|
||||
}
|
||||
if (textArray.length > 70) {
|
||||
textArray.splice(70 - textArray.length)
|
||||
}
|
||||
this.options.text = textArray.join('\n')
|
||||
this.options.color = options.color || "#FFC107"
|
||||
// this.options.cornerType = options.cornerType || 'MITERED'
|
||||
this.options.positions = options.positions
|
||||
// this.options.material = Number(options.material) || 0
|
||||
this.options.speed = (options.speed || options.speed === 0) ? options.speed : 1
|
||||
// this.options.duration = (options.duration || options.duration === 0) ? options.duration : 50000
|
||||
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||
this.nodePoints = []
|
||||
this.entity
|
||||
this.options.instruct = options.instruct || ""
|
||||
this.options.operatingPoint = options.operatingPoint || ""
|
||||
this.options.attribute = options.attribute || {}
|
||||
this.options.attribute.link = this.options.attribute.link || {}
|
||||
this.options.attribute.link.content = this.options.attribute.link.content || []
|
||||
this.options.attribute.camera = this.options.attribute.camera || []
|
||||
this.options.attributeType = options.attributeType || 'richText'
|
||||
this.extrudedHeight
|
||||
this._EventBinding = new EventBinding()
|
||||
this.Dialog = _Dialog
|
||||
this._elms = {};
|
||||
this.sdk.addIncetance(this.options.id, this)
|
||||
StandText.create(this)
|
||||
}
|
||||
|
||||
get text() {
|
||||
return this.options.text
|
||||
}
|
||||
|
||||
set text(v) {
|
||||
this.options.text = v
|
||||
let textArray = this.options.text.split('\n')
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
if (textArray[i].length > 80) {
|
||||
let _error = '行超过80个字符,请按回车(Enter)后,继续输入'
|
||||
window.ELEMENT && window.ELEMENT.Message({
|
||||
message: _error,
|
||||
type: 'warning',
|
||||
duration: 1000
|
||||
});
|
||||
textArray[i] = textArray[i].slice(0, 80-textArray[i].length)
|
||||
}
|
||||
}
|
||||
if (textArray.length > 70) {
|
||||
textArray.splice(70 - textArray.length)
|
||||
let _error = '超过最大输入字符'
|
||||
window.ELEMENT && window.ELEMENT.Message({
|
||||
message: _error,
|
||||
type: 'warning',
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
this.options.text = textArray.join('\n')
|
||||
if (this.entity) {
|
||||
let positions = this.options.positions
|
||||
let fromDegreesArray = []
|
||||
let minimumHeights = []
|
||||
let maximumHeights = []
|
||||
let material = this.getMaterial()
|
||||
let width = this.computeDistance(positions)
|
||||
let extrudedHeight = this.aspectRatio ? (width / this.aspectRatio) : 0
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
minimumHeights.push(positions[i].alt)
|
||||
maximumHeights.push(positions[i].alt + extrudedHeight)
|
||||
}
|
||||
this.entity.wall.material = material
|
||||
this.entity.wall.maximumHeights = maximumHeights
|
||||
this.entity.wall.minimumHeights = minimumHeights
|
||||
}
|
||||
this._elms.text && this._elms.text.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
get color() {
|
||||
return this.options.color
|
||||
}
|
||||
set color(v) {
|
||||
this.options.color = v
|
||||
this.entity.wall.material = this.getMaterial()
|
||||
if (this._elms.color) {
|
||||
this._elms.color.forEach((item, i) => {
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: item.el,
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: v,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (c) => {
|
||||
this.color = c
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
this._elms.color[i] = colorPicker
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// get material() {
|
||||
// return this.options.material
|
||||
// }
|
||||
// set material(v) {
|
||||
// this.options.material = Number(v)
|
||||
// this.entity.wall.material = this.getMaterial()
|
||||
// this._elms.material && this._elms.material.forEach((item) => {
|
||||
// item.value = v
|
||||
// })
|
||||
// }
|
||||
|
||||
get speed() {
|
||||
return this.options.speed
|
||||
}
|
||||
|
||||
set speed(v) {
|
||||
this.options.speed = v
|
||||
this.entity.wall.material = this.getMaterial()
|
||||
this._elms.speed && this._elms.speed.forEach((item) => {
|
||||
item.value = v
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// get attributeLink() {
|
||||
// return this.options.attribute.link.content
|
||||
// }
|
||||
|
||||
// set attributeLink(v) {
|
||||
// this.options.attribute.link.content = v
|
||||
// if (!this._DialogObject || !this._DialogObject._element || !this._DialogObject._element.content) {
|
||||
// return
|
||||
// }
|
||||
// let table = this._DialogObject._element.content.getElementsByClassName('attribute-content-link')[1].getElementsByClassName('table')[0]
|
||||
// let tableContent = table.getElementsByClassName('table-body')[0]
|
||||
// tableContent.innerHTML = ''
|
||||
// if (this.options.attribute.link.content.length > 0) {
|
||||
// table.getElementsByClassName('table-empty')[0].style.display = 'none'
|
||||
// }
|
||||
// else {
|
||||
// table.getElementsByClassName('table-empty')[0].style.display = 'flex'
|
||||
// }
|
||||
// for (let i = 0; i < this.options.attribute.link.content.length; i++) {
|
||||
// let tr = `
|
||||
// <div class="tr">
|
||||
// <div class="td">` + this.options.attribute.link.content[i].name + `</div>
|
||||
// <div class="td">` + this.options.attribute.link.content[i].url + `</div>
|
||||
// <div class="td">
|
||||
// <button class="text" @click="linkEdit">编辑</button>
|
||||
// <button class="text" @click="linkDelete">删除</button>
|
||||
// </div>
|
||||
// </div>`
|
||||
// let trElm = document.createRange().createContextualFragment(tr)
|
||||
// tableContent.appendChild(trElm)
|
||||
// }
|
||||
// let item = tableContent.getElementsByClassName('tr')
|
||||
// let fun = {
|
||||
// linkEdit: async (index) => {
|
||||
// this.attributeLink = await this.options.attribute.link.content
|
||||
// let table = this._DialogObject._element.content.getElementsByClassName('attribute-content-link')[1].getElementsByClassName('table')[0]
|
||||
// let tableContent = table.getElementsByClassName('table-body')[0]
|
||||
// let item = tableContent.getElementsByClassName('tr')
|
||||
// for (let i = 0; i < item.length; i++) {
|
||||
// if (index === i) {
|
||||
// let html = `
|
||||
// <div class="td">
|
||||
// <input class="input" type="text">
|
||||
// </div>
|
||||
// <div class="td">
|
||||
// <div class="input-group">
|
||||
// <input class="input" type="text" style="width: 140px;">
|
||||
// <input type="file" accept=".mp4, .pdf" class="file-select" index="`+ i + `" style="display:none">
|
||||
// <button @click="fileSelect">...</button>
|
||||
// </div>
|
||||
// </div>
|
||||
// <div class="td">
|
||||
// <button class="text" @click="confirmEdit">确认</button>
|
||||
// <button class="text" @click="cancelEdit">取消</button>
|
||||
// </div>`
|
||||
// item[i].innerHTML = html
|
||||
// let td = item[i].getElementsByClassName('td')
|
||||
// td[0].getElementsByClassName('input')[0].value = this.options.attribute.link.content[index].name
|
||||
// td[1].getElementsByClassName('input')[0].value = this.options.attribute.link.content[index].url
|
||||
// let btn = item[i].getElementsByTagName('button')
|
||||
// for (let n = 0; n < btn.length; n++) {
|
||||
// for (let m of btn[n].attributes) {
|
||||
// if (m.name === '@click') {
|
||||
// btn[n].addEventListener('click', (e) => {
|
||||
// if (typeof (fun[m.value]) === 'function') {
|
||||
// fun[m.value]({ name: td[0].getElementsByClassName('input')[0].value, url: td[1].getElementsByClassName('input')[0].value }, i)
|
||||
// }
|
||||
// });
|
||||
// btn[n].attributes.removeNamedItem(m.name)
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// linkDelete: (i) => {
|
||||
// this.options.attribute.link.content.splice(i, 1)
|
||||
// this.attributeLink = this.options.attribute.link.content
|
||||
// },
|
||||
|
||||
// confirmEdit: (value, i) => {
|
||||
// this.options.attribute.link.content[i] = value
|
||||
// this.attributeLink = this.options.attribute.link.content
|
||||
// },
|
||||
// cancelEdit: () => {
|
||||
// this.attributeLink = this.options.attribute.link.content
|
||||
// },
|
||||
// fileSelect: (value, i) => {
|
||||
// let fileElm = item[i].getElementsByClassName('file-select')[0]
|
||||
// fileElm.click()
|
||||
// fileElm.removeEventListener('change', fileSelect)
|
||||
// fileElm.addEventListener('change', fileSelect)
|
||||
// }
|
||||
// }
|
||||
// let fileSelect = (event) => {
|
||||
// if (event.target.value) {
|
||||
// let td = item[event.target.getAttribute('index')].getElementsByClassName('td')
|
||||
// td[1].getElementsByClassName('input')[0].value = event.target.value
|
||||
// event.target.value = null
|
||||
// }
|
||||
// }
|
||||
// for (let i = 0; i < item.length; i++) {
|
||||
// let btn = item[i].getElementsByTagName('button')
|
||||
// for (let n = 0; n < btn.length; n++) {
|
||||
// for (let m of btn[n].attributes) {
|
||||
// if (m.name === '@click') {
|
||||
// btn[n].addEventListener('click', (e) => {
|
||||
// if (typeof (fun[m.value]) === 'function') {
|
||||
// fun[m.value](i)
|
||||
// }
|
||||
// });
|
||||
// btn[n].attributes.removeNamedItem(m.name)
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
get attributeCamera() {
|
||||
return this.options.attribute.camera
|
||||
}
|
||||
|
||||
set attributeCamera(v) {
|
||||
this.options.attribute.camera = v
|
||||
}
|
||||
|
||||
//创建
|
||||
static async create(that) {
|
||||
|
||||
// console.log(new Cesium.CustomMaterialSource(), new Cesium.PolylineTrailLinkMaterialProperty())
|
||||
let positions = that.options.positions
|
||||
let fromDegreesArray = []
|
||||
let minimumHeights = []
|
||||
let maximumHeights = []
|
||||
let material = that.getMaterial()
|
||||
let width = that.computeDistance(positions)
|
||||
let extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
|
||||
// aspectRatio
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
minimumHeights.push(positions[i].alt)
|
||||
maximumHeights.push(positions[i].alt + extrudedHeight)
|
||||
}
|
||||
|
||||
that.entity = that.sdk.viewer.entities.add({
|
||||
id: that.options.id,
|
||||
show: that.options.show,
|
||||
wall: {
|
||||
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
|
||||
cornerType: Cesium.CornerType.MITERED,
|
||||
maximumHeights: maximumHeights,
|
||||
minimumHeights: minimumHeights,
|
||||
material: material,
|
||||
},
|
||||
// wall: {
|
||||
// positions: Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray),
|
||||
// maximumHeights: maximumHeights,
|
||||
// minimumHeights: minimumHeights,
|
||||
// material: new Cesium.PolylineTrailLinkMaterialProperty({duration: 1500}),
|
||||
// outline: true,
|
||||
// outlineColor: Cesium.Color.BLACK,
|
||||
// }
|
||||
})
|
||||
syncData(that.sdk, that.options.id)
|
||||
if(that.options.show) {
|
||||
|
||||
setSplitDirection(0, that.options.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑框
|
||||
async edit(state) {
|
||||
let _this = this
|
||||
this.originalOptions = this.deepCopyObj(this.options)
|
||||
|
||||
if (this._DialogObject && this._DialogObject.close) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
if (state) {
|
||||
this._DialogObject = await new Dialog(this.sdk, this.options, {
|
||||
title: '立体文字属性', left: '180px', top: '100px',
|
||||
confirmCallBack: (options) => {
|
||||
this.text = this.text.trim()
|
||||
if (!this.text) {
|
||||
this.text = '未命名对象'
|
||||
}
|
||||
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.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||
for (let i = 0; i < this.nodePoints.length; i++) {
|
||||
this.sdk.viewer.entities.remove(this.nodePoints[i])
|
||||
}
|
||||
this.nodePoints = []
|
||||
YJ.Measure.SetMeasureStatus(false)
|
||||
this.event && this.event.destroy()
|
||||
this.tip && this.tip.destroy()
|
||||
},
|
||||
showCallBack: (show) => {
|
||||
this.options.show = show
|
||||
this.originalOptions.show = show
|
||||
this.show = show
|
||||
this.Dialog.showCallBack && this.Dialog.showCallBack()
|
||||
},
|
||||
secondaryEditCallBack: () => {
|
||||
StandText.nodeEdit(this)
|
||||
}
|
||||
})
|
||||
this._DialogObject._element.body.className = this._DialogObject._element.body.className + ' stand-text'
|
||||
let contentElm = document.createElement('div');
|
||||
contentElm.innerHTML = html(this)
|
||||
this._DialogObject.contentAppChild(contentElm)
|
||||
this.attributeType = this.options.attributeType
|
||||
this.attributeCamera = this.options.attribute.camera
|
||||
// setTimeout(() => {
|
||||
// this.attributeLink = this.options.attribute.link.content
|
||||
// this.cameraSelect()
|
||||
// }, 500);
|
||||
|
||||
// 创建标签页
|
||||
// let tabsElm = new cy_tabs('radar-scan-edit-tabs')
|
||||
// 颜色组件
|
||||
let colorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("color")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.color,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.color = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.color = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let labelColorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelColor")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.labelColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.labelColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.labelColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let lineColorPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelLineColor")[0],
|
||||
size: 'mini',//颜色box类型
|
||||
alpha: true,//是否开启透明度
|
||||
defaultColor: this.labelLineColor,
|
||||
disabled: false,//是否禁止打开颜色选择器
|
||||
openPickerAni: 'opacity',//打开颜色选择器动画
|
||||
sure: (color) => {
|
||||
this.labelLineColor = color
|
||||
},//点击确认按钮事件回调
|
||||
clear: () => {
|
||||
this.labelLineColor = 'rgba(255,255,255,1)'
|
||||
},//点击清空按钮事件回调
|
||||
})
|
||||
let labelBackgroundColorStartPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelBackgroundColorStart")[0],
|
||||
size: 'mini',
|
||||
alpha: true,
|
||||
defaultColor: this.labelBackgroundColorStart,
|
||||
disabled: false,
|
||||
openPickerAni: 'opacity',
|
||||
sure: (color) => {
|
||||
this.labelBackgroundColorStart = color
|
||||
},
|
||||
clear: () => {
|
||||
this.labelBackgroundColorStart = 'rgba(255,255,255,1)'
|
||||
},
|
||||
})
|
||||
let labelBackgroundColorEndPicker = new ewPlugins('colorpicker', {
|
||||
el: contentElm.getElementsByClassName("labelBackgroundColorEnd")[0],
|
||||
size: 'mini',
|
||||
alpha: true,
|
||||
defaultColor: this.labelBackgroundColorEnd,
|
||||
disabled: false,
|
||||
openPickerAni: 'opacity',
|
||||
sure: (color) => {
|
||||
this.labelBackgroundColorEnd = color
|
||||
},
|
||||
clear: () => {
|
||||
this.labelBackgroundColorEnd = 'rgba(255,255,255,1)'
|
||||
},
|
||||
})
|
||||
|
||||
let all_elm = contentElm.getElementsByTagName("*")
|
||||
this._EventBinding.on(this, all_elm)
|
||||
this._elms = this._EventBinding.element
|
||||
this._elms.color = [colorPicker]
|
||||
this._elms.labelColor = [labelColorPicker]
|
||||
this._elms.labelLineColor = [lineColorPicker]
|
||||
this._elms.labelBackgroundColorStart = [labelBackgroundColorStartPicker]
|
||||
this._elms.labelBackgroundColorEnd = [labelBackgroundColorEndPicker]
|
||||
} else {
|
||||
if (this._DialogObject && this._DialogObject.remove) {
|
||||
this._DialogObject.remove()
|
||||
this._DialogObject = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.entity) {
|
||||
return
|
||||
}
|
||||
this.options = this.deepCopyObj(this.originalOptions)
|
||||
this.text = this.originalOptions.text
|
||||
this.color = this.originalOptions.color
|
||||
this.speed = this.originalOptions.speed
|
||||
|
||||
let positions = this.options.positions
|
||||
let fromDegreesArray = []
|
||||
let minimumHeights = []
|
||||
let maximumHeights = []
|
||||
let width = this.computeDistance(positions)
|
||||
let extrudedHeight = this.aspectRatio ? (width / this.aspectRatio) : 0
|
||||
// aspectRatio
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
minimumHeights.push(positions[i].alt)
|
||||
maximumHeights.push(positions[i].alt + extrudedHeight)
|
||||
}
|
||||
this.entity.wall.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
|
||||
}
|
||||
|
||||
async remove() {
|
||||
this.event && this.event.destroy()
|
||||
this.tip && this.tip.destroy()
|
||||
this.sdk.viewer.entities.remove(this.entity)
|
||||
this.entity = null
|
||||
if (this._DialogObject && !this._DialogObject.isDestroy) {
|
||||
this._DialogObject.close()
|
||||
this._DialogObject = null
|
||||
}
|
||||
await this.sdk.removeIncetance(this.options.id)
|
||||
await syncData(this.sdk, this.options.id)
|
||||
}
|
||||
|
||||
getMaterial() {
|
||||
let material
|
||||
let canvas = this.getcanvas()
|
||||
material = new Cesium.CustomMaterialSource({
|
||||
image: canvas.toDataURL("image/png"),
|
||||
color: this.options.color,
|
||||
repeat: new Cesium.Cartesian2(1, 1.0),
|
||||
duration: 50000 / this.options.speed,
|
||||
fltr: false
|
||||
})
|
||||
return material
|
||||
}
|
||||
|
||||
getcanvas() {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d')
|
||||
|
||||
let textArray = this.options.text.split('\n')
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
if (textArray[i].length > 80) {
|
||||
textArray[i] = textArray[i].slice(0, 80-textArray[i].length)
|
||||
}
|
||||
}
|
||||
if (textArray.length > 70) {
|
||||
textArray.splice(70 - textArray.length)
|
||||
}
|
||||
this.options.text = textArray.join('\n')
|
||||
let maxWidth = 0
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
ctx.font = 200 + "px serif";
|
||||
const width = ctx.measureText(textArray[i]).width;
|
||||
if(maxWidth<width) {
|
||||
maxWidth = width
|
||||
}
|
||||
}
|
||||
canvas.width = maxWidth
|
||||
canvas.height = 220 * textArray.length
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
ctx.font = 200 + "px serif";
|
||||
ctx.fillStyle = 'rgba(255, 255, 255, 0)'
|
||||
ctx.fillRect(0, 0, maxWidth + 30, 210)
|
||||
ctx.fillStyle = this.options.color;
|
||||
ctx.font = "200px serif";
|
||||
ctx.fillText(textArray[i], 0, 210 * (i+1));
|
||||
}
|
||||
|
||||
this.aspectRatio = this.options.text ? (canvas.width / canvas.height) : 0
|
||||
return canvas
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开富文本框
|
||||
*/
|
||||
openRichTextEditor(e) {
|
||||
richText.open(this.options.id, this.options.text, this.options.richTextContent)
|
||||
richText.primaryCallBack = (content) => {
|
||||
this.options.richTextContent = content
|
||||
}
|
||||
}
|
||||
|
||||
static nodeEdit(that, cb = () => { }) {
|
||||
if (YJ.Measure.GetMeasureStatus()) {
|
||||
cb('上一次测量未结束')
|
||||
} else {
|
||||
YJ.Measure.SetMeasureStatus(true)
|
||||
that.tip = new MouseTip('请选择一个顶点,右键取消', that.sdk)
|
||||
that.event = new MouseEvent(that.sdk)
|
||||
that.nodePoints = []
|
||||
let selectPoint
|
||||
let originalPosition
|
||||
|
||||
let positions = that.options.positions
|
||||
let fromDegreesArray = []
|
||||
let minimumHeights = []
|
||||
let maximumHeights = []
|
||||
let width = that.computeDistance(positions)
|
||||
let extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
minimumHeights.push(positions[i].alt)
|
||||
maximumHeights.push(positions[i].alt + extrudedHeight)
|
||||
}
|
||||
|
||||
let isAdd = false
|
||||
let leftEvent = (movement, cartesian) => {
|
||||
if (selectPoint) {
|
||||
isAdd = true
|
||||
let pos3 = that.sdk.viewer.scene.clampToHeight(cartesian, [that.entity])
|
||||
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(pos3, that.sdk.viewer)
|
||||
originalPosition = that.options.positions[selectPoint.index]
|
||||
let entity = that.sdk.viewer.entities.add({
|
||||
name: 'node-secondary-edit-point',
|
||||
position: Cesium.Cartesian3.fromDegrees(that.options.positions[selectPoint.index].lng, that.options.positions[selectPoint.index].lat, that.options.positions[selectPoint.index].alt),
|
||||
billboard: {
|
||||
image: that.getSourceRootPath() + '/img/point.png',
|
||||
width: 15,
|
||||
height: 15,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||
},
|
||||
})
|
||||
that.nodePoints.splice(selectPoint.index, 0, entity)
|
||||
that.options.positions.splice(selectPoint.index, 0, that.options.positions[selectPoint.index])
|
||||
|
||||
let positions = that.options.positions
|
||||
fromDegreesArray = []
|
||||
minimumHeights = []
|
||||
maximumHeights = []
|
||||
width = that.computeDistance(positions)
|
||||
extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
minimumHeights.push(positions[i].alt)
|
||||
maximumHeights.push(positions[i].alt + extrudedHeight)
|
||||
}
|
||||
that.tip.setPosition(
|
||||
cartesian,
|
||||
movement.position.x,
|
||||
movement.position.y
|
||||
)
|
||||
}
|
||||
else {
|
||||
var pick = that.sdk.viewer.scene.pick(movement.position);
|
||||
if (pick && pick.id && pick.id.name && pick.id.name === 'node-secondary-edit-point') {
|
||||
selectPoint = pick.id
|
||||
that.nodePoints.splice(pick.id.index, 1)
|
||||
that.sdk.viewer.entities.remove(pick.id)
|
||||
that.tip.set_text('左键开始,右键结束,CTRL+右键撤销')
|
||||
originalPosition = that.cartesian3Towgs84(cartesian, that.sdk.viewer)
|
||||
that.entity.wall.positions = new Cesium.CallbackProperty(function () {
|
||||
return Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
|
||||
}, false)
|
||||
that.entity.wall.maximumHeights = new Cesium.CallbackProperty(function () {
|
||||
return maximumHeights
|
||||
}, false)
|
||||
that.entity.wall.minimumHeights = new Cesium.CallbackProperty(function () {
|
||||
return minimumHeights
|
||||
}, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
let rightEvent = (movement, cartesian) => {
|
||||
if (selectPoint) {
|
||||
that.options.positions[selectPoint.index] = originalPosition
|
||||
if(isAdd) {
|
||||
that.options.positions.splice(selectPoint.index, 1)
|
||||
}
|
||||
cb(null, that.options.positions)
|
||||
}
|
||||
let positions = that.options.positions
|
||||
fromDegreesArray = []
|
||||
minimumHeights = []
|
||||
maximumHeights = []
|
||||
width = that.computeDistance(positions)
|
||||
extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
minimumHeights.push(positions[i].alt)
|
||||
maximumHeights.push(positions[i].alt + extrudedHeight)
|
||||
}
|
||||
that.entity.wall.positions = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
|
||||
|
||||
for (let i = 0; i < that.nodePoints.length; i++) {
|
||||
that.sdk.viewer.entities.remove(that.nodePoints[i])
|
||||
}
|
||||
that.nodePoints = []
|
||||
YJ.Measure.SetMeasureStatus(false)
|
||||
that.event.destroy()
|
||||
that.tip.destroy()
|
||||
}
|
||||
|
||||
that.event.mouse_left(leftEvent)
|
||||
|
||||
that.event.mouse_right(rightEvent)
|
||||
|
||||
that.event.mouse_move((movement, cartesian) => {
|
||||
if (selectPoint) {
|
||||
let pos3 = that.sdk.viewer.scene.clampToHeight(cartesian, [that.entity])
|
||||
that.options.positions[selectPoint.index] = that.cartesian3Towgs84(pos3, that.sdk.viewer)
|
||||
let positions = that.options.positions
|
||||
fromDegreesArray = []
|
||||
minimumHeights = []
|
||||
maximumHeights = []
|
||||
width = that.computeDistance(positions)
|
||||
extrudedHeight = that.aspectRatio ? (width / that.aspectRatio) : 0
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||
minimumHeights.push(positions[i].alt)
|
||||
maximumHeights.push(positions[i].alt + extrudedHeight)
|
||||
}
|
||||
}
|
||||
that.tip.setPosition(
|
||||
cartesian,
|
||||
movement.endPosition.x,
|
||||
movement.endPosition.y
|
||||
)
|
||||
})
|
||||
|
||||
that.event.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||
if (selectPoint) {
|
||||
that.options.positions.pop()
|
||||
that.sdk.viewer.entities.remove(that.nodePoints[that.nodePoints.length - 1])
|
||||
that.nodePoints.pop()
|
||||
if (selectPoint.index === that.options.positions.length) {
|
||||
if (that.nodePoints[selectPoint.index - 1]) {
|
||||
selectPoint = that.nodePoints[selectPoint.index - 1]
|
||||
}
|
||||
else {
|
||||
selectPoint.index = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
that.event.gesture_pinck_start((movement, cartesian) => {
|
||||
let startTime = new Date()
|
||||
let pos = {
|
||||
position: {
|
||||
x: (movement.position1.x + movement.position2.x) / 2,
|
||||
y: (movement.position1.y + movement.position2.y) / 2
|
||||
}
|
||||
}
|
||||
that.event.gesture_pinck_end(() => {
|
||||
let endTime = new Date()
|
||||
if (endTime - startTime >= 500) {
|
||||
// 长按取消
|
||||
rightEvent(pos, cartesian)
|
||||
}
|
||||
else {
|
||||
leftEvent(pos, cartesian)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
for (let i = 0; i < that.options.positions.length; i++) {
|
||||
let entity = that.sdk.viewer.entities.add({
|
||||
name: 'node-secondary-edit-point',
|
||||
index: i,
|
||||
position: Cesium.Cartesian3.fromDegrees(that.options.positions[i].lng, that.options.positions[i].lat, that.options.positions[i].alt),
|
||||
billboard: {
|
||||
image: that.getSourceRootPath() + '/img/point.png',
|
||||
width: 15,
|
||||
height: 15,
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||
},
|
||||
})
|
||||
that.nodePoints.push(entity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default StandText
|
Reference in New Issue
Block a user