Follow the Cursor Arrows in Javascript

Matt came up with a really interesting visual idea where arrows follow the cursor. He found this codepen example which was pretty close to what he envisioned (only with pill shapes). The problem was that this version used Babel, jQuery, and Underscore. That’s good if you know all those pieces but less good if you don’t. I don’t. Could I do this with just plain javascript?

Make the Boxes

First, I didn’t want to cut and paste a whole bunch of divs (or use pug) so I figured javascript should make them. Since I think I’m funny my arrow boxes are in the arrow class and the div they’re inserted before has the id quiver. I’m making 300 boxes in this example and the CSS sets the arrows as background images.

for(var i = 0; i < 300; i++){
  makeArrow(i);
}

function makeArrow (id){
 var newDiv = document.createElement('div');
  newDiv.classList.add("arrow");
 var newContent = document.createTextNode(" "); 
  // add the text node to the newly created div
  newDiv.appendChild(newContent);  
  var quiver = document.getElementById('quiver');
  document.body.insertBefore(newDiv, quiver); 
}

arrow {
  background-color: #424242;
  width:50px;
  height:50px;
  display:inline-block;
  background-image: url("http://rampages.us/playgroundforme/wp-content/uploads/sites/26581/2018/03/Arrow16up_SWh.svg");
  background-position: center;
  background-repeat: no-repeat;
  margin: 1.5em;
}

Watch the Cursor

This bit watches the body element for the mouse move.

var body = document.getElementsByTagName("body")[0];
body.onmousemove = function(event) {cursorFinder(event)};

The cursorFinder piece gets the X and Y coordinates of the mouse. In this case, we’re also spitting it out at the bottom of the page so we can see what’s going on. It’s pretty much from the W3 example.

function cursorFinder(e) {
    var x = e.clientX;
    var y = e.clientY;
    var coor = "Coordinates: (" + x + "," + y + ")";
}

Now that we can see where the mouse is we need to tilt the divs based on where they are and where the mouse is.

Tilting the Divs

First, we have to get all the arrow divs and where they are. document.getElementsByClassName(“arrow”);

Then we need to tilt them based on where the mouse is. We can do that by manipulating transform rotate CSS.

var theArrows = document.getElementsByClassName("arrow");
  for(var i = 0; i < theArrows.length; i++){
     var xShapeCenter = getPos(theArrows[i],'x');
     var yShapeCenter = getPos(theArrows[i],'y');
    theArrows[i].style.transform = 'rotate('+ twisterMath(x, y, xShapeCenter, yShapeCenter)+'deg)';
  }

To make them tilt in the right ways, I used the math from the original example. It involves arc tangent and Pi so I have no idea how they figured this out but it works nicely. Math.atan2(x – xShapeCenter,-(y – yShapeCenter)) *(180 / Math.PI)

//from this crazy smart person https://codepen.io/frost084/details/MOEpog#forks
function twisterMath(x,y, xShapeCenter, yShapeCenter){
  return  Math.atan2(x - xShapeCenter,-(y - yShapeCenter)) *(180 / Math.PI)
}

That gets us a basic setup (below in whole) but it also opens the door to do other fun stuff like manipulating the background opacity via other math tricks. It’s fun and the variations are pretty endlessly amusing (at least to me).

See the Pen follow the arrow by Tom (@twwoodward) on CodePen.