js knowing people, Below you can see my very first code of JavaScript. I would like to build a website with four different rotating gltf models. Each of them should be a hyperlink. So far I managed somehow to load two of them and let them rotate in the live server. But I'm stuck with this error 'Uncaught (in promise) TypeError: duck is undefined'. How can I solve this problem? And how can I create the links? I'm very thankful for your help.
// 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);
The error occurs at duck.rotation.x += 0.01. Since loader.load function is asynchronous, the line duck = gltf.scene.children[0]; is not called before the first execution of animate(). Consequently, duck variable is undefined. You could avoid it with
if(duck) {
duck.rotation.x += 0.01
}
Regarding hyperlink:
There is no concept of links in the three.js scene.
Anchor tags are only available in the DOM and it's not a standard element available in WebGL.
You will need to write some code to handle mouse events, click and open the corresponding URL.
The process goes as below:
The three.js documentation is quite clear about the raycaster and intersections with mesh https://threejs.org/docs/#api/en/core/Raycaster