snail shell clock

by asteriskman

HTML

<canvas id='cmain' width='800' height='700'></canvas>
<img id='img_snail' class='img_hidden'...

CSS

body {
  background: black;
}

canvas {
  background: white;
}

.img_hidden {
  display: none;
}

JavaScript

const canvas = document.getElementById('cmain');
const ctx = canvas.getContext('2d');
const snailImage = document.getElementById('img_snail');

function textAtPointAndAngle(context, x, y, angle, text, scale) {
  //draw centered, stroked text at x,y at angle
  context.save();
  
  context.fillStyle = '#afcf84';
  context.textAlign = 'center';
  context.translate(x, y);
  context.scale(scale, scale);
  context.rotate(-angle);
  context.lineWidth = 3;
  context.strokeText(text, 0, 0);
  context.fillText(text, 0, 0);  
  context.restore();
}

function getSpiralPos(a,b,theta) {
  //get position on logarithmic spiral with constants a and b and angle theta
  let r = a * Math.exp(b * theta);
  let x = r * Math.cos(theta);
  let y = r * Math.sin(theta);
  return [x, y, r];
}

function dateToText(displayDate) {
    let hour = displayDate.getHours() % 12;
    if (hour === 0) {hour = 12;}
    //if (hour < 10) {hour = `0${hour}`;}
    let minute = displayDate.getMinutes();
    if (minute < 10) {minute = `0${minute}`;}
    return [`${hour}:${minute}`, minute];
}

function draw() {
  //ctx.clearRect(0,0,canvas.width,canvas.height);
  ctx.drawImage(snailImage, 0, 0);
  let a = 0.5;
  let b = 0.2;
  let x = 0;
  let y = 0;
  let thetaFinal = 10.0 * Math.PI; //controls # of time around spiral
  ctx.save();
  ctx.translate(156,302); //place center of spiral in correct spot
  ctx.beginPath();
  //draw sprial path
  for (let theta = 0; theta <= thetaFinal; theta += Math.PI / 32) {
    let [newX, newY] = getSpiralPos(a, b, theta);
    ctx.lineTo(newX,newY);
  }
  
  let msToNextMinute = 60000 - new Date().getTime() % 60000
  let t = -Math.PI/4 * msToNextMinute / 60000
  
  let mCount = 1;
  let hourLines = [];
  //draw spiral lines and times
  for (let d = 0; d <= thetaFinal * 10; d += Math.PI/4) {
    //thetaFinal is 0 seconds away from now and 0 is infinite seconds away
    let theta = thetaFinal * thetaFinal / ((d-t) + thetaFinal);

    //start and end of minute line
    let...