在CSS Tranformation之后更新Three.js Raycaster
问题描述:
我正在尝试使用Three.js的WebGL。我是一名初学者,我决定试试类似this的东西。我已经能够实现它的大部分。我目前面临的问题是在将画布左移之后更新raycaster和对象。只要我在画布移动后悬停,除了将鼠标向东移动一段距离外,它不会反射到球体上。我已经检查了几个帖子,我试图移动相机和球体的位置无济于事。在CSS Tranformation之后更新Three.js Raycaster
下面的代码:
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 {
\t \t \t height: 100%;
\t \t \t padding: 0;
\t \t \t margin: 0;
\t \t }
\t \t #scene {
\t \t \t position: relative;
\t \t \t height: 100%;
\t \t \t -webkit-transition: transform .7s ease-in-out;
\t \t \t -moz-transition: transform .7s ease-in-out;
\t \t \t -ms-transition: transform .7s ease-in-out;
\t \t \t -o-transition: transform .7s ease-in-out;
\t \t \t transition: transform .7s ease-in-out;
\t \t }
\t \t .bar {
\t \t \t display: block;
\t \t \t height: 3px;
\t \t \t width: 30px;
\t \t \t background-color: #00ff00;
\t \t \t margin: 5px auto;
\t \t \t -webkit-transition: all .7s ease;
\t \t \t -moz-transition: all .7s ease;
\t \t \t -ms-transition: all .7s ease;
\t \t \t -o-transition: all .7s ease;
\t \t \t transition: all .7s ease;
\t \t }
\t \t .hamburger {
\t \t \t position: fixed;
\t \t \t right: 40px;
\t \t \t top: 20px;
\t \t \t z-index: 3;
\t \t \t -webkit-transition: all .7s ease;
\t \t \t -moz-transition: all .7s ease;
\t \t \t -ms-transition: all .7s ease;
\t \t \t -o-transition: all .7s ease;
\t \t \t transition: all .7s ease;
\t \t }
\t \t .hamburger.active .top {
\t \t \t -webkit-transform: translateY(7px) rotateZ(45deg);
\t \t \t -moz-transform: translateY(7px) rotateZ(45deg);
\t \t \t -ms-transform: translateY(7px) rotateZ(45deg);
\t \t \t -o-transform: translateY(7px) rotateZ(45deg);
\t \t \t transform: translateY(7px) rotateZ(45deg);
\t \t }
\t \t .hamburger.active .bottom {
\t \t \t -webkit-transform: translateY(-10px) rotateZ(-45deg);
\t \t \t -moz-transform: translateY(-10px) rotateZ(-45deg);
\t \t \t -ms-transform: translateY(-10px) rotateZ(-45deg);
\t \t \t -o-transform: translateY(-10px) rotateZ(-45deg);
\t \t \t transform: translateY(-10px) rotateZ(-45deg);
\t \t }
\t \t .hamburger.active .middle {
\t \t \t width: 0;
\t \t }
\t \t .slide-left {
\t \t \t -webkit-transform: translateX(-250px);
\t \t \t -moz-transform: translateX(-250px);
\t \t \t -ms-transform: translateX(-250px);
\t \t \t -o-transform: translateX(-250px);
\t \t \t transform: translateX(-250px);
\t \t }
<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;
谢谢。我现在将添加完整的代码。 – odujokod
Thaks终于我做到了。 – George