首页 > 解决方案 > 在应成为超链接的 Three.js 中加载多个 gltf 文件

问题描述

js 认识人,下面你可以看到我的第一个 JavaScript 代码。我想用四种不同的旋转 gltf 模型建立一个网站。它们中的每一个都应该是一个超链接。到目前为止,我设法以某种方式加载了其中两个并让它们在实时服务器中旋转。但是我遇到了这个错误“未捕获(承诺)类型错误:鸭子未定义”。我怎么解决这个问题?以及如何创建链接?我非常感谢你的帮助。

// variables for setup
let container;
let camera;
let renderer;
let scene;
let box;
let duck;
let controls;

function init(){
    container = document.querySelector('.scene');

    //create scene
    scene = new THREE.Scene();

    const fov = 10;
    const aspect = container.clientWidth / container.clientHeight;
    const near = 0.1;
    const far = 900;

    // camera setup
    camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    camera.position.set(0, 30, 1);


    const ambient = new THREE.AmbientLight(0x404040, 3);
    scene.add(ambient);


    const light = new THREE.DirectionalLight(0xffffff, 0.5);
    light.position.set(10,10,30);
    scene.add(light);
    

    //renderer
    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setSize(container.clientWidth, container.clientHeight);
    renderer.setPixelRatio(window.devicePixelRatio);

    container.appendChild(renderer.domElement);

   
    controls = new THREE.OrbitControls (camera, renderer.domElement);
    
    //load model
    let loader = new THREE.GLTFLoader();
    
    loader.load('./3d/duck.gltf', function(gltf){
        scene.add(gltf.scene);
        duck = gltf.scene.children[0];
        duck.position.set(0,0,0);
        animate();
    })

    loader.load('./3d/cube.gltf', function(gltf){
        scene.add(gltf.scene);
        box = gltf.scene.children[0];
        box.position.set(-2,0,0);
        animate();
    })

    
}

function animate(){
    controls.update();
    duck.rotation.x += 0.01
    box.rotation.y += 0.01
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}


init();


function onWindowResize () {
    camera.aspect = container.clientWidth / container.clientHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(container.clientWidth, container.clientHeight);
}

    window.addEventListener('resize', onWindowResize);

标签: javascriptthree.js

解决方案


错误发生在duck.rotation.x += 0.01。由于loader.load函数是异步的,因此duck = gltf.scene.children[0];在第一次执行之前不会调用该行animate()。因此,duck变量是未定义的。你可以避免它

if(duck) {
  duck.rotation.x += 0.01
}

关于超链接:
three.js 场景中没有链接的概念。
锚标记仅在 DOM 中可用,它不是 WebGL 中可用的标准元素。
您将需要编写一些代码来处理鼠标事件,单击并打开相应的 URL。
过程如下:

  • 如果悬停的元素是可点击的,则监听鼠标移动事件并更改光标
  • 听鼠标点击并导航到与点击元素对应的链接
  • 这两个都需要从鼠标指针投射光线并检查与网格的交叉点

three.js 文档非常清楚 raycaster 和与网格的交叉点 https://threejs.org/docs/#api/en/core/Raycaster

演示:
https ://codepen.io/cdeep/pen/JjyjEdV


推荐阅读