Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update Three.js Raycaster After CSS Tranformation

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>
like image 453
odujokod Avatar asked Aug 06 '17 18:08

odujokod


1 Answers

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;
like image 86
TheJim01 Avatar answered Oct 19 '22 01:10

TheJim01