当前位置:   article > 正文

threejs添加弹窗_vue threejs 弹出框

vue threejs 弹出框

添加弹窗 效果

在这里插入图片描述

首先安排插件 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];
      }
    }
  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

使用

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}`);


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

这就添加好了,一般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位置即可
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

最后交代一下这个 坐标换算 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();
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/928625
推荐阅读
相关标签
  

闽ICP备14008679号