鼠标离开 three.js
Mouseleave in three.js
我是 Three.js 的新手,我做了一个实验,我创建了多个球体并尝试将它们应用到 "hover" 效果。因此,当您将鼠标放在球体上时,它会变大,而当您将鼠标离开球体时,它会变小。
这是我想出的:
//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();
https://jsfiddle.net/xaviergodbout/evdxLbk8/13/
现在,这个解决方案面临的问题是我无法在 "mouseleave" 上放置动画。
我也尝试了 THREEx.domevents.js 作为替代方案。我能够创建我想要的悬停动画,但是我无法将它应用到我的所有领域。只有一个受到影响。我无法为此创建一个 JSFiddle,所以这是它的样子和代码:
GIF Preview of what happen with THREEx.domevents.js
//Scene
var scene = new THREE.Scene();
//Camera
var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
camera.position.z = 300;
//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,innerHeight);
camera.aspect = window.innerWidth / innerHeight;
camera.updateProjectionMatrix();
})
controls = new THREE.OrbitControls(camera, renderer.domELement);
//Creating a sphere
//Shape variable
var aCircles = [];
var geometry = new THREE.SphereGeometry(20, 20, 20);
//Material variable
var material = new THREE.MeshNormalMaterial({wireframe: true});
for (var i = 0; i < 15; i++) {
var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = (Math.random() - 0.5) *200;
mesh.position.y = (Math.random() - 0.5) *200;
mesh.position.z = (Math.random() - 0.5) *200;
scene.add(mesh);
aCircles.push(mesh);
}
var light = new THREE.PointLight(0xFFFFFF, 1, 500)
light.position.set(10,0,25);
scene.add(light);
var domEvents = new THREEx.DomEvents(camera, renderer.domElement)
var url = 'http://xaviergodbout.com/'
var linkify = THREEx.Linkify(domEvents, mesh, url, true)
var sphereClicked = false
domEvents.addEventListener(mesh, 'click', event => {
if (!sphereClicked) {
material.wireframe = false
sphereClicked = true
} else {
material.wireframe = true
sphereClicked = false
}
})
domEvents.addEventListener(mesh, 'mouseover', event => {
this.tl = new TimelineMax();
this.tl.to(this.mesh.scale, 1, {x: 2, ease: Expo.easeOut, y: 2, ease: Expo.easeOut, z: 2, ease: Expo.easeOut})
})
domEvents.addEventListener(mesh, 'mouseout', event => {
this.tl = new TimelineMax();
this.tl.to(this.mesh.scale, 1, {x: 1, ease: Expo.easeOut, y: 1, ease: Expo.easeOut, z: 1, ease: Expo.easeOut})
})
domEvents.addEventListener(mesh, 'dblclick', event => {
this.tl = new TimelineMax();
this.tl.to(this.mesh.scale, 1, {x: 5, ease: Expo.easeOut, y: 5, ease: Expo.easeOut, z: 5, ease: Expo.easeOut})
})
//Call the Render method on the renderer
var render = function() {
requestAnimationFrame(render);
renderer.render(scene, camera);
mesh.rotation.y += 0.01
}
render();
任何帮助将不胜感激。提前致谢!
你不应该订阅 window.addEventListener('mouseleave', onMouseLeave);
因为当鼠标离开对象时它不会触发。
修复 #1 – 删除 window.addEventListener('mouseleave', onMouseLeave);
修复 #2 – 分析 raycaster.intersectObjects(scene.children, true);
的结果并手动处理悬停对象的集合,以说明每次鼠标移动时哪个对象未悬停。
已更新 fiddle 您在此处找到:https://jsfiddle.net/mmalex/c7t6b1ze/
固定码:
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
});
}
}
}
我是 Three.js 的新手,我做了一个实验,我创建了多个球体并尝试将它们应用到 "hover" 效果。因此,当您将鼠标放在球体上时,它会变大,而当您将鼠标离开球体时,它会变小。
这是我想出的:
//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();
https://jsfiddle.net/xaviergodbout/evdxLbk8/13/
现在,这个解决方案面临的问题是我无法在 "mouseleave" 上放置动画。
我也尝试了 THREEx.domevents.js 作为替代方案。我能够创建我想要的悬停动画,但是我无法将它应用到我的所有领域。只有一个受到影响。我无法为此创建一个 JSFiddle,所以这是它的样子和代码: GIF Preview of what happen with THREEx.domevents.js
//Scene
var scene = new THREE.Scene();
//Camera
var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
camera.position.z = 300;
//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,innerHeight);
camera.aspect = window.innerWidth / innerHeight;
camera.updateProjectionMatrix();
})
controls = new THREE.OrbitControls(camera, renderer.domELement);
//Creating a sphere
//Shape variable
var aCircles = [];
var geometry = new THREE.SphereGeometry(20, 20, 20);
//Material variable
var material = new THREE.MeshNormalMaterial({wireframe: true});
for (var i = 0; i < 15; i++) {
var mesh = new THREE.Mesh(geometry, material);
mesh.position.x = (Math.random() - 0.5) *200;
mesh.position.y = (Math.random() - 0.5) *200;
mesh.position.z = (Math.random() - 0.5) *200;
scene.add(mesh);
aCircles.push(mesh);
}
var light = new THREE.PointLight(0xFFFFFF, 1, 500)
light.position.set(10,0,25);
scene.add(light);
var domEvents = new THREEx.DomEvents(camera, renderer.domElement)
var url = 'http://xaviergodbout.com/'
var linkify = THREEx.Linkify(domEvents, mesh, url, true)
var sphereClicked = false
domEvents.addEventListener(mesh, 'click', event => {
if (!sphereClicked) {
material.wireframe = false
sphereClicked = true
} else {
material.wireframe = true
sphereClicked = false
}
})
domEvents.addEventListener(mesh, 'mouseover', event => {
this.tl = new TimelineMax();
this.tl.to(this.mesh.scale, 1, {x: 2, ease: Expo.easeOut, y: 2, ease: Expo.easeOut, z: 2, ease: Expo.easeOut})
})
domEvents.addEventListener(mesh, 'mouseout', event => {
this.tl = new TimelineMax();
this.tl.to(this.mesh.scale, 1, {x: 1, ease: Expo.easeOut, y: 1, ease: Expo.easeOut, z: 1, ease: Expo.easeOut})
})
domEvents.addEventListener(mesh, 'dblclick', event => {
this.tl = new TimelineMax();
this.tl.to(this.mesh.scale, 1, {x: 5, ease: Expo.easeOut, y: 5, ease: Expo.easeOut, z: 5, ease: Expo.easeOut})
})
//Call the Render method on the renderer
var render = function() {
requestAnimationFrame(render);
renderer.render(scene, camera);
mesh.rotation.y += 0.01
}
render();
任何帮助将不胜感激。提前致谢!
你不应该订阅 window.addEventListener('mouseleave', onMouseLeave);
因为当鼠标离开对象时它不会触发。
修复 #1 – 删除 window.addEventListener('mouseleave', onMouseLeave);
修复 #2 – 分析 raycaster.intersectObjects(scene.children, true);
的结果并手动处理悬停对象的集合,以说明每次鼠标移动时哪个对象未悬停。
已更新 fiddle 您在此处找到:https://jsfiddle.net/mmalex/c7t6b1ze/
固定码:
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
});
}
}
}