添加弹窗 效果
首先安排插件 creatinfobox.js (这是在vue项目的引入,其他适当调整即可)
/*
* @Author: your name
* @Date: 2022-01-27 10:58:22
* @LastEditTime: 2022-02-09 17:19:34
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \branches\src\common\js\createInfoBox.js
*/
import {CSS3DRenderer, CSS3DObject, CSS3DSprite} from 'three/examples/jsm/renderers/CSS3DRenderer';
import {CSS2DRenderer, CSS2DObject} from 'three/examples/jsm/renderers/CSS2DRenderer';
export default class CreateInfoBox {
constructor(scene, element, renderModel = 3) {
this.renderModel = renderModel; // css的渲染的模式(2D 和 3D 模式)
this.cssRenderer = undefined; // Renderer对象
this.scene = scene; // Renderer对象
this.cssRendererDomElement = undefined; // 信息框的dom对象
// this.infoBoxLayer = new Group();// 信息框的三维物体组
this.config = {};
this.init(element); // 初始化
this.dom = null;
this.tmp = null;
}
init(element) {
const cssRenderer = this.renderModel === 2 ? new CSS2DRenderer() : new CSS3DRenderer();
cssRenderer.setSize(element.offsetWidth, element.offsetHeight);
cssRenderer.domElement.style.position = 'absolute';
cssRenderer.domElement.style.top = 0;
cssRenderer.domElement.style.pointerEvents = 'none';
element.appendChild(cssRenderer.domElement);
this.cssRenderer = cssRenderer;
this.cssRendererDomElement = cssRenderer.domElement;
}
add(option) {
let list = [];
if (Array.isArray(option))
list = option;
else
list.push(option);
list.forEach(e => {
this.dom = document.createElement('div');
this.tmp = document.createElement('div');
this.tmp.innerHTML = e.element;
this.dom = this.tmp.children[0];
const label = this.renderModel === 2 ? new CSS2DObject(this.dom) : this.renderModel === 3 ? new CSS3DObject(this.dom) : new CSS3DSprite(this.dom);
label.userData.isCss23D = true;
label.position.set(e.position[0], e.position[1], e.position[2]);
label.name = e.name;
if (e.scale) label.scale.set(e.scale[0], e.scale[1], e.scale[2]);
e.parent ? e.parent.add(label) : this.scene.add(label);
this.config[e.name] = label;
//再添加css3引导线
// this.addGuideLine(e);
});
}
update(name, innerHtml) {
this.config[name].element.innerHTML = innerHtml;
}
remove(name, parent) {
parent = parent || this.scene;
parent.remove(parent.getObjectByName(name));
if (this.config[name]) delete this.config[name];
}
search(name) {
return this.config[name];
}
removeAll(parent) {
//需要倒序遍历
for (let i = parent.children.length - 1;i >= 0;i--) {
const e = parent.children[i];
if (e.userData.isCss23D) {
const name = e.name;
parent.remove(e);
if (this.config[name]) delete this.config[name];
}
}
}
}
使用
import CreateInfoBox from '../../common/createInfoBox';
//下面是在mounted中声明的
sceneContainer = document.getElementById('container'); //底图场景容器
css2dInstance = new CreateInfoBox(scene, sceneContainer, 2);
css2DRenderer = css2dInstance.cssRenderer;
//下面这个方法是关键
/**
* @event: speedTips
* @author: 大帅逼
* @param: model 需要添加到哪个模型或场景中 scene
* @param: html 文本
* @param: position 相对模型坐标位置
* @param: name 模型名称
* @description: 高速标题弹窗创建
* **/
speedTips(model, html, position, name) {
if (position) {
const css3Group = new THREE.Group(); // 信息框的三维物体组
css3Group.name = name;
const scale = [10, 10, 10];
model.add(css3Group);
const list = [
{
parent: css3Group,
name: name,
element: html,
scale: scale,
position: position
}
];
css2dInstance.add(list);
}
}
//使用示例 d3Projection是经纬度转平面的方法,这里要不要提供一些
const to3dMapPointArr = d3Projection([i.lng, i.lat]);
const modelDiv = `
<div class="lineDiv" id="lineDiv${i.id}">
</div>
`;
this.speedTips(sceneModel, modelDiv, [to3dMapPointArr[0], 270, to3dMapPointArr[1]], `lineDivS${i.id}`);
这就添加好了,一般html我们一般不在js里写,写在vue的template中,方便做数据处理,所以这里有个小技巧,可以在js代码使用上述的speedTips方法添加一个div,然后将这个div的位置信息赋给vue上写的标签
//vue
<template>
<div id="lineBox">{{name}}</div>
</template>
const to3dMapPointArr = d3Projection([i.lng, i.lat]);
const modelDiv = `
<div class="lineDiv" id="lineDiv${i.id}">
</div>
`;
this.speedTips(sceneModel, modelDiv, [to3dMapPointArr[0], 270, to3dMapPointArr[1]], `lineDivS${i.id}`);
document.getElementById('lineBox').style.transform = document.getElementById(`lineDiv${i.id}`).style.transform;
//然后根据需要适当调整弹框lineBox位置即可
最后交代一下这个 坐标换算 npm i d3-geo – save -dev
import * as d3 from ‘d3-geo’;
export function projection() {
const projectionPos = d3.geoMercator().center([81.23, 46.33]) // 这个不太懂百度吧,没百明白
.scale(6400)
.translate([0, 0]);
// console.log(projectionPos);
return projectionPos;
}
引入后使用
d3Projection = projection();
版权声明:本文为LBY_XK原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。