How to create Sketchfab like annotations and click zoom with Three.js?

HI How to create Sketchfab like annotations and click zoom with Three.js?

I have found a case: WebGL/three.js Annotations | manu.ninja

But is there an example of clicking to zoom like this?:Giant sculpture of a scarab beetle - Download Free 3D model by The British Museum (@britishmuseum) [98a6e8f] - Sketchfab

The question about annotations has been asked many times, please use the search function.

https://discourse.threejs.org/tag/annotations

As for moving the camera, I’d recommend using Yomutsu’s camera controls and for each label, pick a camera position that looks good. When you find a position you like, use:

const position = new Vector3();
const target = new Vector3();
controls.getPosition(position);
controls.getTarget(target);

You can save the position and target however you like, for example log the values to the console and hard code them to a label.

Then when the user clicks the label, you can move back to that camera position like so:

const enableTransition = true; // whether to animate or jump to the new position
controls.setLookAt(position.x, position.y, position.z, target.x, target.y, target.z, enableTransition);

Using the latest three.js version which has iterable vectors you can shorten this to:

controls.setLookAt(...position, ...target, true);
1 Like

The raycaster event is automatically triggered when the model is rotated, but only when I want to click on the model.

loade model

  // model
  let loader = new THREE.GLTFLoader(manager);
  loader.load("../models/r282-p91/r282-p91.gltf", function (gltf) {
    scene.add(gltf.scene);
    box = gltf.scene;

    //動畫調用 animation
    mixer = new THREE.AnimationMixer(gltf.scene);

    gltf.animations.forEach((clip) => {
      mixer.clipAction(clip).play();
    });
  });

Click Model

var raycaster = new THREE.Raycaster();
  var mouse = new THREE.Vector2();
  var intersects = [0];
  renderer.domElement.addEventListener("click", onClick, false);

  function onClick(event) {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    raycaster.setFromCamera(mouse, camera);
    intersects = raycaster.intersectObject(box, true);
    if (intersects.length > 0) {
      console.log("Intersection:", intersects[0]);

      gsap.to(camera.position, {
        duration: 3,
        x: 0,
        y: 15,
        z: 20,
        onUpdate: function () {
          controls.update();
        },
      });
    }
  }