如何解决removeEventListener 在我的three.js
我是 JavaScript 的新手(但对数学(坐标系、三角学和 Three.js 中涉及的其他一些东西)并不陌生)。我已经在 JavaScript 代码学院学习了两个星期,我尝试按照 YouTube 上的教程在three.js 中制作形状,以及当您单击鼠标或将鼠标悬停在对象上时发生的事情。尽管我正在学习教程,但我必须针对同一主题观看 5 个不同的教程才能使其正常工作,但我仍然遇到问题。
我有 5 个对象,如果你将鼠标悬停在它们上面,它们会轻微旋转(比如 40 度,但这无关紧要),当你将鼠标移离对象时,它会稍微反向旋转回到起始位置位置。 如果我点击它们中的任何一个,我就会有一个向物体靠近的相机的补间。如果我再次单击同一个对象,它会将相机补间回到场景开始时的位置。
我为 'mousemove' 和 'onclick' 创建了事件监听器,它们可以工作....但我想要的是,如果一个人点击了其中一个对象并且相机向它移动,我想删除悬停效果(然后,如果他们再次单击对象,则使事情恢复正常,这将使相机返回原点)。
目前我有一个关于 3D 对象的 raycaster 的 if 语句,所以我尝试在我点击一个对象时执行的代码块内添加一行,因为那是我希望事件监听器不活动的时候。我尝试进行谷歌搜索,查看 stackoverflow,观看了更多 YouTube 视频,查看了 MDN 网站,发现我完全按照说明操作(据我所知),但它无法正常工作。可能是我什至没有考虑到的事情,例如无法在 if 语句或其他内容中删除事件侦听器。
如果是这种情况,那么有没有一种方法可以禁用处理轻微旋转的补间,而仅在 if 语句的特殊情况下?
我尝试通过在我的 if 语句中的 case 中添加一行来实现此目的,该语句在单击事件触发补间但没有任何反应时执行。
//ONE OF THE OBJECTS FOR REFERENCE
const minigeometry1 = new THREE.CylinderGeometry(5,5,0.5,50);
const minimaterial1 = new THREE.MeshLAmbertMaterial();
const minicylinder1 = new THREE.Mesh(minigeometry1,minimaterial1);
minicylinder1.name = 'minicylinder1';
minicylinder1.position.z = 7.5;
minicylinder1.position.x = -40;
minicylinder1.rotation.z = Math.PI / 2;
minicylinder1.rotation.y = Math.PI / 2;
scene.add(minicylinder1);
//TWEEN ANIMATIONS FOR CLICK EVENTS
function tweenCamera(finalPosition,tweenSpeed) {
let initialPosition = new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);
new TWEEN.Tween(initialPosition)
.to(finalPosition,tweenSpeed)
.onUpdate(() => {
camera.position.set(initialPosition.x,initialPosition.y,initialPosition.z);
})
.easing(TWEEN.Easing.Cubic.Out)
.start();
}
//WHERE THE CAMERA IS CURRENTLY LOOKING,I THINK
let currentTarget = new THREE.Vector3();
currentTarget.set(controls.target.x,controls.target.y,controls.target.z);
let originTarget = new THREE.Vector3();
originTarget.set(0,0);
//TELLS CAMERA TO ORIENT TOWARD SPECIFIED OBJECT (target controls = camera orientation?)
let cylinderTarget = new THREE.Vector3();
cylinderTarget.set(cylinder.position.x,cylinder.position.y - 15,cylinder.position.z);
let minicylinder1Target = new THREE.Vector3();
minicylinder1Target.set(minicylinder1.position.x,minicylinder1.position.y,minicylinder1.position.z);
//THIS DETERmineS WHETHER WE ARE ZOOMING IN TO,OR OUT OF,OUR SELECTION
let coin1Clicked = false;
let coin2Clicked = false;
let coin3Clicked = false;
let coin4Clicked = false;
这是我的事件侦听器.....
//THESE ARE AT THE BottOM OF MY CODE BUT They RUN WITHOUT ISSUE
window.addEventListener("click",(event) => {
onClick(event);
})
window.addEventListener("mousemove",(event) => {
onMouseMove(event);
})
这是我的 onClick 函数和它下面的 onMouseMove 函数。你可以在这里看到,在我的 if 语句的第一个例子中,我尝试使用 removeEventListener(从这里向下 17 行),但它不起作用。
function onClick(event) {
//normalized mouse coordinates (-1,+1)
mouse.x = (event.offsetX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse,camera);
const intersects = raycaster.intersectObjects(scene.children,true);
if ((getIndexInIntersectsArray(cylinder,intersects) > -1)) {
window.open(cylinder.userData.URL);
}
//IF WE CLICK ON COIN1 FROM THE MAIN POSITION,WE WILL ZOOM INTO IT
if ((getIndexInIntersectsArray(minicylinder1,intersects) > -1) && (!coin1Clicked)) {
coin1Clicked = true;
window.removeEventListener("mousemove",(event) => {
onMouseMove(event);
})
//CODE THAT ACHIEVES MY SLIGHT ROTATION THAT I FOUND ON STACKOVERFLOW
var start = {}
start.y = 0;
var targ = {};
targ.y = 0;
function rot(s,t) {
start["y"] = s;
targ["y"] = t;
}
rot(1.5*Math.PI/2,4.5*Math.PI);
const spun1 = new TWEEN.Tween(start).to(targ,1500).onUpdate(function() {minicylinder1.rotation.y = start.y}).easing(TWEEN.Easing.Quintic.Out);
spun1.start();
new TWEEN.Tween(currentTarget)
.to(minicylinder1Target,2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
//RESTRICT CAMERA ROTATION AND ZOOM OUT
tweenCamera(new THREE.Vector3(minicylinder1.position.x,25),2500)
return coin1Clicked;
} else if ((getIndexInIntersectsArray(minicylinder1,intersects) > -1) && (coin1Clicked)) {
//TWEEN TO ORIENT CAMERA TOWARDS ORIGIN
new TWEEN.Tween(currentTarget)
.to(cylinderTarget,2500)
.onUpdate(function() {
controls.target = currentTarget;
})
.easing(TWEEN.Easing.Quartic.InOut)
.start()
coin1Clicked = false;
//MOVES CAMERA BACK TO THE ORIGIN
tweenCamera(new THREE.Vector3(minicylinder3.position.x,20,60),2500)
return coin1Clicked;
} else if ((getIndex....................................
对象 2 到对象 4 相同
let coin1Hover = false;
function onMouseMove(event) {
mouse.x = (event.offsetX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse,true);
if ((getIndexInIntersectsArray(minicylinder1,intersects) > -1) && !coin1Hover) {
coin1Hover = true;
var start = {}
start.y = 0;
var targ = {};
targ.y = 0;
function rot(s,t) {
start["y"] = s;
targ["y"] = t;
}
rot(Math.PI/2,1.5*Math.PI/2);
const spinning1 = new TWEEN.Tween(start).to(targ,350).onUpdate(function() {minicylinder1.rotation.y = start.y});
spinning1.start();
return coin1Hover
} else if ((getIndexInIntersectsArray(minicylinder1,intersects) > -1) && coin1Hover) {
} else if ((getIndexInIntersectsArray(minicylinder1,intersects) == -1) && coin1Hover) {
coin1Hover = false;
var start = {}
start.y = 0;
var targ = {};
targ.y = 0;
function rot(s,Math.PI/2);
const backwards = new TWEEN.Tween(start).to(targ,350).onUpdate(function() {minicylinder1.rotation.y = start.y});
backwards.start();
return coin1Hover
}
function getIndexInIntersectsArray(elem,array) {
var ind = -1;
for (var i = 0; i < array.length; i++) {
if (array[i].object.name == elem.name) {
ind = i;
}
}
return ind;
}
}
请,如果有人可以提供帮助,我将不胜感激。我不想听起来太戏剧化,但这是我父亲不会停止骚扰我的事情,我再也无法忍受失败的感觉。 :-(
解决方法
您现在正在使用此模式添加事件侦听器:
window.addEventListener("mousemove",(event) => {
onMouseMove(event);
});
然后像这样删除它们:
window.removeEventListener("mousemove",(event) => {
onMouseMove(event);
});
您必须注意,您为两个方法调用分配了两个不同的匿名函数。这样,就不可能删除正确的事件侦听器。请改用此模式:
window.addEventListener("mousemove",onMouseMove);
后来:
window.removeEventListener("mousemove",onMouseMove);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。