效果图
干货
npm install three
<template>
<div id="container"></div>
</template>
<script>
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import {CSS3DRenderer, CSS3DObject} from 'three/examples/jsm/renderers/CSS3DRenderer';
export default {
name: 'labelTest',
data() {
return {}
},
mounted() {
const frustumSize = 60;
const aspect = window.innerWidth / window.innerHeight;
var container = document.getElementById('container');
var scene = new THREE.Scene();
// var camera = new THREE.PerspectiveCamera(frustumSize, aspect, .1, 1000);
var camera = new THREE.OrthographicCamera(frustumSize * aspect / -2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / -2, 1, 1000);
camera.position.set(10, 10, 10);
var gridHelper = new THREE.GridHelper(20);
scene.add(gridHelper);
var renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement);
// 光源
scene.add(new THREE.AmbientLight(0xffffff));
let renderer2 = new CSS3DRenderer();
renderer2.setSize(window.innerWidth, window.innerHeight);
renderer2.domElement.style.position = 'absolute';
renderer2.domElement.style.top = 0;
container.appendChild(renderer2.domElement);
var controls = new OrbitControls(camera, renderer2.domElement);
// 创建标签
function createPlane(pos, text) {
let element = document.createElement('div');
element.className = "labelBox";
element.style.width = '0px';
element.style.height = '0px';
element.innerHTML = `<div class='labelLine'></div><div class='labelText'><span>${text}</span></div>`;
let object = new CSS3DObject(element);
// pos.y = pos.y - 1; // 将多余的图形往地下偏移
object.position.copy(pos);
object.rotation.copy(new THREE.Euler(0, 0, 0));
scene.add(object);
}
createPlane(new THREE.Vector3(0, 0, 0), '测试标签文案');
render();
function render() {
controls.update();
requestAnimationFrame(render);
renderer.render(scene, camera);
renderer2.render(scene, camera);
}
}
}
</script>
<style lang="less">
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
overflow: hidden;
font-family: Lato, sans-serif;
width: 100%;
height: 100%;
background-color: #dedede;
color: #202020;
padding: 20px;
text-shadow: 0 1px 0 rgba(255, 255, 255, .5);
}
#container {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
border: 1px solid #ff0000;
}
.labelBox {
background-color: #0099ff;
position: relative;
.labelLine {
position: absolute;
left: 0;
top: -15px;
width: 1px;
height: 15px;
background-color: #0099ff;
}
.labelText {
position: absolute;
left: 0;
top: -15px;
background-color: #ff0000;
width: 20px;
height: 5px;
span {
display: inline-block;
padding: 5px 10px;
font-size: 12px;
transform: scale(.1, .1);
transform-origin: top left;
width: 200px; // 宽度为 .labelText 宽度/缩放等级
height: 50px; // 高度原理同上
}
}
}
</style>