console
<div id="container"></div>
<script type="module">
import { TrackballControls } from 'https://threejs.org/examples/jsm/controls/TrackballControls.js';
import { CSS2DRenderer, CSS2DObject } from 'https://threejs.org/examples/jsm/renderers/CSS2DRenderer.js';
let camera, scene, renderer, labelRenderer;
let controls;
let root;
const offset = new THREE.Vector3();
const menu = document.getElementById( 'menu' );
init();
animate();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 1500;
camera.position.x = 1700;
camera.position.y = 1200;
scene.add( camera );
const light1 = new THREE.DirectionalLight( 0xffffff, 0.8 );
light1.position.set( 1, 1, 1 );
scene.add( light1 );
const light2 = new THREE.DirectionalLight( 0xffffff, 0.5 );
light2.position.set( - 1, - 1, 1 );
scene.add( light2 );
root = new THREE.Group();
scene.add( root );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById( 'container' ).appendChild( renderer.domElement );
labelRenderer = new CSS2DRenderer();
labelRenderer.setSize( window.innerWidth, window.innerHeight );
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
labelRenderer.domElement.style.pointerEvents = 'none';
document.getElementById( 'container' ).appendChild( labelRenderer.domElement );
controls = new TrackballControls( camera, renderer.domElement );
controls.minDistance = 500;
controls.maxDistance = 1000;
var geometry = new THREE.BufferGeometry();
var band = [
379.6613, 0.0045 ,-159.5722,
-67.0589,373.6930,-159.5719,
-1.6247, -1.9418 ,527.6072,
], vertices = [],
xline = [], yline = [], zline = [],
xPointV3='', yPointV3='', zPointV3='', originPointV3='',
ori = [0,0,0];
originPointV3 = new THREE.Vector3(0,0,0);
for(let i = 0; i < 3; i++) {
let se = [band[i*3],band[i*3+1],band[i*3+2]];
if(i == 0){
xline = [...ori, ...se];
vertices = vertices.concat(xline);
xPointV3 = new THREE.Vector3(se[0],se[1],se[2]);
}
if(i == 1){
yline = [...ori, ...se];
yPointV3 = new THREE.Vector3(se[0],se[1],se[2]);
}
if(i == 2){
zline = [...ori, ...se];
vertices = vertices.concat(zline);
zPointV3 = new THREE.Vector3(se[0],se[1],se[2]);
}
}
var lengthX = xPointV3.length(), lengthY = yPointV3.length(), lengthZ =zPointV3.length();
var material = new THREE.PointsMaterial( {
color: 0xff0ff0,
size:20 } );
var group1 = new THREE.Group();
var group2 = new THREE.Group();
var x1 = new THREE.BufferGeometry();
x1.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array(xline), 3 ));
var x1L = new THREE.Line( x1, material );
group2.add(x1L);
var x2L = x1L.clone();
zPointV3.normalize();
x2L.translateOnAxis(zPointV3, lengthZ);
var x3L = x1L.clone();
yPointV3.normalize();
x3L.translateOnAxis(yPointV3, lengthY);
group2.add(x3L);
var y1 = new THREE.BufferGeometry();
y1.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array(yline), 3 ));
var y1L = new THREE.Line( y1, material );
group1.add(y1L);
var y2L = y1L.clone();
xPointV3.normalize();
y2L.translateOnAxis(xPointV3, lengthX);
group2.add(y2L);
var y3L = y1L.clone();
y3L.translateOnAxis(zPointV3, lengthZ);
group1.add(y3L)
var z1 = new THREE.BufferGeometry();
z1.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array(zline), 3 ));
var z1L = new THREE.Line( z1, material );
group1.add(z1L)
var z3L = z1L.clone();
z3L.translateOnAxis(yPointV3, lengthY);
group1.add(z3L)
scene.add(group1);
scene.add(group2);
var group3 = group1.clone();
group3.translateOnAxis(xPointV3, lengthX);
scene.add(group3);
var group4 = group2.clone();
group4.translateOnAxis(zPointV3, lengthZ);
scene.add(group4);
var dirlength = 150, labelren=[];
let dirs = [{
name:'a',
color:'red',
angTxt: '��',
line: yPointV3,
toCurve:xPointV3,
length: lengthY,
}, {
name:'b',
color:'green',
angTxt: '��',
line: xPointV3,
toCurve:zPointV3,
length: lengthX
},{
name:'c',
color:'blue',
angTxt: '��',
line:zPointV3,
toCurve:yPointV3,
length: lengthZ
},];
dirs.forEach((item, i)=> {
let arrow = new THREE.ArrowHelper( item.line, originPointV3, item.length+dirlength, item.color);
scene.add( arrow);
let text = document.createElement( 'div' );
text.className = 'label';
text.style.color = item.color;
text.textContent = item.name;
let label = new CSS2DObject( text );
label.translateOnAxis( item.line , Math.ceil(item.length*2/3));
scene.add( label );
let dirco = arrow.line.clone();
dirco.translateOnAxis( item.line , Math.ceil(item.length/3));
labelren.push({
line: dirco,
length:item.length,
angTxt: item.angTxt,
});
});
labelren.forEach((htem,h) => {
let end = labelren[h+1]?labelren[h+1].line : labelren[0].line;
let li = addLines(htem.line.position,end.position, originPointV3, htem.angTxt);
scene.add( li.lineMesh);
})
window.addEventListener( 'resize', onWindowResize );
}
function addLines(v0, v3, point, txt) {
let angle = v0.angleTo(v3)*(180/Math.PI);
let aLen = angle * 1, hLen = 1;
let p0 = new THREE.Vector3(0, 0, 0);
let rayLine = new THREE.Ray(p0, getVCenter(v0.clone(), p0));
let rayLine2 = new THREE.Ray(p0, getVCenter(v3.clone(), p0));
let vtop = rayLine.at(rayLine.at(1).distanceTo(p0));
let vtop2 = rayLine2.at(rayLine.at(1).distanceTo(p0));
let v1 = getLenVcetor(v0.clone(), vtop2, aLen);
let v2 = getLenVcetor(v3.clone(), vtop, aLen);
let curve = new THREE.CubicBezierCurve3(v0, v1, v2, v3);
let geo = new THREE.BufferGeometry().setFromPoints( curve.getPoints(50) );
let mat = new THREE.LineDashedMaterial({
color: 0x000000,
dashSize: 10,
gapSize: 6,
});
let line = new THREE.Line(geo, mat);
line.computeLineDistances();
let text2 = document.createElement( 'div' );
text2.className = 'label';
text2.textContent = txt;
let label2 = new CSS2DObject( text2 );
debugger;
label2.translateOnAxis( v1 , 1);
scene.add( label2 );
return {
curve: curve,
lineMesh: line
};
}
function getVCenter(v1, v2) {
let v = v1.add(v2);
return v.divideScalar(2);
}
function getLenVcetor(v1, v2, len) {
let v1v2Len = v1.distanceTo(v2);
return v1.lerp(v2, len / v1v2Len);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
labelRenderer.setSize( window.innerWidth, window.innerHeight );
render();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
render();
}
function render() {
renderer.render( scene, camera );
labelRenderer.render( scene, camera );
}
</script>