CSS转换后更新Three.js Raycaster [英] Update Three.js Raycaster After CSS Tranformation

查看:76
本文介绍了CSS转换后更新Three.js Raycaster的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Three.js尝试使用WebGL。我是初学者,我决定尝试类似于这个的内容。我已经能够实现其中的大部分。我目前面临的问题是在向左移动画布后更新raycaster和对象。每当我在画布移动后悬停时,它都不会反射在球体上,除非我将鼠标向东移动,离球体有一段距离。我已经检查了几个帖子,我试着移动相机和球体位置无济于事。



这是代码:



< pre class =snippet-code-js lang-js prettyprint-override> 让scene,camera,renderer; var raycaster,mouse,INTERSECTED; let SCREEN_WIDTH = window.innerWidthlet SCREEN_HEIGHT = window.innerHeightlet 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(几何,材料); 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;}函数onClick(){raycaster.setFromCamera(mouse,camera); var intersects = raycaster.intersectObjects(objects); console.log(我是点击:,相交)} 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(几何,材料); 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 {身高:100%;填充:0;保证金:0; } #scene {position:relative;身高: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;过渡:变换.7s轻松进出; } .bar {display:block;身高:3px;宽度:30px; background-color:#00ff00;保证金:5px auto; -webkit-transition:所有.7s轻松; -moz-transition:所有.7s轻松; -ms-transition:所有.7s轻松; -o-transition:所有.7s轻松;过渡:所有.7s轻松; } .hamburger {position:fixed;右:40px;上:20px; z-index:3; -webkit-transition:所有.7s轻松; -moz-transition:所有.7s轻松; -ms-transition:所有.7s轻松; -o-transition:所有.7s轻松;过渡:所有.7s轻松; } .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)请包含小提琴的完整代码。当(不是)你的小提琴消失时,问题的背景和答案也会消失。



2)你附上鼠标事件到文档,而不是移动的部分。改为使用:

  canvas.addEventListener('mousemove',onDocumentMouseMove,false); 
canvas.addEventListener('mousemove',onHover,false);

3) clientX / clientY 不要表现出你对他们的期望。使用 offsetX / offsetY 获取相对于画布的坐标(如果您按照步骤2执行)。 (不要担心MDN说它是实验性的,它在支持WebGL的浏览器中运行良好。)

  mouse.x = (event.offsetX / SCREEN_WIDTH)* 2  -  1; 
mouse.y = - (event.offsetY / SCREEN_HEIGHT)* 2 + 1;


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;

这篇关于CSS转换后更新Three.js Raycaster的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆