// 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