【问题标题】:Need tooltip on mouseover in three.js在three.js中需要鼠标悬停工具提示
【发布时间】:2021-05-20 00:19:06
【问题描述】:

我正在加载类似 this [demo] 的对象,我想在鼠标悬停在该特定部分上时显示工具提示/信息框。 (就像单击按钮顶部一样,我想在框顶部显示工具提示)。我尝试了这些示例,但无法使用我的 obj

Example 1Example 2

我试过了

 cube.name = "top cube";
  cube.getObjectbyname = "top cube obj";
  scene.add(cube); // add cube to the scene

我不熟悉 three.js 和 Angular 材料。所以我不知道如何添加工具提示。 any1可以帮助我如何解决它。我不知道如何链接我的按钮和对象上/左/右...

【问题讨论】:

  • 我可能误解了你的问题,但我认为这已经在这里得到了回答:stackoverflow.com/questions/47297794/…
  • @TomBonynge:这是不同的,我需要框上的工具提示,而不是弹出窗口.. 但谢谢我从中得到了想法:-)

标签: javascript angularjs three.js


【解决方案1】:

This example 通过CSS2DRenderer 模块提供工具提示,但它们始终在线并与对象的位置同步。

如果您希望它们仅在悬停时出现,则必须通过 Raycaster 选择性地切换它们(文档中包含示例代码)。

以下是组合技术 (Codesandbox) 的示例,其中包含一个共享标签,可移动和更新到场景中的悬停元素:

body {
  margin: 0;
}

canvas {
  cursor: grab;
  display: block;
}

canvas:active {
  cursor: grabbing;
}

.hovered {
  cursor: help;
}

.label {
  color: #fff;
  font-family: sans-serif;
  padding: 2px;
  background: rgba(0, 0, 0, 0.6);
}
<script type="module">
  import {
    WebGLRenderer,
    PerspectiveCamera,
    Scene,
    BoxGeometry,
    MeshNormalMaterial,
    Mesh,
    Vector3,
    Box3,
    Raycaster,
    Vector2,
  } from 'https://unpkg.com/three@0.125.2/build/three.module.js';
  import { OrbitControls } from 'https://unpkg.com/three@0.125.2/examples/jsm/controls/OrbitControls.js';
  import {
    CSS2DRenderer,
    CSS2DObject,
  } from 'https://unpkg.com/three@0.125.2/examples/jsm/renderers/CSS2DRenderer.js';

  // Boilerplate
  const { innerWidth, innerHeight } = window;

  const renderer = new WebGLRenderer({ alpha: true, antialias: true });
  renderer.setSize(innerWidth, innerHeight);
  renderer.setPixelRatio(2);
  document.body.appendChild(renderer.domElement);

  const camera = new PerspectiveCamera(70, innerWidth / innerHeight, 0.1, 10);
  camera.position.z = 1;

  const controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;

  const scene = new Scene();

  const geometry = new BoxGeometry(0.2, 0.2, 0.2);
  const material = new MeshNormalMaterial();
  const mesh = new Mesh(geometry, material);
  mesh.name = 'mesh';
  scene.add(mesh);

  // Setup labels
  const labelRenderer = new CSS2DRenderer();
  labelRenderer.setSize(innerWidth, innerHeight);
  labelRenderer.domElement.style.position = 'absolute';
  labelRenderer.domElement.style.top = '0px';
  labelRenderer.domElement.style.pointerEvents = 'none';
  document.body.appendChild(labelRenderer.domElement);

  const labelDiv = document.createElement('div');
  labelDiv.className = 'label';
  labelDiv.style.marginTop = '-1em';
  const label = new CSS2DObject(labelDiv);
  label.visible = false;
  scene.add(label);

  // Track mouse movement to pick objects
  const raycaster = new Raycaster();
  const mouse = new Vector2();

  window.addEventListener('mousemove', ({ clientX, clientY }) => {
    const { innerWidth, innerHeight } = window;

    mouse.x = (clientX / innerWidth) * 2 - 1;
    mouse.y = -(clientY / innerHeight) * 2 + 1;
  });

  // Handle window resize
  window.addEventListener('resize', () => {
    const { innerWidth, innerHeight } = window;

    renderer.setSize(innerWidth, innerHeight);
    camera.aspect = innerWidth / innerHeight;
    camera.updateProjectionMatrix();
  });

  renderer.setAnimationLoop(() => {
    controls.update();

    // Pick objects from view using normalized mouse coordinates
    raycaster.setFromCamera(mouse, camera);

    const [hovered] = raycaster.intersectObjects(scene.children);

    if (hovered) {
      // Setup label
      renderer.domElement.className = 'hovered';
      label.visible = true;
      labelDiv.textContent = hovered.object.name;

      // Get offset from object's dimensions
      const offset = new Vector3();
      new Box3().setFromObject(hovered.object).getSize(offset);

      // Move label over hovered element
      label.position.set(
        hovered.object.position.x,
        offset.y / 2,
        hovered.object.position.x
      );
    } else {
      // Reset label
      renderer.domElement.className = '';
      label.visible = false;
      labelDiv.textContent = '';
    }

    // Render scene
    renderer.render(scene, camera);

    // Render labels
    labelRenderer.render(scene, camera);
  });
</script>

【讨论】:

  • 谢谢@Cody Bennett:我一定会试试的。感谢您的宝贵时间
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 2018-06-02
相关资源
最近更新 更多