Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow mouse control of three.js scene only when mouse is over canvas

Tags:

three.js

3d

The three.js canvas is a 500 x 500 square inside a larger web page with other content and I need mouse control of the camera (for zooming and rotating around the object) to only happen when the mouse is inside the 500 x 500 square.

Also, I am unable to scroll the web page but maybe that will be fixed when we isolate the mouse event listener to the 500 x 500 canvas.

Current code:

<!DOCTYPE html>
<html>
<head> 
   <style>
    div         { 
            position:relative;
            left:100px;           
            top:100px;
            background-color: #eeeeee;
            border:1px solid black;             
            width:500px;
            height:500px;
                }

    canvas      {
            width:500px;
            height:500px;
                }

   </style> 
</head>     
<body> 

    <script src="https://raw.github.com/mrdoob/three.js/master/build/three.min.js"></script>

    <script src="https://raw.github.com/mrdoob/three.js/master/examples/js/loaders/STLLoader.js"></script>

    <script src="https://raw.github.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js"></script>

    <script>
        var container, camera, scene, renderer, controls;

        init();
        animate();

        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            var width = container.clientWidth;
            var height = container.clientHeight;


            camera = new THREE.PerspectiveCamera( 10 , width / height , .1 , 10000 );

            camera.position.set( 0, 0, 10);

            scene = new THREE.Scene();

            controls = new THREE.TrackballControls( camera ); // mouse control
            controls.addEventListener( 'change', render );    // mouse control

            // object

            var loader = new THREE.STLLoader();
            loader.addEventListener( 'load', function ( event ) {

                var geometry = event.content;

                var material = new THREE.MeshLambertMaterial( { ambient: 0xff5533, color: 0xff5533 } );

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

                scene.add( mesh );

            } );

            loader.load( 'slotted_disk.stl' ); // from https://raw.github.com/mrdoob/three.js/master/examples/models/stl/slotted_disk.stl


            // lights

            scene.add( new THREE.AmbientLight( 0x222222 ) );

            var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
            directionalLight.position = camera.position;
            scene.add( directionalLight );

            // renderer

            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setSize( width , height );
            container.appendChild( renderer.domElement );

            window.addEventListener( 'resize', onWindowResize, false );


        }

        function addLight( x, y, z, color, intensity ) {

            var directionalLight = new THREE.DirectionalLight( color, intensity );
            directionalLight.position.set( x, y, z )
            scene.add( directionalLight );

        }

       function onWindowResize() {   

            camera.aspect = width / height;
            camera.updateProjectionMatrix();

            renderer.setSize( width, height );
        }

        function animate() {

            requestAnimationFrame( animate );
    controls.update();
            render();

        }

       function render() {

           camera.lookAt( scene.position );
           renderer.render( scene, camera );

       }

    </script>

</body>
</html>
like image 724
ForumLeech Avatar asked Dec 02 '12 15:12

ForumLeech


2 Answers

Most of the controls allow you to specify which DOM node the event listeners are added to. Event handlers are added to document by default, but this should constrain the mouse handling to your container element:

controls = new THREE.TrackballControls( camera , container);
like image 170
yaku Avatar answered Jan 01 '23 07:01

yaku


Suggested answer does not work for me, this however does. Hope it helps someone!

controls = new THREE.TrackballControls(camera, renderer.domElement);
like image 43
Jonas Johansson Avatar answered Jan 01 '23 08:01

Jonas Johansson