Draw a clock with sin/cos

Date: 2022-05-16
const on = (el, ev, fn) => el.addEventListener(ev, fn, { passive: true });
const $ = (selector, el) => (el || document).querySelector(selector);

on(document, 'DOMContentLoaded', () => {
	const canvas = $('#my-canvas');
	const context = canvas.getContext('2d');
	const half_width = canvas.width / 2;
	const half_height = canvas.height / 2;
	const clock_radius = Math.min(half_width, half_height) * 0.85;

	function drawLine(x1, y1, x2, y2) {
		context.beginPath();
		context.moveTo(x1 + half_width, y1 + half_height);
		context.lineTo(x2 + half_width, y2 + half_height);
		context.stroke();
	};

	function putText(x, y, text) {
		context.font = "18px Arial";
		context.textAlign = "center"; 
		context.fillText(text, x + half_width, y + half_height);
	};

	function clock() {
        context.clearRect(0, 0, canvas.width, canvas.height);
		const count = 12
        const pi2 = 2 * Math.PI;

		for (let r = 0; r < count; r++) {
			const angle = r * (pi2 / 12);
			
			const x = Math.sin(angle) * clock_radius;
			const y = -Math.cos(angle) * clock_radius;
			
			const nextX = Math.sin(angle) * (clock_radius / 1.1);
			const nextY = -Math.cos(angle) * (clock_radius / 1.1);
			
			const textX = Math.sin(angle) * (clock_radius * 1.1);
			const textY = -Math.cos(angle) * (clock_radius * 1.1);

			drawLine(x, y, nextX, nextY);
			putText(textX, textY + 7, (r || 12).toString());
		};
		
		const parts = 24 * 10;
		for (let r = 0; r < parts; r++) {
			const angle = r * (pi2 / parts);
			
			const x = Math.sin(angle) * clock_radius;
			const y = -Math.cos(angle) * clock_radius;
			
			const nextAngle = (r + 1) * pi2 / parts;
			const nextX = Math.sin(nextAngle) * clock_radius;
			const nextY = -Math.cos(nextAngle) * clock_radius;
			drawLine(x, y, nextX, nextY);
		};

        // draw hour/minute lines
        const now = new Date();
        const hoursWithDecimals = now.getHours() + (now.getMinutes() / 60);
        const minutes = now.getMinutes();
        const seconds = now.getSeconds() + (now.getMilliseconds() / 1000);

        function drawHours() {
            const angle = hoursWithDecimals * (pi2 / 12)
            const x = Math.sin(angle) * (clock_radius / 2);
            const y = -Math.cos(angle) * (clock_radius / 2);
            drawLine(0, 0, x, y);
        }
        
        function drawMinutes() {
            const angle = minutes * (pi2 / 60)
            const x = Math.sin(angle) * (clock_radius / 1.2);
            const y = -Math.cos(angle) * (clock_radius / 1.2);
            drawLine(0, 0, x, y);
        }

        function drawSeconds() {
            const angle = seconds * (pi2 / 60)
            const x = Math.sin(angle) * (clock_radius / 1.05);
            const y = -Math.cos(angle) * (clock_radius / 1.05);
            drawLine(0, 0, x, y);
        }

        drawHours();
        drawMinutes();
        drawSeconds();
	};

    const fps = 10;
    const fpsInterval = 1000 / fps;
    let then;
    function step(now) {
        window.requestAnimationFrame(step);
        if (then === undefined) {
            then = now;
        }
        const elapsed = now - then;
        if (elapsed > fpsInterval) {
            // Get ready for next frame by setting then=now, but also adjust for your
            // specified fpsInterval not being a multiple of RAF's interval (16.7ms)
            then = now - (elapsed % fpsInterval);
            clock();
        }
      }
    window.requestAnimationFrame(step);
	// setInterval(() => clock(), 20);
});
61770cookie-checkDraw a clock with sin/cos