Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mouseleave在three.js中_Javascript_Three.js_Hover_Dom Events_Mouseleave - Fatal编程技术网

Javascript Mouseleave在three.js中

Javascript Mouseleave在three.js中,javascript,three.js,hover,dom-events,mouseleave,Javascript,Three.js,Hover,Dom Events,Mouseleave,我不熟悉Three.js,做了一个实验,我创建了多个球体,并尝试将它们应用于悬停效果。所以当你把鼠标放在一个球体上时,它会变大,而当你把鼠标离开球体时,它会变小 以下是我的想法: //Scene var scene = new THREE.Scene(); //Camera var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000) camera.position.

我不熟悉Three.js,做了一个实验,我创建了多个球体,并尝试将它们应用于悬停效果。所以当你把鼠标放在一个球体上时,它会变大,而当你把鼠标离开球体时,它会变小

以下是我的想法:

    //Scene
var scene = new THREE.Scene();

//Camera
var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
camera.position.z = 10;


//Renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor("#F4F4F4");
renderer.setSize(window.innerWidth,innerHeight);

document.body.appendChild(renderer.domElement);

window.addEventListener('resize', () => {
  renderer.setSize(window.innerWidth,window.innerHeight);
  camera.aspect = window.innerWidth / window.innerHeight;

  camera.updateProjectionMatrix();
})

//Orbit Controls
controls = new THREE.OrbitControls(camera, renderer.domELement);

//Raycaster
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();


//Creating my Spheres
//Shape variable
var geometry = new THREE.SphereGeometry(1, 10, 10);
//Material variable
var material = new THREE.MeshNormalMaterial({wireframe: true});

//loop to create multiple spheres
meshX = -10;
for (var i = 0; i<15; i++) {

  var mesh = new THREE.Mesh(geometry, material);

  mesh.position.x = (Math.random() - 0.5) * 10;
  mesh.position.y = (Math.random() - 0.5) * 10;
  mesh.position.z = (Math.random() - 0.5) * 10;
  scene.add(mesh);
  meshX+=1;
}

//Light
var light = new THREE.PointLight(0xFFFFFF, 1, 500)
light.position.set(10,0,25);
scene.add(light);

//Call the Render method on the renderer
var render = function() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}

//Mouse Over Animation
function onMouseMove(event) {
  event.preventDefault();

  mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
  mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);

  var intersects = raycaster.intersectObjects(scene.children, true);
  for ( var i = 0; i < intersects.length; i++ ) {
    this.tl = new TimelineMax();
    this.tl.to(intersects[i].object.scale, 1, {x: 2, y: 2, z: 2, ease: Expo.easeOut})
  }
}

//Mouse Leave Animation
function onMouseLeave(event) {
  event.preventDefault();

  mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
  mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);

  var intersects = raycaster.intersectObjects(scene.children, true);
  for ( var i = 0; i < intersects.length; i++ ) {
    this.tl = new TimelineMax();
    this.tl.to(intersects[i].object.scale, 1, {x: 1, y: 1, z: 1, ease: Expo.easeOut})
  }
}

//Event Listener
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseleave', onMouseLeave);
render();
现在,这个解决方案面临的问题是我不能在mouseleave上放置动画

我还尝试了THREEx.domevents.js作为替代方案。我能够创建我想要的悬停动画,但是,我无法将其应用于我的所有球体。只有一个受到影响。我无法为此创建一个JSFIDLE,因此下面是它的外观和代码:

任何帮助都将不胜感激。提前谢谢

您不应该订阅window.addEventListener'mouseleave',onMouseLeave; 因为它不会在鼠标离开对象时触发

修复1–移除窗口。在mouseleave上添加EventListener“mouseleave”

修正2–分析raycaster.intersectObjectsscene.children的结果,正确;并手动处理悬停对象的集合,以确定在每次鼠标移动时哪个对象未悬停

更新了您在此处找到的小提琴:

固定代码:

var hoveredObjects = {};

function onMouseMove(event) {
    event.preventDefault();

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(scene.children, true);

    // collect array of uuids of currently hovered objects
    var hoveredObjectUuids = intersects.map(el => el.object.uuid);

    for (let i = 0; i < intersects.length; i++) {
        var hoveredObj = intersects[i].object;
        if (hoveredObjects[hoveredObj.uuid]) {
            continue; // this object was hovered and still hovered
        }

        this.tl = new TimelineMax();
        this.tl.to(intersects[i].object.scale, 1, {
            x: 2,
            ease: Expo.easeOut,
            y: 2,
            ease: Expo.easeOut,
            z: 2,
            ease: Expo.easeOut
        });

        // collect hovered object
        hoveredObjects[hoveredObj.uuid] = hoveredObj;
    }

    for (let uuid of Object.keys(hoveredObjects)) {
        let idx = hoveredObjectUuids.indexOf(uuid);
        if (idx === -1) {
            // object with given uuid was unhovered
            let unhoveredObj = hoveredObjects[uuid];
            delete hoveredObjects[uuid];

            this.tl = new TimelineMax();
            this.tl.to(unhoveredObj.scale, 2, {
                x: 1,
                ease: Expo.easeOut,
                y: 1,
                ease: Expo.easeOut,
                z: 1,
                ease: Expo.easeOut
            });

        }
    }
}

你不能在mouseleave上放动画是什么意思?你有错误吗?我只在您的代码示例中看到mouseout。还有,为什么在tween命令中声明了三次ease?对于所有x、y、z属性,一次就足够了。真的很抱歉造成混淆!!。。。我粘贴了错误的代码。。。我用正确的问题编辑了我的问题。我想感谢您提供的关于放松的提示,我已经更新了我的JSFIDLE!我认为不能像在HTMLDOM事件中那样直接使用mouseleave。将会有更多的解决方案,但我建议在old之前和onMouseMove事件实际发生时计数交叉口,当实际交叉口为空时,因为在同一时间第一个older已满,这可能是可以运行mouseleave功能的条件。如果使用更多的对象,则需要指定哪些对象与所属对象相交,并超出更复杂的模式。
var hoveredObjects = {};

function onMouseMove(event) {
    event.preventDefault();

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(scene.children, true);

    // collect array of uuids of currently hovered objects
    var hoveredObjectUuids = intersects.map(el => el.object.uuid);

    for (let i = 0; i < intersects.length; i++) {
        var hoveredObj = intersects[i].object;
        if (hoveredObjects[hoveredObj.uuid]) {
            continue; // this object was hovered and still hovered
        }

        this.tl = new TimelineMax();
        this.tl.to(intersects[i].object.scale, 1, {
            x: 2,
            ease: Expo.easeOut,
            y: 2,
            ease: Expo.easeOut,
            z: 2,
            ease: Expo.easeOut
        });

        // collect hovered object
        hoveredObjects[hoveredObj.uuid] = hoveredObj;
    }

    for (let uuid of Object.keys(hoveredObjects)) {
        let idx = hoveredObjectUuids.indexOf(uuid);
        if (idx === -1) {
            // object with given uuid was unhovered
            let unhoveredObj = hoveredObjects[uuid];
            delete hoveredObjects[uuid];

            this.tl = new TimelineMax();
            this.tl.to(unhoveredObj.scale, 2, {
                x: 1,
                ease: Expo.easeOut,
                y: 1,
                ease: Expo.easeOut,
                z: 1,
                ease: Expo.easeOut
            });

        }
    }
}