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();
//...