gisthreemap
Version:
基于webGL的三维api
178 lines (167 loc) • 6.87 kB
JavaScript
import $ from 'jquery'
const popbg = require('../../assets/images/popbg1.png').default || require('../../assets/images/popbg1.png')
const closebg = require('../../assets/images/关闭.png').default || require('../../assets/images/关闭.png')
const popline = require('../../assets/images/popline.svg').default || require('../../assets/images/popline.svg')
const popbgline = require('../../assets/images/popbgline.png').default || require('../../assets/images/popbgline.png')
const clientHeight = document.body.clientHeight
const clientWidth = document.body.clientWidth
// 创建弹窗对象的方法
class Popup {
constructor(viewer) {
this.viewer = viewer //弹窗创建的viewer
this.position = null //弹窗挂载的位置
this.ctn = document.createElement('div')
this.ctn.style.position = 'absolute'
// this.ctn.style.height = '300px'
this.ctn.style.height = 'auto'
// 地球渲染改变弹窗位置事件监听
this.eventListener = () => {
const canvasPosition = this.viewer.scene.cartesianToCanvasCoordinates(this.position, new Cesium.Cartesian2()) // 笛卡尔坐标到画布坐标
if (canvasPosition) {
this.render(canvasPosition)
// 地球背面隐藏
const cameraPosition = this.viewer.camera.position
let height = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cameraPosition).height
height += this.viewer.scene.globe.ellipsoid.maximumRadius
if (!(Cesium.Cartesian3.distance(cameraPosition, this.position) > height)) {
this.ctn.style.display = 'block'
} else {
this.ctn.style.display = 'none'
}
if ((canvasPosition.y) > (clientHeight) || (canvasPosition.x) > (clientWidth - this.ctn.clientWidth)) {
this.ctn.style.display = 'none'
} else {
this.ctn.style.display = 'block'
}
}
}
}
open(options) {
this.position = options.position
if (options.custombox) {
// 自定义框
this.customHtml(options.content)
// this.ctn = options.content
} else {
this.ctn = document.createElement('div')
this.ctn.style.position = 'absolute'
// this.ctn.style.height = '300px'
this.ctn.style.height = 'auto'
// 默认框
this.createHtml(options.title, options.content, options.onClose, options.style)
}
// 自定义传入框
this.removeHandler = this.viewer.scene.preRender.addEventListener(this.eventListener)
//相机移动开始事件
this.viewer.scene.camera.moveStart.addEventListener(() => {
console.log('start')
this.removeHandler = this.viewer.scene.preRender.addEventListener(this.eventListener)
})
//相机移动结束事件
this.viewer.scene.camera.moveEnd.addEventListener(() => {
console.log('end')
this.removeHandler.call()
})
}
render(position) {
// let offsety = this.ctn.clientHeight+50
// let offsetx = this.ctn.clientWidth/2
// this.ctn.style.left = position.x - offsetx + 'px'
// this.ctn.style.top = position.y - offsety + 'px'
let linedom = document.querySelector('.popup-line')
if (linedom) {
let offsety = linedom.clientHeight + linedom.offsetTop
let offsetx = -Number(linedom.clientWidth)
this.ctn.style.left = position.x - offsetx + 'px'
this.ctn.style.top = position.y - offsety + 'px'
}
}
createHtml(title, content, callback, style = {
popup_style: `background:url(${popbg});background-size: 100% 100%;z-index:10;
background-repeat: no-repeat;color:#3EBFE1; width: 360px;
padding: 10px;
box-sizing: border-box;`,
popup_classname: 'self-popup'
}) {
let element = `<div id='popup' class='ol-popup ${style.popup_classname}'
style = '${style.popup_style}'
>
<div class='popup-line' style="position: absolute;
left: -50px;
top: 40px;
width: 50px;">
<img src='${popline}' alt='' >
</div>
<div class='popup-title' style = '
display: flex;
justify-content: space-between;
height: 24px;
padding: 6px;
'>
<span id='popup-span-title' class='popup-span-title' style='font-family: YouSheBiaoTiHei;
font-weight: 500 !important;
font-size: 20px !important;
color: #E6F3FF;
letter-spacing: 0;
text-indent: 12px;'>${title}</span>
<a href='javascript:void(0)' id='popup-closer' class='ol-popup-closer' style='text-decoration:none;color: #3EBFE1;position: absolute;
right: 25px;
top: 28px;'>
<img src='${closebg}' alt=''>
</a>
</div>
<div class='popup-title-line' style='background:url(${popbgline});background-size: 100% 100%; height: 12px;
margin: 0 16px;'></div>
<div class='popup-content' style = 'padding: 8px;overflow:auto; padding: 0 16px !important;
max-height: 210px !important;
margin: 12px 0 20px;
font-family: SourceHanSansSC-Regular;
font-weight: 400;
font-size: 16px;
color: #31BDFF !important;
letter-spacing: 0;
box-sizing: border-box;'></div>
<div id='popup-tooltip-arrow' class='popup-tooltip-arrow' style=' position: absolute;
bottom: -24px;
display:none;
left:0px;
width: 0;
height: 0;
border-top: 12px solid rgba(3, 22, 37, 0.85);
border-right: 12px solid transparent;
border-bottom: 12px solid transparent;
border-left: 12px solid transparent;'></div>
</div>`;
this.ctn.innerHTML = element
this.viewer.container.append(this.ctn);
let outContent = document.querySelector('.popup-content');
// if (style.parent_style.height) this.ctn.style.height = style.parent_style.height;
if (typeof content === 'string') {
outContent.innerHTML = content
} else {
outContent.appendChild(content)
}
// 动态处理小箭头位置
const popupdom = document.querySelector('#popup')
if (popupdom) {
// 设置箭头的颜色和位置
// 居中为盒子宽度的一半 //left偏移设置无效?
document.querySelector('.popup-tooltip-arrow').style.borderColor = `${popupdom.style.backgroundColor} transparent transparent`
// 设置盒子整体偏移,使箭头对准点位
// popupdom.style.top = ''
}
document.querySelector('#popup-closer').addEventListener('click', evt => {
this.close()
if (callback) callback()
});
}
customHtml(content) {
this.ctn = content
this.viewer.container.append(this.ctn);
}
close() {
this.ctn.remove()
this.viewer.scene.preRender.removeEventListener(this.eventListener)
}
}
export default Popup