<!-- Inspired by Peter Cho www.typotopo.com -->
<canvas></canvas>
<aside>
	<h1>Find your mouse cursor</h1>
	<h2>by @gianlucaguarini</h2>
</aside>
	body {
		overflow:hidden;
		margin:0;
      font-family: Georgia;
		font-weight: normal;
		font-style:oblique;
	}
	canvas {
		cursor:none;
	}

aside {
	position: absolute;
  color: black;
  text-align: right;
  bottom:0;
  right:0;
  padding: 5px 25px;
  background: rgba(255,255,255,0.8);
}
h1 {
  font-weight: normal;
  font-size:20px;
  line-height: 10px;
}
h2,p {
  color:#666;
  font-weight: normal;
  font-size:13px;
}
/*!
 *
 * Author:      Gianluca Guarini
 * Contact:     [email protected]
 * Website:     http://www.gianlucaguarini.com/
 * Twitter:     @gianlucaguarini
 *
 * Copyright (c) 2013 Gianluca Guarini
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 **/

var canvas = document.querySelectorAll('canvas')[0],
	ctx = canvas.getContext('2d'),
	arrows = [],
	ARROWS_GRID = 40;
// requestAnimationFrame polyfill
(function() {
  var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||                      window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  window.requestAnimationFrame = requestAnimationFrame;
})();

// Mouse Class to get the mouse coordinates
var Mouse = function (el) {
	// Public Vars
	this.el		= el || window;
	this.x		= 0;
	this.y		= 0;

	/*
	*
	* Private Internal Methods
	*
	*/
	var _getPointerEvent = function(event) {
		return event.targetTouches ? event.targetTouches[0] : event;
	};
	/*
	*
	* Set the x and y values of this class according to the mouse coordinates givent to the event object
	*
	*/

	var _setMouseCoordinates = function ( e ) {

		e.preventDefault();
		var pointer = _getPointerEvent(e),
			x = pointer.pageX,
			y = pointer.pageY;

		this.x = x;
		this.y = y;
	};

	
	var events = "mousernter mousemove touchstart touchenter touchmove";

	// bind events
	events.split(' ').forEach(function(eventName){
		this.el.addEventListener(eventName,_setMouseCoordinates.bind(this))
	})

	return this;
}();
// Arrow Class https://github.com/lamberta/html5-animation/blob/master/examples/ch05/classes/arrow.js
var Arrow = function (o) {
	this.x = o.x | 0;
	this.y = o.y | 0;
	this.color = o.color || "#ffffff";
	this.rotation = o.rotation | 0;
	this.draw = function () {
		ctx.save();
		ctx.translate(this.x, this.y);
		ctx.rotate(this.rotation);
		ctx.lineWidth = 1;
		ctx.fillStyle = this.color;
		ctx.beginPath();
		ctx.moveTo(-10, -5);
		ctx.lineTo(0, -5);
		ctx.lineTo(0, -10);
		ctx.lineTo(10, 0);
		ctx.lineTo(0, 10);
		ctx.lineTo(0, 5);
		ctx.lineTo(-10, 5);
		ctx.lineTo(-10, -5);
		ctx.closePath();
		ctx.fill();
		ctx.stroke();
		ctx.restore();
	};
};
/*
*
* Set the viewport size let's make it fullscreen!
*
*/
var setViewport = function () {
	canvas.width = window.innerWidth;
	canvas.height = window.innerHeight;
	createParticles();
};
/*
*
* Make all the arrows
*
*/
var createParticles = function () {
	arrows = [];
	var ROWS = canvas.width / ARROWS_GRID,
		COLS = canvas.height / ARROWS_GRID;
	for (var x = 0; x < ROWS; x++) {
		for (var y = 0; y < COLS; y++){
			arrows.push(new Arrow({
				x:x * ARROWS_GRID,
				y:y * ARROWS_GRID
			}));
		}
	}
};
/*
*
* Rock and roll baby!
*
*/
var loop = function (){
	render();
	window.requestAnimationFrame(loop);
};
/*
*
* Draw the arrows and clean the canvas
*
*/
var render = function () {
	ctx.clearRect(0,0,canvas.width,canvas.height);
	[].forEach.call(arrows,function(arrow){
		arrow.rotation = Math.atan2(Mouse.y - arrow.y,Mouse.x - arrow.x);
		arrow.draw();
	});
};

// Init this shit
setViewport();
createParticles();
loop();

// UI Events
window.addEventListener('resize',setViewport,false);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.