Reputation: 1692
Say I have some elements in the canvas, they may be overridden with each other. When clicking on a point, how can I get that very element?
update: this demo helps a lot: http://mrdoob.github.com/three.js/examples/canvas_interactive_cubes.html
Upvotes: 14
Views: 52405
Reputation: 279
maybe this tool can help you, a full-interaction manager, help three.js easy to binding interaction event
more detial see three.interaction
import { Scene, PerspectiveCamera, WebGLRenderer, Mesh, BoxGeometry, MeshBasicMaterial } from 'three';
import { Interaction } from 'three.interaction';
const renderer = new WebGLRenderer({ canvas: canvasElement });
const scene = new Scene();
const camera = new PerspectiveCamera(60, width / height, 0.1, 100);
// new a interaction, then you can add interaction-event with your free style
const interaction = new Interaction(renderer, scene, camera);
const cube = new Mesh(
new BoxGeometry(1, 1, 1),
new MeshBasicMaterial({ color: 0xffffff }),
);
scene.add(cube);
cube.cursor = 'pointer';
cube.on('click', function(ev) {});
cube.on('touchstart', function(ev) {});
cube.on('touchcancel', function(ev) {});
cube.on('touchmove', function(ev) {});
cube.on('touchend', function(ev) {});
cube.on('mousedown', function(ev) {});
cube.on('mouseout', function(ev) {});
cube.on('mouseover', function(ev) {});
cube.on('mousemove', function(ev) {});
cube.on('mouseup', function(ev) {});
// and so on ...
/**
* you can also listen at parent or any display-tree node,
* source event will bubble up along with display-tree.
*/
scene.on('touchstart', ev => {
console.log(ev);
})
scene.on('touchmove', ev => {
console.log(ev);
})
Upvotes: 5
Reputation: 1152
Drew's answer using THREEx.domevents is outdated. The new API requires initializing a domEvents object and then bind meshes w/ corresponding event listeners to it.
From the Github repo:
var domEvents = new THREEx.DomEvents(camera, renderer.domElement)
// ...
domEvents.addEventListener(mesh, 'click', function(event){
console.log('you clicked on the mesh')
}, false)
Also, it's available on bower!
bower install threex.domevents
Edit:
Though not documented, there is support for 'touchstart'
, 'touchend'
, and a few other mobile events as well. Be sure to look into these if supporting mobile, as mouse 'clicks' aren't always reported as such on some devices.
Upvotes: 2
Reputation: 1935
Use the following code. This will allow you to add a click event and do what you need to when that happens. You can view the source of the page to see what they are doing which is were I got this code from.
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
var projector = new THREE.Projector();
function onDocumentMouseDown( event ) {
event.preventDefault();
var vector = new THREE.Vector3(
( event.clientX / window.innerWidth ) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1,
0.5
);
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position,
vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( objects );
if ( intersects.length > 0 ) {
intersects[ 0 ].object.materials[ 0 ].color.setHex( Math.random() * 0xffffff );
var particle = new THREE.Particle( particleMaterial );
particle.position = intersects[ 0 ].point;
particle.scale.x = particle.scale.y = 8;
scene.add( particle );
}
/*
// Parse all the faces
for ( var i in intersects ) {
intersects[ i ].face.material[ 0 ].color
.setHex( Math.random() * 0xffffff | 0x80000000 );
}
*/
}
Upvotes: 20
Reputation: 310907
The example you link to has a simple API for this.
Put this in your HTML. You'll have to download the script and make sure it loads.
<script src='threex.domevent.js'></script>
Then, on your mesh object, call the following:
mesh.on('click', function()
{
// response to click...
mesh.scale.x *= 2;
});
Or a more interesting example that animates the rotation and color of an object smoothly:
mesh.on('click', function(event)
{
var object3d = event.target,
rotation, color;
if (object3d.rotation.x < Math.PI / 4) {
rotation = {x: Math.PI / 2};
color = {r: 1, g: 0.5, b: 0};
} else {
rotation = {x: 0};
color = {r: 0.5, g: 0.75, b: 0.25};
}
new TWEEN.Tween(object3d.rotation)
.to(rotation, 800)
.easing(TWEEN.Easing.Bounce.EaseOut)
.start();
new TWEEN.Tween(object3d.material.color)
.to(color, 300)
.easing(TWEEN.Easing.Quartic.EaseIn)
.start();
})
Upvotes: 7