【问题标题】:Make children of imported Three.js group follow pointer when their canvas gets hovered当画布悬停时,使导入的 Three.js 组的子级跟随指针
【发布时间】:2021-10-11 20:34:23
【问题描述】:

在 Three.js 中,我有一组在 FBX 加载器的帮助下从外部加载的网格。该组内部有六个网格。我的任务是让这些网格在悬停时跟随指针。更准确地说,我想要一种磁效应(就像 this pen 中的导航栏项目,但在 Three.js 中使用网格)。

我认为,首先,我必须检测当前指针的位置,即获取光标在世界坐标系中的位置,然后将网格平移到它。但是当我尝试获取光标的位置时,它似乎是错误的。

话虽如此,我有两个问题:

  1. 如何获得正确的光标相对于世界坐标的位置?
  2. 如何更改组中每个网格的位置,以便根据光标平移?

这是我到目前为止所做的:

大家好。

在 Three.js 中,我有一组在 FBX 加载器的帮助下从外部加载的网格。该组内部有六个网格。我的任务是让这些网格在画布悬停时跟随指针。更准确地说,我想要一种磁效应(就像this pen 中的导航栏项目,但使用 Three.js 的网格)。

我认为,首先,我必须检测画布上当前指针的位置,即获取光标在世界坐标系中的位置,然后将网格平移到它。但是当我尝试获取光标的位置时,它似乎是错误的。

话虽如此,我有两个问题:

  1. 如何获得正确的光标相对于世界坐标的位置?
  2. 如何更改组中每个网格的位置,以便根据光标平移?

这是我到目前为止所做的。尚未编写转换网格的函数。不过,Mousemove 回调会返回相当大的数字:

// Load object and play a third-party animation
loader.load("Object_001.fbx", (object) => {
mixer = new THREE.AnimationMixer(object);
const action = mixer.clipAction(object.animations[0]);
action.play();

object.traverse((child) => {
  if (child.isMesh) {
    child.material.map = texture;
    child.material.needsUpdate = true;
  }
});
scene.add(object);
});


// log coordinates of the pointer
const mouse = new THREE.Vector3();
const position = new THREE.Vector3();

function onMouseMove(event) {
  mouse.set(
    (event.clientX / window.innerWidth) * 2 - 1,
    -(event.clientY / window.innerHeight) * 2 + 1,
    0.5
  );
  mouse.unproject(camera);
  mouse.sub(camera.position).normalize();
  const distance = -camera.position.z / mouse.z;
  position.copy(camera.position).add(mouse.multiplyScalar(distance));
  console.log(position);
}

wrapperElement.addEventListener("mousemove", onMouseMove);

提前致谢。

【问题讨论】:

    标签: three.js


    【解决方案1】:

    在这里做了一个codepen:
    https://codepen.io/cdeep/pen/YzxPPZQ

    光标仅存在于画布 dom 元素中,该元素是相机视图平截头体的渲染。

    让对象跟随鼠标最简单的方法是获取鼠标与 3d 场景中另一个对象的交点,并将对象位置设置为交点。上面的 codepen 展示了这一点。

    raycaster.setFromCamera( mouse, camera );
    const intersects = raycaster.intersectObjects([ground]);
    if(intersects.length) {
        const { point } = intersects[0];
        cube.position.copy(point.setY(0.5));
    }
    

    您也可以将其放置在距鼠标固定距离的位置,但我认为它看起来很奇怪:

    const distance = 10;
    raycaster.setFromCamera( mouse, camera );
    const { origin, direction } = raycaster.ray;
    cube.position.copy(origin.clone().add(direction.multiplyScalar(distance)));
    

    raycaster 的文档:
    https://threejs.org/docs/index.html?q=ray#api/en/core/Raycaster

    Raycasting 用于鼠标拾取(计算出 鼠标悬停的 3d 空间)等等。

    【讨论】:

      猜你喜欢
      • 2019-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-10
      • 2017-02-09
      • 2014-02-13
      • 2020-06-29
      • 2012-03-15
      相关资源
      最近更新 更多