I am trying my hands on WebGL using Three.js. I am a beginner and I decided to try out something similar to this. I have been able to achieve most of it. The issue I am currently facing is updating the raycaster and object after moving the canvas left. Whenever I hover after the canvas has been moved, it doesn't reflect on the sphere except I move the mouse eastwards, some distance away from the sphere. I have checked out several posts, I tried moving the camera and sphere position to no avail.
Here's the code:
let scene, camera, renderer;
var raycaster, mouse, INTERSECTED;
let SCREEN_WIDTH = window.innerWidth
let SCREEN_HEIGHT = window.innerHeight
let canvas = document.getElementById('scene')
let objects = []
init();
animate();
$(".hamburger").on("click", function () {
$(".hamburger").toggleClass("active");
$("#scene").toggleClass("slide-left");;
});
function init() {
renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
});
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.setClearColor(0x000000);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(
100, SCREEN_WIDTH / SCREEN_HEIGHT, .1, 10000);
camera.position.set(0, 0, 10);
camera.lookAt(new THREE.Vector3(0, 0, 0));
var geometry = new THREE.SphereGeometry(5, 32, 32);
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
sphere = new THREE.Mesh(geometry, material);
objects.push(sphere)
scene.add(sphere);
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener('mousemove', onHover, false);
document.addEventListener('click', onClick, false);
window.addEventListener('resize', render, false);
scene.add(new THREE.AmbientLight(0x333333));
var light = new THREE.DirectionalLight(0xffffff, 0.8);
light.position.set(50, 3, 5);
scene.add(light);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / SCREEN_WIDTH) * 2 - 1;
mouse.y = - (event.clientY / SCREEN_HEIGHT) * 2 + 1;
}
function onClick() {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects);
console.log("I was click: ", intersects)
}
function onHover() {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects);
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED) INTERSECTED.remove(INTERSECTED.sphere);
INTERSECTED = intersects[0].object//.geometry;
var geometry = new THREE.SphereGeometry(5.1, 32, 32);
var material = new THREE.MeshBasicMaterial({
color: 0xff5521,
opacity: 0.01
});
sphere1 = new THREE.Mesh(geometry, material);
INTERSECTED.sphere = sphere1
INTERSECTED.add(sphere1);
}
} else {
if (INTERSECTED) INTERSECTED.remove(INTERSECTED.sphere);
INTERSECTED = null;
}
}
function render() {
sphere.rotation.x += 0.01
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
renderer.render(scene, camera);
};
body {
height: 100%;
padding: 0;
margin: 0;
}
#scene {
position: relative;
height: 100%;
-webkit-transition: transform .7s ease-in-out;
-moz-transition: transform .7s ease-in-out;
-ms-transition: transform .7s ease-in-out;
-o-transition: transform .7s ease-in-out;
transition: transform .7s ease-in-out;
}
.bar {
display: block;
height: 3px;
width: 30px;
background-color: #00ff00;
margin: 5px auto;
-webkit-transition: all .7s ease;
-moz-transition: all .7s ease;
-ms-transition: all .7s ease;
-o-transition: all .7s ease;
transition: all .7s ease;
}
.hamburger {
position: fixed;
right: 40px;
top: 20px;
z-index: 3;
-webkit-transition: all .7s ease;
-moz-transition: all .7s ease;
-ms-transition: all .7s ease;
-o-transition: all .7s ease;
transition: all .7s ease;
}
.hamburger.active .top {
-webkit-transform: translateY(7px) rotateZ(45deg);
-moz-transform: translateY(7px) rotateZ(45deg);
-ms-transform: translateY(7px) rotateZ(45deg);
-o-transform: translateY(7px) rotateZ(45deg);
transform: translateY(7px) rotateZ(45deg);
}
.hamburger.active .bottom {
-webkit-transform: translateY(-10px) rotateZ(-45deg);
-moz-transform: translateY(-10px) rotateZ(-45deg);
-ms-transform: translateY(-10px) rotateZ(-45deg);
-o-transform: translateY(-10px) rotateZ(-45deg);
transform: translateY(-10px) rotateZ(-45deg);
}
.hamburger.active .middle {
width: 0;
}
.slide-left {
-webkit-transform: translateX(-250px);
-moz-transform: translateX(-250px);
-ms-transform: translateX(-250px);
-o-transform: translateX(-250px);
transform: translateX(-250px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js"></script>
<canvas id="scene"></canvas>
<div class="hamburger">
<div class="bar top"></div>
<div class="bar middle"></div>
<div class="bar bottom"></div>
</div>
1) Please include the full code of your fiddle. When (not if) your fiddle goes away, so does the context of your question, and this answer.
2) You're attaching the mouse events to the document, not to the part that's moving. Use this instead:
canvas.addEventListener('mousemove', onDocumentMouseMove, false);
canvas.addEventListener('mousemove', onHover, false);
3) clientX
/clientY
don't behave how you're expecting them to. Use offsetX
/offsetY
to get the coordinates relative to the canvas (provided you followed step 2). (Don't worry that MDN says it's experimental, it works just fine in browsers that support WebGL.)
mouse.x = (event.offsetX / SCREEN_WIDTH) * 2 - 1;
mouse.y = - (event.offsetY / SCREEN_HEIGHT) * 2 + 1;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With