<div id="app"></div>
main {
--alpha: #0d0d0d;
--beta: #2d2d2d;
--gamma: #3d3d3d;
--delta: #fafafa;
--sigma: #fa0000;
font-family: sans-serif;
min-height: 100dvh;
display: grid;
place-items: center;
background: var(--alpha);
color: var(--delta);
}
.clock {
position: relative;
width: min(95vmax, 400px);
aspect-ratio: 1;
background: var(--gamma);
border-radius: 50%;
border: 20px solid var(--beta);
rotate: -90deg;
.hand {
position: absolute;
top: 50%;
left: 50%;
translate: 0% -50%;
transform-origin: left;
box-shadow: 2px 2px 5px var(--beta);
&.hour {
width: 30%;
height: 6px;
background: var(--delta);
}
&.min {
width: 40%;
height: 4px;
background: var(--delta);
}
&.sec {
width: 40%;
height: 2px;
background: var(--sigma);
}
}
}
View Compiled
/*
* https://frontendeval.com/questions/analog-clock
*
* Create an analog clock with hour, minute, and second hands. Each of the hands should be accurate to the browser's local timezone and update once per second.
*/
const Clock = ({ tz = "Asia/Kolkata" }) => {
const getTime = (timeZone) => {
const t = new Intl.DateTimeFormat(
{},
{
timeZone,
hour: "numeric",
minute: "numeric",
second: "numeric",
hourCycle: "h11"
}
).formatToParts();
const obj = t.reduce((acc, curr) => {
return { acc, [curr.type]: +curr.value };
}, {});
const { hour, minute: min, second: sec, rest } = obj;
return { hour, min, sec };
};
const getKeyframes = (value) => {
const start = value * 30;
const end = start + 360;
return [
{ transform: `rotate(${start}deg)` },
{ transform: `rotate(${end}deg)` }
];
};
const hourRef = React.useRef(null);
const minRef = React.useRef(null);
const secRef = React.useRef(null);
React.useEffect(() => {
if (hourRef.current && minRef.current && secRef.current) {
const time = getTime(tz);
const animOptions = {
iterations: Infinity,
easing: "steps(60, end)"
};
hourRef.current.animate(getKeyframes(time.hour), {
animOptions,
duration: 3600000 * 60
});
minRef.current.animate(getKeyframes(time.min), {
animOptions,
duration: 3600000
});
secRef.current.animate(getKeyframes(time.sec), {
animOptions,
duration: 60000
});
}
}, [hourRef, minRef, secRef]);
return (
<aside className="clock">
<div className="hand hour" ref={hourRef}></div>
<div className="hand min" ref={minRef}></div>
<div className="hand sec" ref={secRef}></div>
</aside>
);
};
const App = () => {
const TIME_ZONES = ["Asia/Kolkata", "Australia/Sydney", "America/New_York"];
return (
<main>
{TIME_ZONES.map((tz) => (
<div key={`clock-${tz}`}>
<h2>{tz}</h2>
<Clock tz={tz} />
</div>
))}
</main>
);
};
ReactDOM.render(<App />, document.getElementById("app"));
View Compiled
This Pen doesn't use any external CSS resources.