title: Magnet effect using particles in Three js
body: <p>I'm using the following code based on one of the official Three.js examples: </p>
  
  <pre><code>        var SCREEN_WIDTH = window.innerWidth,
          SCREEN_HEIGHT = window.innerHeight,
  
          mouseX = 0, mouseY = 0,
  
          windowHalfX = window.innerWidth / 2,
          windowHalfY = window.innerHeight / 2,
  
          SEPARATION = 200,
          AMOUNTX = 10,
          AMOUNTY = 10,
  
          camera, scene, renderer, startx, starty, startz, currentx, currenty, currentz;
  
          init();
          animate();
  
          function init() {
  
              var container, separation = 100, amountX = 50, amountY = 50,
              particles, particle;
  
              container = document.createElement('div');
  
              var currentDiv = document.getElementById("container");
          currentDiv.appendChild(container);
              $('#container &gt; div').hide();
  
  
              camera = new THREE.PerspectiveCamera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
              camera.position.z = 1000;
  
              scene = new THREE.Scene();
  
              renderer = new THREE.CanvasRenderer();
              renderer.setPixelRatio( window.devicePixelRatio );
              renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
              renderer.setClearColor( 0xe0e0e0, 1);
              container.appendChild( renderer.domElement );
  
              // particles
  
              var PI2 = Math.PI * 2;
              var material = new THREE.SpriteCanvasMaterial( {
  
                  color: 0x0000ee,
                  program: function ( context ) {
  
                      context.beginPath();
                      context.arc( 0, 0, 0.5, 0, PI2, true );
                      context.fill();
  
                  }
  
              } );
  
              group = new THREE.Group();
              scene.add( group );
  
              for ( var i = 0; i &lt; 200; i ++ ) {
  
                  particle = new THREE.Sprite( material );
                  startx = particle.position.x = Math.random() * 2 - 1;
                  starty = particle.position.y = Math.random() * 2 - 1;
                  startz = particle.position.z = Math.random() * 2 - 1;
                  particle.position.normalize();
                  particle.position.multiplyScalar( Math.random() * 1 + 450 );
                  particle.scale.multiplyScalar( 2 );
                  group.add( particle );
  
              }
  
  
              document.addEventListener( 'mousemove', onDocumentMouseMove, false );
              document.addEventListener( 'touchstart', onDocumentTouchStart, false );
              document.addEventListener( 'touchmove', onDocumentTouchMove, false );
  
              //
  
              window.addEventListener( 'resize', onWindowResize, false );
  
          }
  
          function onWindowResize() {
  
              windowHalfX = window.innerWidth / 2;
              windowHalfY = window.innerHeight / 2;
  
              camera.aspect = window.innerWidth / window.innerHeight;
              camera.updateProjectionMatrix();
  
              renderer.setSize( window.innerWidth, window.innerHeight );
  
          }
  
          //
  
          function onDocumentMouseMove(event) {
  
              mouseX = event.clientX - windowHalfX;
              mouseY = event.clientY - windowHalfY;
          }
  
          function onDocumentTouchStart( event ) {
  
              if ( event.touches.length &gt; 1 ) {
  
                  event.preventDefault();
  
                  mouseX = event.touches[ 0 ].pageX - windowHalfX;
                  mouseY = event.touches[ 0 ].pageY - windowHalfY;
  
              }
  
          }
  
          function onDocumentTouchMove( event ) {
  
              if ( event.touches.length == 1 ) {
  
                  event.preventDefault();
  
                  mouseX = event.touches[ 0 ].pageX - windowHalfX;
                  mouseY = event.touches[ 0 ].pageY - windowHalfY;
  
              }
  
          }
  
          //
  
          function animate() {
  
              requestAnimationFrame( animate );
  
              render();
  
          }
  
          setTimeout( function(){
  
              $('#container &gt; div').fadeIn(3000);
          }, 1000 );
  
  
  
          function render() {
  
              camera.position.x += ( mouseX - camera.position.x ) * .05;
              camera.position.y += ( - mouseY + 20 - camera.position.y ) * .05;
              camera.lookAt( scene.position );
  
  
  
              for (var i = 0; i &lt; group.children.length; i++) {
                  group.children[i].position.x += Math.random() * 2 - 1;
                  group.children[i].position.y += Math.random() * 2 - 1;
                  group.children[i].position.z += Math.random() * 2 - 1;
                  /*currentx = group.children[i].position.x;
                  currenty = group.children[i].position.y;
                  currentz = group.children[i].position.z;
  
                  if (Math.sqrt(mouseX*mouseX+currentx*currentx)&lt;330 &amp;&amp; Math.sqrt(mouseY*mouseY+currenty*currenty)&lt;330) {
  
  
                      var boosterx = (mouseX==group.children[i].position.x) ? '' : 1;
                      var boostery = (mouseY==group.children[i].position.y) ? '' : 1;
  
                      group.children[i].position.x += boosterx;
                      group.children[i].position.y += boostery;*/
                  }
  
  
              }
  
              renderer.render( scene, camera );
  
          }
  </code></pre>
  
  <p>Everything works fine but there's one effect that I can't get to work. I want the particles to react whenever cursor comes close after reaching certain point (sort of magnet-like effect - the closer the cursor is, the faster particles are going towards it). I know it may be difficult to achieve since there is some 3d/2d translation. I am noob when it comes to 3d canvas and js in general but something tells me it can be done. I tried to do it on my own and thats where the messy part (commented) at the end comes from. Thanks!</p>