All components

Animated Frameworks

Animated Frameworks is a React and Tailwind CSS component from Eldora UI, licensed MIT. Copy it and paste it into your project.

Eldora UI MIT other

What it is

Animated Frameworks is a React and Tailwind CSS component from Eldora UI, licensed MIT. Copy it and paste it into your project.

How to use it

Open it in the catalogue, press copy, and paste it into your project. The prompt you copy carries the code and the rules that tell your agent to reproduce it without changing anything.

Open in the catalogue

Five free copies a month. No card.

Needs

npm i motion react

Licence

This component comes from Eldora UI and is redistributed under the MIT licence, which permits commercial use. The copyright notice travels with the code.

Animated Frameworks

registry/eldoraui/animated-frameworks.tsx
"use client"

import { useEffect, useState } from "react"

import { cn } from "@/lib/utils"
import { Icons } from "@/components/icons"

type AnimatedFrameworksProps = {
  cardTitle?: string
  cardDescription?: string
}

const AnimatedFrameworks = ({
  cardTitle = "Universal Compatibility",
  cardDescription = "Works seamlessly with Next.js, React, HTML, Apple, GitHub, OpenAI, and more fits everywhere.",
}: AnimatedFrameworksProps) => {
  return (
    <div
      className={cn(
        "relative",
        "flex flex-col justify-between",
        "h-[20rem] space-y-4",
        "rounded-md border bg-white shadow-sm",
        "dark:border-neutral-800/50 dark:bg-[#171717]",
        "border-neutral-200"
      )}
    >
      <FrameworkCard />
      <div className="px-4 pb-4">
        <div className="text-sm font-semibold text-neutral-900 dark:text-white">
          {cardTitle}
        </div>
        <div className="mt-2 text-xs text-neutral-600 dark:text-neutral-400">
          {cardDescription}
        </div>
      </div>
    </div>
  )
}

export default AnimatedFrameworks

const FrameworkCard = () => {
  const [nextJsTransform, setNextJsTransform] = useState("none")
  const [reactTransform, setReactTransform] = useState("none")
  const [htmlTransform, setHtmlTransform] = useState("none")

  useEffect(() => {
    const cycleAnimations = async () => {
      const upStyle = "translateY(-3.71px) rotateX(10.71deg) translateZ(20px)"
      const downStyle = "none"

      const transitionDuration = 1100

      const durationOfUpState = 1200
      const delayBetweenCards = 600

      while (true) {
        setReactTransform(upStyle)
        await new Promise((resolve) => setTimeout(resolve, durationOfUpState))
        setReactTransform(downStyle)
        await new Promise((resolve) =>
          setTimeout(resolve, transitionDuration + delayBetweenCards)
        )

        setNextJsTransform(upStyle)
        await new Promise((resolve) => setTimeout(resolve, durationOfUpState))
        setNextJsTransform(downStyle)
        await new Promise((resolve) =>
          setTimeout(resolve, transitionDuration + delayBetweenCards)
        )

        setHtmlTransform(upStyle)
        await new Promise((resolve) => setTimeout(resolve, durationOfUpState))
        setHtmlTransform(downStyle)
        await new Promise((resolve) =>
          setTimeout(resolve, transitionDuration + delayBetweenCards)
        )
      }
    }

    cycleAnimations()
  }, [])

  const cardClasses =
    "flex aspect-square items-center justify-center rounded-md border bg-gradient-to-b from-neutral-50 to-neutral-100 p-4 " +
    "dark:border-neutral-800 dark:from-[#272727] dark:to-[#3d3d3d] " +
    "border-neutral-300 shadow-[0_8px_30px_rgb(0,0,0,0.12)] " +
    "[@media(min-width:320px)]:h-20 [@media(min-width:500px)]:h-36 " +
    "transition-transform duration-1000 ease-out will-change-transform"

  return (
    <>
      <div
        className={cn(
          "relative",
          "flex flex-col items-center justify-center gap-1",
          "h-[14.5rem] w-full"
        )}
      >
        <div className="absolute flex h-full w-full items-center justify-center">
          <div className="h-full w-[15rem]">
            <svg
              className="h-full w-full"
              width="100%"
              height="100%"
              viewBox="0 0 100 100"
              fill="none"
            >
              <g
                stroke="currentColor"
                strokeWidth="0.1"
                className="text-neutral-400 dark:text-neutral-600"
              >
                <path d="M 1 0 v 5 q 0 5 5 5 h 39 q 5 0 5 5 v 71 q 0 5 5 5 h 39 q 5 0 5 5 v 5" />
              </g>
              <g mask="url(#framework-mask)">
                <circle
                  className="frameworkline framework-line"
                  cx="0"
                  cy="0"
                  r="12"
                  fill="url(#framework-blue-grad)"
                />
              </g>
              <defs>
                <mask id="framework-mask">
                  <path
                    d="M 1 0 v 5 q 0 5 5 5 h 39 q 5 0 5 5 v 71 q 0 5 5 5 h 39 q 5 0 5 5 v 5"
                    strokeWidth="0.3"
                    stroke="white"
                  />
                </mask>
                <radialGradient id="framework-blue-grad" fx="1">
                  <stop offset="0%" stopColor={"#3b82f6"} />
                  <stop offset="100%" stopColor="transparent" />
                </radialGradient>
              </defs>
            </svg>
          </div>
        </div>
        <div
          className={cn(
            "flex items-center justify-center gap-4",
            "[perspective:1000px] [transform-style:preserve-3d]"
          )}
        >
          <div className={cardClasses} style={{ transform: reactTransform }}>
            <Icons.apple className="size-6 text-neutral-700 dark:text-neutral-100 [@media(min-width:500px)]:size-9" />
          </div>
          <div className={cardClasses} style={{ transform: nextJsTransform }}>
            <Icons.gitHub className="size-6 text-neutral-700 dark:text-neutral-100 [@media(min-width:500px)]:size-9" />
          </div>
          <div className={cardClasses} style={{ transform: htmlTransform }}>
            <Icons.openai className="size-6 text-neutral-700 dark:text-neutral-100 [@media(min-width:500px)]:size-9" />
          </div>
        </div>

        <div className="absolute bottom-0 left-0 h-3 w-full bg-gradient-to-t from-white to-transparent dark:from-[#171717]" />
      </div>
    </>
  )
}

Similar components