components/analog-clock.tsx
"use client";
import { useEffect, useState } from "react";
const SIZE = 180;
export function AnalogClock() {
const [clockRotation, setClockRotation] = useState({
hour: 0,
minute: 0,
second: 0,
});
const handleClock = () => {
const currentDate = new Date();
const currentHour = currentDate.getHours() % 12;
const currentMinute = currentDate.getMinutes();
const currentSecond = currentDate.getSeconds();
setClockRotation({
hour: currentHour * 30 + currentMinute * 0.5,
minute: currentMinute * 6 + currentSecond * 0.1,
second: currentSecond * 6,
});
};
useEffect(() => {
handleClock();
const intervalId = setInterval(handleClock, 1000);
return () => {
clearInterval(intervalId);
};
}, []);
return (
<div
className="rounded-full bg-gray-50 relative"
style={{ width: SIZE, height: SIZE }}
>
<div>
<div
className="bg-accent-orange w-1.5 h-12 absolute origin-[50%_100%]"
style={{
rotate: `${+clockRotation.hour}deg`,
left: SIZE / 2 - 3,
bottom: SIZE / 2,
}}
></div>
<div
className="bg-black w-0.5 h-[72px] absolute origin-bottom"
style={{
rotate: `${+clockRotation.minute}deg`,
left: SIZE / 2 - 1,
bottom: SIZE / 2,
}}
></div>
<div
className="bg-black w-px h-24 absolute origin-[center_calc(100%-16px)] left-1/2"
style={{
rotate: `${+clockRotation.second}deg`,
left: SIZE / 2 - 0.5,
bottom: SIZE / 2 - 16,
}}
></div>
<div className="size-2 bg-background border rounded-full absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"></div>
</div>
<div>
{Array.from({ length: 60 }).map((_, i) => (
<div
key={i}
className="w-px h-1 absolute left-1/2 bg-gray-500 -translate-x-1/2 nth-of-type-[5n]:h-2 nth-of-type-[5n]:bg-gray-900"
style={{
transform: `rotate(${6 * (i + 1)}deg)`,
transformOrigin: `50% ${SIZE / 2}px`,
}}
></div>
))}
</div>
</div>
);
}