CodePen

HTML

            
              <canvas id="c"></canvas>
<p>
  Current Angle: <span id="angle"></span><br />
  &nbsp;Target Angle: <span id="target-angle"></span><br />
</p>
<p>I'm trying to have the joint rotate smoothly around the center of the canvas, toward the angle of mouse pointer. What I have works, but I want it to animate the shortest distance possible, to get to the mouse angle. The problem occurs when the value loops around at the horizontal line (3.14 and -3.14). Mouseover that area to see how the direction switches and it takes the long way back around.</p>
<p>Relevant lines of code are 20 and 48. Any ideas on how to get this working?</p>
            
          
!

↑ Insert the most common viewport meta tag

CSS

            
              body {
  background: #ddd;
  font: 100%/1.5 monospace;
}

canvas {
  background: #fff;
  display: block;
}

p {
  max-width: 40em;
  padding-left: 1.5em;
}
            
          
!
? ?
? ?
Must be a valid URL.
+ add another resource
via CSS Lint

JS

            
              var c = document.getElementById( 'c' ),
    ctx = c.getContext( '2d' ),
    cw = c.width = 300,
    ch = c.height = 200,
    joint = {
      x: cw / 2,
      y: ch / 2,
      length: 50,
      angle: 0,
      targetAngle: 0,
      easing: 0.05
    },
    angleElem = document.getElementById( 'angle' );
    targetAngleElem = document.getElementById( 'target-angle' );

function step() {
  requestAnimationFrame( step );
  ctx.clearRect( 0, 0, cw, ch );
  
  // ease the current angle to the target angle
  //joint.angle += ( joint.targetAngle - joint.angle ) * joint.easing;
  
   var dtheta = joint.targetAngle - joint.angle;
  if (dtheta > Math.PI) joint.angle += 2*Math.PI
  else if (dtheta < -Math.PI) joint.angle -= 2*Math.PI
  joint.angle += ( joint.targetAngle - joint.angle ) * joint.easing;
  
  ctx.save();
  ctx.beginPath();
  ctx.translate( joint.x, joint.y + 0.5 );
  ctx.rotate( joint.angle );
  ctx.moveTo( 0, 0 );
  ctx.lineTo( joint.length, 0 );
  ctx.lineWidth = 5;
  ctx.stroke();
  ctx.restore();
  
  ctx.beginPath();
  ctx.arc( joint.x, joint.y, 10, 0, Math.PI * 2 );
  ctx.fill();
  
  ctx.beginPath();
  ctx.moveTo( 0, joint.y + 0.5 );
  ctx.lineTo( joint.x, joint.y + 0.5 );
  ctx.lineWidth = 1;
  ctx.stroke();
  
  angleElem.innerHTML = joint.angle.toFixed( 3 );
  targetAngleElem.innerHTML = joint.targetAngle.toFixed( 3 );
}

window.addEventListener( 'mousemove', function( e ) {
  // get angle from joint to mouse
  var dx = e.clientX - joint.x,
      dy = e.clientY - joint.y;  
  joint.targetAngle = Math.atan2( dy, dx );
}, false );

step();
            
          
!
Must be a valid URL.
+ add another resource
via JS Hint
Loading ..................