Compass

by Arjan Haverkamp

HTML

<canvas id="canvas"></canvas>

JavaScript

const Compass = (() => {
	let SIZE = 300, fontSize = 32, fontFamily = 'sans-serif';
	let canvas, ctx, heading = 0;

	const calcAngle = (x, a, b) => {
		let degree = (a - b) * x + b;
		return (degree * Math.PI) / 180;
	}




	const init = el => {
		canvas = el, ctx = canvas.getContext('2d');
		canvas.width = canvas.height = SIZE;
		render()
	}
	
function drawTicks(ctx) {
var centerX = SIZE/2, centerY = SIZE/2;
var clockWidth = SIZE-20;
var nr = 48;
	var i = nr;
	ctx.strokeStyle = "red";
	ctx.lineWidth = 2;
	while(i > 0) {
		ctx.save();
		ctx.beginPath();
		ctx.translate(centerX, centerY);
		ctx.rotate((i * 360/nr) * Math.PI/180);
		ctx.translate(0, -clockWidth/2);

		ctx.moveTo(0, 0);
		ctx.lineTo(0, 10);
		ctx.stroke();
		ctx.closePath();
		ctx.restore();
		i--;
	}
}
	
	
	const render = () => {
		// Background circle
		ctx.fillStyle = '#000'
		ctx.arc(SIZE/2, SIZE/2, SIZE/2-10, 0, 2 * Math.PI);
		ctx.fill();
      
		// Faint circle around central speed
		ctx.beginPath();
		ctx.strokeStyle = '#555';
		ctx.lineWidth = 8;
		ctx.arc(SIZE/2, SIZE/2, 94, 0, 2 * Math.PI);
		ctx.stroke();

		drawTicks(ctx)
		
		// N, E, S, W
		ctx.fillStyle = '#fff';
		ctx.font = '700 ' + fontSize + 'px ' + fontFamily;
		ctx.textAlign = 'center';

		ctx.textBaseline = 'top';
		ctx.fillText('N', SIZE/2, fontSize/1.5);
		
		ctx.fillText('S', SIZE/2, SIZE - fontSize - fontSize/2);

		ctx.textBaseline = 'middle';
		ctx.textAlign = 'center';
		
		// West
		ctx.save();
 		ctx.translate(0, SIZE/2);
 		ctx.rotate(-Math.PI/2);
 		ctx.fillText('W', 0, fontSize + 8);
 		ctx.restore();		
		
		// East
		ctx.save();
 		ctx.translate(0, SIZE/2);
 		ctx.rotate(Math.PI/2);
 		ctx.fillText('E', 0, -SIZE + fontSize + 8);
 		ctx.restore();
		
		ctx.fillStyle = '#999';
		ctx.font = '400 ' + (fontSize/2) + 'px ' + fontFamily;			

		// NW
		ctx.save();
		ctx.translate(SIZE/2, SIZE/2);
		ctx.rotate((-45 * Math.PI) / 180);
 		ctx.fillText('NW', 0, -115);
 		ctx.restore();
		
		//...