Простые анимированные аналоговые часы в Tailwind.css

Как создать очень простые аналоговые часы с анимацией только в Tailwind.css

Заводной попутный ветер

При разработке страницы сведений для проектов, над которыми я работал (доступной на странице моего портфолио), я также реализовал простые анимированные аналоговые часы, которые отображаются рядом с продолжительностью проекта.

Поскольку я не хотел использовать какие-либо новые внешние библиотеки или видео, я решил реализовать часы через Tailwind.css и его отличные утилиты для анимации.

Примеры кода

Больше нечего сказать, так как я подумал, что для вас будет наиболее полезно, когда я просто предоставлю несколько примеров кода для повторного использования.

Компоновка в каждом примере почти одинакова или очень похожа. Я просто визуализирую некоторые блоки div с помощью абсолютного позиционирования друг над другом. Поскольку каждое поле имеет наименьшую доступную ширину, они выглядят как курсоры, видимые на часах.

Последний пример демонстрирует, как начать с 12 часов. Первые два примера начинаются с 3 часов, как они расположены в ряду.

Пример 1: Самые простые часы

Image dbead4b8e463

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: часы с рамкой и индикаторами

Image 06597167696f

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: часы, начинающиеся в полночь

Image c2d6bdde9e1e

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>
  );
}