三个js中文本位于一行的中心点

问题描述 投票:0回答:1

我有什么。

我想要实现的目标:

所以这是我的问题:

  1. 如何将三个js中的位置x和y转换为浏览器坐标,以便我可以将文本正确定位在行的中心?我只添加了垂直线的示例,我将有不同的线,例如水平线和对角线。

  2. 如何剪掉中心的箭头线以便为文本留出空间?

这是我的代码

var gridCanvas = document.getElementById('gridcanvas');
			var ctx = gridCanvas.getContext('2d');
			ctx.beginPath();
			for(var x=0.5; x<gridCanvas.width; x+=20) {
			    ctx.moveTo(x, 0);
			    ctx.lineTo(x, gridCanvas.height);
			}
			for(var y=0.5; y<gridCanvas.height; y+=20) {
			    ctx.moveTo(0, y);
			    ctx.lineTo(gridCanvas.width, y);
			}

			ctx.strokeStyle = 'lightgrey';
			ctx.stroke();

			var container = document.getElementById( '3dcontainer' );
			var aspect = 400 / 400;
			var viewHeight = 400;
			var viewWidth = viewHeight * aspect;
			var scene = new THREE.Scene();
			var camera = new THREE.OrthographicCamera(
			    viewWidth / - 2, viewWidth / 2, viewHeight / 2, viewHeight / - 2, 1, 1000);

			camera.translateZ(15);
			scene.add(camera);

			var points = {
				start : {x: 1.0229999999999109, y: 150.44000000000005},
				end : {x: 1.0229999999999118, y: -151.50399999999996}
			};

			var from = new THREE.Vector3(points.start.x, points.start.y, 0);
			var to = new THREE.Vector3(points.end.x, points.end.y, 0);

			var direction = to.clone().sub(from);
			var length = direction.length();
			
			var hex = 0x0;
			var arrorGroupHelper = new THREE.Group();
			arrorGroupHelper.add(new THREE.ArrowHelper(direction.normalize(), from, length, hex, 5, 5));
			arrorGroupHelper.add(new THREE.ArrowHelper(direction.negate(), to, length, hex, 5, 5));
			scene.add(arrorGroupHelper);

			var threejsCanvas = document.getElementById('threejs-canvas');
			var renderer = new THREE.WebGLRenderer({
				canvas : threejsCanvas,
				alpha : true
			});

			var centerPointLine = findLineCenterPoint(points.start, points.end);
			var text = document.createElement('div');
			text.style.position = 'absolute';
			text.style.zIndex = 5;
			text.innerHTML = length;
			// need to convert this into browser position
			text.style.top = centerPointLine.y + 'px';
			text.style.left = centerPointLine.x + 'px';
			document.getElementById('container').append(text);

			renderer.render( scene, camera );

			function findLineCenterPoint(a, b) {
			    return { x: (b.x - a.x) / 2 + a.x, y: (b.y - a.y) / 2 + a.y }; 
			}
body { margin: 0; }
			#container {
				position: relative;
			}
			#threejs-canvas {
				position:absolute;
				z-index: 2;
			}
			#gridcanvas {
				position: absolute;
				z-index: 1;
			}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script>
<div id="container">
			<canvas id="threejs-canvas" width="400" height="400"></canvas>
			<canvas id="gridcanvas" width="400" height="400"></canvas>
		</div>

javascript html three.js
1个回答
4
投票

您可以使用

CSS2DRenderer
three.js
使用的相同代码来实现此目的。这意味着您将矢量投影到剪辑空间中,然后将其转换,以便可以与 CSS
translate
属性一起使用。如果您随后将白色背景应用于文本标签,您应该会达到预期的结果。

var gridCanvas = document.getElementById('gridcanvas');
var ctx = gridCanvas.getContext('2d');
ctx.beginPath();
for(var x=0.5; x<gridCanvas.width; x+=20) {
    ctx.moveTo(x, 0);
    ctx.lineTo(x, gridCanvas.height);
}
for(var y=0.5; y<gridCanvas.height; y+=20) {
    ctx.moveTo(0, y);
    ctx.lineTo(gridCanvas.width, y);
}

ctx.strokeStyle = 'lightgrey';
ctx.stroke();

var container = document.getElementById( '3dcontainer' );
var aspect = 400 / 400;
var viewHeight = 400;
var viewWidth = viewHeight * aspect;
var scene = new THREE.Scene();
var camera = new THREE.OrthographicCamera(
    viewWidth / - 2, viewWidth / 2, viewHeight / 2, viewHeight / - 2, 1, 1000);

camera.translateZ(15);
camera.updateProjectionMatrix();
scene.add(camera);

var points = {
    start : {x: 1.0229999999999109, y: 150.44000000000005},
    end : {x: 1.0229999999999118, y: -151.50399999999996}
};

var from = new THREE.Vector3(points.start.x, points.start.y, 0);
var to = new THREE.Vector3(points.end.x, points.end.y, 0);

var direction = to.clone().sub(from);
var length = direction.length();

var hex = 0x0;
var arrorGroupHelper = new THREE.Group();
arrorGroupHelper.add(new THREE.ArrowHelper(direction.normalize(), from, length, hex, 5, 5));
arrorGroupHelper.add(new THREE.ArrowHelper(direction.negate(), to, length, hex, 5, 5));
scene.add(arrorGroupHelper);

var threejsCanvas = document.getElementById('threejs-canvas');
var renderer = new THREE.WebGLRenderer({
    canvas : threejsCanvas,
    alpha : true
});

var centerPointLine = findLineCenterPoint(points.start, points.end);
var text = document.createElement('div');
text.style.position = 'absolute';
text.style.zIndex = 5;
text.style.backgroundColor = '#ffffff';
text.innerHTML = length;

var vector = new THREE.Vector3( centerPointLine.x, centerPointLine.y, 0 );
vector.project( camera );
// need to convert this into browser position

var widthHalf = viewWidth / 2;
var heightHalf = viewHeight / 2;

var style = 'translate(-50%,-50%) translate(' + ( vector.x * widthHalf + widthHalf ) + 'px,' + ( - vector.y * heightHalf + heightHalf ) + 'px)';
text.style.transform = style;

document.getElementById('container').append(text);

renderer.render( scene, camera );

function findLineCenterPoint(a, b) {
    return { x: (b.x - a.x) / 2 + a.x, y: (b.y - a.y) / 2 + a.y }; 
}
body { margin: 0; }
#container {
    position: relative;
}
#threejs-canvas {
    position:absolute;
    z-index: 2;
}
#gridcanvas {
    position: absolute;
    z-index: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script>
<div id="container">
    <canvas id="threejs-canvas" width="400" height="400"></canvas>
    <canvas id="gridcanvas" width="400" height="400"></canvas>
</div>

顺便说一句:考虑直接使用CSS2DRenderer,如果您想渲染连接到 3D 对象的基于 HTML 的标签,这是理想的选择。

three.js R112

© www.soinside.com 2019 - 2024. All rights reserved.