how to get clicked element in THREE.js

前端 未结 4 1624
长情又很酷
长情又很酷 2020-12-04 20:34

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: t

相关标签:
4条回答
  • 2020-12-04 20:51

    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);
    })

    0 讨论(0)
  • 2020-12-04 20:54

    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();
    })
    
    0 讨论(0)
  • 2020-12-04 20:55

    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.

    0 讨论(0)
  • 2020-12-04 21:06

    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 );
        }
        */
    }
    
    0 讨论(0)
提交回复
热议问题