解决办法是:
-
在每个顶点放置小方框,
-
在每个框中添加工具提示,
-
工具提示文本设置为顶点索引。
如何在three.js中添加工具提示请参见我的答案:
Threejs Tooltip
为方便您使用jsfiddle,请参见:
http://jsfiddle.net/mmalex/fux6srgv/
Javascript代码:
var scene = new THREE.Scene();
var raycaster = new THREE.Raycaster();
//create some camera
camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 3;
camera.position.y = 3;
camera.position.z = 3;
camera.lookAt(0, 0, 0);
var controls = new THREE.OrbitControls(camera);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color(0x595959));
document.body.appendChild(renderer.domElement);
// white spotlight shining from the side, casting a shadow
var spotLight = new THREE.SpotLight(0xffffff, 2.5, 25, Math.PI / 6);
spotLight.position.set(4, 10, 7);
scene.add(spotLight);
// collect objects for raycasting,
// for better performance don't raytrace all scene
var tooltipEnabledObjects = [];
var colors = new RayysWebColors();
var dodecahedronGeometry = new THREE.DodecahedronBufferGeometry(1, 0);
var dodecahedronMaterial = new THREE.MeshPhongMaterial({
color: colors.pickRandom().hex,
transparent: true,
opacity: 0.75
});
var dodecahedron = new THREE.Mesh(dodecahedronGeometry, dodecahedronMaterial);
scene.add(dodecahedron);
var size = 0.1;
var vertGeometry = new THREE.BoxGeometry(size, size, size);
var vertMaterial = new THREE.MeshBasicMaterial({
color: 0x0000ff,
transparent: false
});
var verts = dodecahedronGeometry.attributes.position.array;
for (let k=0; k<verts.length; k+=3) {
var vertMarker = new THREE.Mesh(vertGeometry, vertMaterial);
// this is how tooltip text is defined for each box
let tooltipText = `idx: ${k}, pos: [${verts[k].toFixed(3)},${verts[k+1].toFixed(3)},${verts[k+2].toFixed(3)}]`;
vertMarker.userData.tooltipText = tooltipText;
vertMarker.applyMatrix(new THREE.Matrix4().makeTranslation(verts[k],verts[k+1],verts[k+2]));
scene.add(vertMarker);
tooltipEnabledObjects.push(vertMarker);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
// this will be 2D coordinates of the current mouse position, [0,0] is middle of the screen.
var mouse = new THREE.Vector2();
var latestMouseProjection; // this is the latest projection of the mouse on object (i.e. intersection with ray)
var hoveredObj; // this objects is hovered at the moment
// tooltip will not appear immediately. If object was hovered shortly,
// - the timer will be canceled and tooltip will not appear at all.
var tooltipDisplayTimeout;
// This will move tooltip to the current mouse position and show it by timer.
function showTooltip() {
var divElement = $("#tooltip");
if (divElement && latestMouseProjection) {
divElement.css({
display: "block",
opacity: 0.0
});
var canvasHalfWidth = renderer.domElement.offsetWidth / 2;
var canvasHalfHeight = renderer.domElement.offsetHeight / 2;
var tooltipPosition = latestMouseProjection.clone().project(camera);
tooltipPosition.x = (tooltipPosition.x * canvasHalfWidth) + canvasHalfWidth + renderer.domElement.offsetLeft;
tooltipPosition.y = -(tooltipPosition.y * canvasHalfHeight) + canvasHalfHeight + renderer.domElement.offsetTop;
var tootipWidth = divElement[0].offsetWidth;
var tootipHeight = divElement[0].offsetHeight;
divElement.css({
left: `${tooltipPosition.x - tootipWidth/2}px`,
top: `${tooltipPosition.y - tootipHeight - 5}px`
});
// var position = new THREE.Vector3();
// var quaternion = new THREE.Quaternion();
// var scale = new THREE.Vector3();
// hoveredObj.matrix.decompose(position, quaternion, scale);
divElement.text(hoveredObj.userData.tooltipText);
setTimeout(function() {
divElement.css({
opacity: 1.0
});
}, 25);
}
}
// This will immediately hide tooltip.
function hideTooltip() {
var divElement = $("#tooltip");
if (divElement) {
divElement.css({
display: "none"
});
}
}
// Following two functions will convert mouse coordinates
// from screen to three.js system (where [0,0] is in the middle of the screen)
function updateMouseCoords(event, coordsObj) {
coordsObj.x = ((event.clientX - renderer.domElement.offsetLeft + 0.5) / window.innerWidth) * 2 - 1;
coordsObj.y = -((event.clientY - renderer.domElement.offsetTop + 0.5) / window.innerHeight) * 2 + 1;
}
function handleManipulationUpdate() {
raycaster.setFromCamera(mouse, camera);
{
var intersects = raycaster.intersectObjects(tooltipEnabledObjects);
if (intersects.length > 0) {
latestMouseProjection = intersects[0].point;
hoveredObj = intersects[0].object;
}
}
if (tooltipDisplayTimeout || !latestMouseProjection) {
clearTimeout(tooltipDisplayTimeout);
tooltipDisplayTimeout = undefined;
hideTooltip();
}
if (!tooltipDisplayTimeout && latestMouseProjection) {
tooltipDisplayTimeout = setTimeout(function() {
tooltipDisplayTimeout = undefined;
showTooltip();
}, 330);
}
}
function onMouseMove(event) {
updateMouseCoords(event, mouse);
latestMouseProjection = undefined;
hoveredObj = undefined;
handleManipulationUpdate();
}
window.addEventListener('mousemove', onMouseMove, false);
animate();
HTML代码:
<p style="margin-left: 12px;">Mouse hover verts to see vert index and coordinates</p>
<div id="tooltip"></div>
工具提示元素的CSS:
#tooltip {
position: fixed;
left: 0;
top: 0;
min-width: 10px;
text-align: center;
padding: 2px 2px;
font-family: monospace;
background: #a0c020;
display: none;
opacity: 0;
border: 0px solid transparent;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
transition: opacity 0.25s linear;
border-radius: 0px;
}
给定的方法允许每个顶点附加和显示任何文本信息。