DEMO: https://df2y4.csb.app/

GitHub: https://github.com/dejavu1987/react-svg-clock

This blog post is an exercise from my previous blog post Introduction to Polar Coordinates, plotting on radial diagrams. If you have not read the post and have no idea how radial coordinates work. Please go to the post and read and come back. If you are confident, lets go build a Clock.

We will start with a simple React component Clock. It has 2 states, hour, min and sec, which will be set to current time every second.

import { useState } from "react";
import "./styles.css";

import useInterval from "./useInterval";

export default function Clock() {
  const [hour, setHour] = useState(0);
  const [min, setMin] = useState(0);
  const [sec, setSec] = useState(0);

  useInterval(() => {
    const now = new Date();

    const m = now.getMinutes();
    const h = now.getHours();
    const s = now.getSeconds();
    
    setHour(h > 11 ? h - 12 : h);
    setMin(m);
    setSec(s);
    
  }, 1000);


  return (
    

React SVG Clock

Polar coordinates fundamentals

Hour: {hour}, Minutes: {min}, Seconds: {sec}

); }

useTimeout() is a custom React hook that will call the callback function every given delay.

import useInterval from "./useInterval";
 
 
+const getAngleFromRatio = (ratio: number): number => {
+  return ratio * 2 * Math.PI;
+};
+
 export default function Clock() {
   const [hour, setHour] = useState(0);
   const [min, setMin] = useState(0);
   const [sec, setSec] = useState(0);
 
+  const [hourAngle, setHourAngle] = useState(0);
+  const [minAngle, setMinAngle] = useState(0);
+  const [secAngle, setSecAngle] = useState(0);
+
 
   useInterval(() => {
     const now = new Date();
@@ -20,6 +28,10 @@ export default function Clock() {
     setHour(h > 11 ? h - 12 : h);
     setMin(m);
     setSec(s);
+
+    setHourAngle(getAngleFromRatio(h / 12));
+    setMinAngle(getAngleFromRatio(m / 60));
+    setSecAngle(getAngleFromRatio(s / 60));
     
   }, 1000);
 
@@ -33,6 +45,9 @@ export default function Clock() {
       

Hour: {hour}, Minutes: {min}, Seconds: {sec}

+ {hourAngle} + {minAngle} + {secAngle}