536 lines
18 KiB
JavaScript
536 lines
18 KiB
JavaScript
// 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 YJColorPicker({
|
|
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 YJColorPicker({
|
|
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 YJColorPicker({
|
|
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 YJColorPicker({
|
|
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 YJColorPicker({
|
|
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 YJColorPicker({
|
|
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 |