Hi there! I’m new to Three.JS and just made my first project!!
So far it’s working beautifully, except for the Raycaster. When I use an easy shape/geometry, like a cube, it does work, but with my model, I just can’t get it to do what I want and it’s driving me nuts. This is my code, the raycaster is at the very end. Does anyone have an idea how to fix it? Thank u sm!!
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
let scene, camera, webGLRenderer, css3dRenderer, raycaster, mouse;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
webGLRenderer = new THREE.WebGLRenderer({ alpha: true });
webGLRenderer.setClearColor(0x212121, 1);
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(webGLRenderer.domElement);
css3dRenderer = new CSS3DRenderer();
css3dRenderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(css3dRenderer.domElement);
const ambientLight = new THREE.AmbientLight(0xffffff, 3);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xa78bff, 1);
directionalLight.position.set(5, 9, 10);
scene.add(directionalLight);
const directionalLight3 = new THREE.DirectionalLight(0xff00ff, 0.5);
directionalLight3.position.set(200, -200, -200);
scene.add(directionalLight3);
const directionalLight2 = new THREE.DirectionalLight(0xda8bff , 0.3);
directionalLight2.position.set(-9, -10, 10);
scene.add(directionalLight2);
const directionalLight4 = new THREE.DirectionalLight(0x4adede, 0.2);
directionalLight4.position.set(-17, -3, 10);
scene.add(directionalLight4);
const element = document.createElement('div');
element.style.width = '80px';
element.style.height = '190px';
element.style.overflowY = 'scroll';
element.style.marginRight = '15px';
element.style.webkitScrollbar = {
width: '4px' // Set it thin
};
element.innerHTML = '<img src="scroll.jpg" alt="scrollable content" style="width: 100%;">';
const style = document.createElement('style');
style.textContent = `
::-webkit-scrollbar {
width: 2px;
}
::-webkit-scrollbar-thumb {
background-color: #2614817c;
}
* {
scrollbar-color: #2614817c transparent;
scrollbar-width: thin;
}
`;
document.head.appendChild(style);
const cssObject = new CSS3DObject(element);
cssObject.scale.set(1, 1, 1);
cssObject.position.set(0, 0, 8);
let iphone;
const loader = new GLTFLoader();
loader.load('iphone.gltf', (gltf) => {
iphone = gltf.scene;
iphone.scale.set(0.022, 0.022, 0.022); // You might need to adjust the scale to fit your scene
iphone.add(cssObject);
scene.add(iphone);
});
css3dRenderer.domElement.style.position = 'absolute';
webGLRenderer.domElement.style.position = 'absolute';
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
let targetRotationX = 0;
let isHovering = false;
function animate() {
requestAnimationFrame(animate);
if (iphone) {
iphone.rotation.x = (targetRotationX - iphone.rotation.x) * 0.1;
iphone.rotation.y += 0.003;
}
const normalMatrix = new THREE.Matrix3().getNormalMatrix(iphone.matrixWorld);
const normal = new THREE.Vector3(0, 0, 1).applyMatrix3(normalMatrix).normalize();
const cameraDirection = camera.getWorldDirection(new THREE.Vector3()).normalize();
const dotProduct = normal.dot(cameraDirection);
if (dotProduct > -0.05) {
cssObject.element.style.opacity = 0;
} else {
cssObject.element.style.opacity = 1;
}
webGLRenderer.render(scene, camera);
css3dRenderer.render(scene, camera);
}
animate();
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
if (iphone) {
const intersects = raycaster.intersectObjects([iphone], true);
//note, I tried to do iphone.children but that didn't work either
if (intersects.length > 0) {
isHovering = true;
targetRotationX = -1;
} else {
isHovering = false;
targetRotationX = 0;
}
}
}
window.addEventListener('mousemove', onMouseMove);