Threejs工具提示

时间:2016-08-27 03:32:46

标签: three.js tooltip

这可能是重复的,但我还没有找到任何东西。 我正在尝试为鼠标悬停创建工具提示。 (透视镜头)

工具提示问题: https://jsfiddle.net/thehui87/d12fLr0b/14/

threejs r76

function onDocumentMouseMove( event ) 
{
    // update sprite position
    // sprite1.position.set( event.clientX, event.clientY, 1 );

    // update the mouse variable
    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );
    vector.unproject(camera);

    var dir = vector.sub( camera.position ).normalize();
    var distance = - camera.position.z / dir.z;
    var pos = camera.position.clone().add( dir.multiplyScalar( distance ) );
    sprite1.position.copy(pos);


}

但是一旦我在相机上运行,​​工具提示会移开。

工具提示的参考资料。

如果有人可以在stackoverflow上找到正确的答案或提供替代解决方案。

由于

2 个答案:

答案 0 :(得分:3)

良好的工作提示不仅正确放置了文本标签。它具有一些显示和隐藏情报

它应该:

  1. 不会立即显示,但是一旦鼠标停在某个对象上,
  2. 不会立即消失,而是应该在鼠标离开对象区域后逐渐消失
  3. 如果用户在对象区域周围移动鼠标而不离开鼠标,则它既不应跟随鼠标,也不应停留在原来的位置。

所有这些都包含在我的解决方案中:http://jsfiddle.net/mmalex/ycnh0wze/ threejs html css tooltip

<div id="tooltip"></div>必须首先添加到HTML。您可以在下面找到推荐的CSS。拥有position: fixed;至关重要,其他任何事情都取决于品味。

#tooltip {
  position: fixed;
  left: 0;
  top: 0;
  min-width: 100px;
  text-align: center;
  padding: 5px 12px;
  font-family: monospace;
  background: #a0c020;
  display: none;
  opacity: 0;
  border: 1px solid black;
  box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
  transition: opacity 0.25s linear;
  border-radius: 3px;
}
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 = 5;
camera.position.y = 5;
camera.position.z = 5;
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();
for (let k = 0; k < 12; k++) {
    var size = 0.5;
    var geometry = new THREE.BoxGeometry(size, 0.2, size);
    var randomColor = colors.pickRandom();
    var material = new THREE.MeshPhongMaterial({
        color: randomColor.hex,
        transparent: true,
        opacity: 0.75
    });
    var cube = new THREE.Mesh(geometry, material);
    cube.userData.tooltipText = randomColor.name;
    cube.applyMatrix(new THREE.Matrix4().makeTranslation(-3 + 6 * Math.random(), 0, -3 + 0.5 * k));
    scene.add(cube);
    tooltipEnabledObjects.push(cube);
}

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();

答案 1 :(得分:1)

替换:

var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );

由:

var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );