Заводной попутный ветер
При разработке страницы сведений для проектов, над которыми я работал (доступной на странице моего портфолио), я также реализовал простые анимированные аналоговые часы, которые отображаются рядом с продолжительностью проекта.
Поскольку я не хотел использовать какие-либо новые внешние библиотеки или видео, я решил реализовать часы через Tailwind.css и его отличные утилиты для анимации.
Примеры кода
Больше нечего сказать, так как я подумал, что для вас будет наиболее полезно, когда я просто предоставлю несколько примеров кода для повторного использования.
Компоновка в каждом примере почти одинакова или очень похожа. Я просто визуализирую некоторые блоки div с помощью абсолютного позиционирования друг над другом. Поскольку каждое поле имеет наименьшую доступную ширину, они выглядят как курсоры, видимые на часах.
Последний пример демонстрирует, как начать с 12 часов. Первые два примера начинаются с 3 часов, как они расположены в ряду.
Пример 1: Самые простые часы
export function Clock() {
return (
<div className="flex justify-center py-10 group">
<div className="relative flex items-center justify-end w-20 h-20 overflow-hidden bg-gray-900 rounded-full ">
<div className="absolute w-1/2 h-1 bg-white rounded-full origin-left -rotate-12 group-hover:rotate-[215deg] duration-1000 ease-in-out" />
<div className="absolute w-1/2 h-1 origin-left rotate-[70] group-hover:rotate-[340deg] duration-1000 ease-in-out">
<div className="w-2/3 h-full bg-white rounded-full" />
</div>
<div className="absolute flex justify-center flex-1 w-full">
<div className="w-1 h-1 bg-white rounded-full" />
</div>
</div>
</div>
);
}
Пример 2: часы с рамкой и индикаторами
import React from "react";
// Note that I'm using 'clsx' for
// composing classnames.
import clsx from "clsx";
export function Clock() {
return (
<div className="relative flex items-center justify-end w-20 h-20 overflow-hidden rounded-full ring-gray-600 ring-1">
{Array.from({ length: 8 }, (_, i) => (
<div
key={i}
style={{ height: 1 }}
className={clsx("absolute w-1/2 origin-left flex justify-end", {
"rotate-0": i === 0,
"rotate-45": i === 1,
"rotate-90": i === 2,
"rotate-[135deg]": i === 3,
"rotate-180": i === 4,
"rotate-[225deg]": i === 5,
"rotate-[270deg]": i === 6,
"rotate-[315deg]": i === 7,
})}>
<div className="w-1/3 h-full bg-gray-600 rounded-full" />
</div>
))}
<div className="absolute w-1/2 h-1 bg-gray-300 rounded-full origin-left -rotate-12 group-hover:rotate-[215deg] duration-1000 ease-in-out" />
<div className="absolute w-1/2 h-1 origin-left rotate-[85deg] group-hover:rotate-[340deg] duration-1000 ease-in-out">
<div className="w-2/3 h-full bg-gray-300 rounded-full" />
</div>
<div className="absolute flex justify-center flex-1 w-full">
<div className="w-1 h-1 bg-gray-300 rounded-full" />
</div>
</div>
);
}
Пример 3: часы, начинающиеся в полночь
export function Clock() {
return (
<div className="flex justify-center py-10 group">
<div className="relative flex flex-col items-center justify-start w-20 h-20 overflow-hidden bg-gray-900 rounded-full ">
<div className="absolute w-1 duration-1000 ease-in-out origin-bottom bg-gradient-to-t from-white to-red-400 rounded-full h-1/2 group-hover:rotate-[200deg]" />
<div className="absolute h-1/2 w-1 origin-bottom rotate-[55deg] group-hover:rotate-[340deg] duration-1000 ease-in-out flex flex-col justify-end">
<div className="w-full rounded-full bg-gradient-to-t from-white to-blue-400 h-2/3" />
</div>
<div className="absolute flex items-center justify-center flex-1 w-full h-full">
<div className="w-1 h-1 bg-white rounded-full" />
</div>
</div>
</div>
);
}