Threejs工具提示 [英] Threejs Tooltip

查看:35
本文介绍了Threejs工具提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

工具提示问题:

<div id="tooltip"></div> 必须最初添加到 HTML 中.您在下面找到的推荐 CSS.position: fixed; 至关重要,其他任何事情都是品味问题.

#tooltip {位置:固定;左:0;顶部:0;最小宽度:100px;文本对齐:居中;填充:5px 12px;字体系列:等宽;背景:#a0c020;显示:无;不透明度:0;边框:1px纯黑色;box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);过渡:不透明度 0.25s 线性;边框半径:3px;}

var scene = new THREE.Scene();var raycaster = new THREE.Raycaster();//创建一些相机camera = new THREE.PerspectiveCamera(55, window.innerWidth/window.innerHeight, 0.1, 1000);相机.位置.x = 5;相机.位置.y = 5;相机.位置.z = 5;相机.lookAt(0, 0, 0);var controls = new THREE.OrbitControls(camera);var renderer = new THREE.WebGLRenderer({抗锯齿:真});renderer.setSize(window.innerWidth, window.innerHeight);renderer.setClearColor(new THREE.Color(0x595959));document.body.appendChild(renderer.domElement);//白色聚光灯从侧面照射,投下阴影var spotLight = new THREE.SpotLight(0xffffff, 2.5, 25, Math.PI/6);spotLight.position.set(4, 10, 7);场景添加(聚光灯);//收集用于光线投射的对象,//为了更好的性能,不要对所有场景进行光线跟踪var tooltipEnabledObjects = [];var 颜色 = new RayysWebColors();for (让 k = 0; k <12; k++) {变量大小 = 0.5;var geometry = new THREE.BoxGeometry(size, 0.2, size);var randomColor = colors.pickRandom();var material = new THREE.MeshPhongMaterial({颜色:randomColor.hex,透明:真实,不透明度: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));场景.添加(立方体);tooltipEnabledObjects.push(cube);}函数动画(){请求动画帧(动画);控制更新();renderer.render(场景,相机);};//这将是当前鼠标位置的二维坐标,[0,0] 是屏幕中间.var mouse = new THREE.Vector2();var latestMouseProjection;//这是鼠标在对象上的最新投影(即与射线的交点)var hoveredObj;//该对象此时悬停//工具提示不会立即出现.如果物体短暂悬停,//- 计时器将被取消,工具提示将根本不会出现.var tooltipDisplayTimeout;//这会将工具提示移动到当前鼠标位置并通过计时器显示.函数 showTooltip() {var divElement = $("#tooltip");如果(divElement && latestMouseProjection){divElement.css({显示:块",不透明度: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 toipWidth = divElement[0].offsetWidth;var toipHeight = divElement[0].offsetHeight;divElement.css({左:`${tooltipPosition.x-totipWidth/2}px`,顶部:`${tooltipPosition.y -totipHeight - 5}px`});//var position = new THREE.Vector3();//var quaternion = new THREE.Quaternion();//var scale = new THREE.Vector3();//hoveredObj.matrix.decompose(position, 四元数, scale);divElement.text(hoveredObj.userData.tooltipText);设置超时(函数(){divElement.css({不透明度:1.0});}, 25);}}//这将立即隐藏工具提示.函数隐藏工具提示(){var divElement = $("#tooltip");如果(divElement){divElement.css({显示:无"});}}//以下两个函数将转换鼠标坐标//从屏幕到three.js系统(其中[0,0]在屏幕中间)函数 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;}函数 handleManipulationUpdate() {raycaster.setFromCamera(鼠标,相机);{var intersects = raycaster.intersectObjects(tooltipEnabledObjects);如果(相交.长度> 0){latestMouseProjection = intersects[0].point;hoveredObj = intersects[0].object;}}if (tooltipDisplayTimeout || !latestMouseProjection) {清除超时(工具提示显示超时);tooltipDisplayTimeout = 未定义;隐藏工具提示();}if (!tooltipDisplayTimeout && latestMouseProjection) {tooltipDisplayTimeout = setTimeout(function() {tooltipDisplayTimeout = 未定义;显示工具提示();}, 330);}}函数 onMouseMove(event) {更新鼠标坐标(事件,鼠标);latestMouseProjection = 未定义;悬停对象 = 未定义;handleManipulationUpdate();}window.addEventListener('mousemove', onMouseMove, false);动画();

this could be a duplicate, but I have not found anything as yet. I am trying to create tooltip for on mouse hover. (perspective camera)

Tooltip issue: 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);


}

But once i orbit the camera the tooltip moves away.

References for tooltip.

If anyone could kindly point me to the right answer on stackoverflow or provide an alternate solution.

Thanks

解决方案

Well working tooltip is not only correctly placed text label. It has some of show and hide intelligence.

It should:

  1. not appear immediately, but once mouse becomes stationary over some object,
  2. not disappear immediately, rather it should fade away after mouse left the object area,
  3. it should neither follow the mouse, nor stay where it was, if user moves the mouse around the object area not leaving it.

All of that is included in my solution: http://jsfiddle.net/mmalex/ycnh0wze/

<div id="tooltip"></div> must be initially added to HTML. The recommended CSS you find below. Crucial to have it position: fixed;, anything else is a matter of taste.

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

这篇关于Threejs工具提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆