Added logo animation

This commit is contained in:
AlacrisDevs
2026-05-02 18:32:07 +03:00
parent e2c3ec5b8a
commit 8a715cd5c3
11 changed files with 159 additions and 34 deletions

View File

@@ -135,3 +135,36 @@ body {
.material-symbols-outlined {
font-variation-settings: 'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 24;
}
.tipilan-logo-letter {
animation: tipilan-logo-letter-in 720ms cubic-bezier(0.16, 1, 0.3, 1) both;
animation-delay: var(--tipilan-logo-letter-delay, 0ms);
opacity: 0;
transform: translate3d(0, 100%, 0);
will-change: opacity, transform;
}
@keyframes tipilan-logo-letter-in {
0% {
opacity: 0;
transform: translate3d(0, 100%, 0);
}
70% {
opacity: 1;
}
100% {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@media (prefers-reduced-motion: reduce) {
.tipilan-logo-letter {
animation: none;
opacity: 1;
transform: none;
will-change: auto;
}
}

View File

@@ -0,0 +1,84 @@
"use client";
import Image from "next/image";
import type { AnimationEvent, CSSProperties } from "react";
import { useEffect, useState } from "react";
const LOGO_WIDTH = 2092;
const LOGO_HEIGHT = 300;
const logoLetters = [
{ letter: "T", src: "/letters/T.svg", x: 0, width: 367 },
{ letter: "I", src: "/letters/I.svg", x: 334.858, width: 178 },
{ letter: "P", src: "/letters/P.svg", x: 481.258, width: 411 },
{ letter: "I", src: "/letters/I.svg", x: 872.218, width: 178 },
{ letter: "L", src: "/letters/L.svg", x: 1018.64, width: 286 },
{ letter: "A", src: "/letters/A.svg", x: 1289.2, width: 390 },
{ letter: "N", src: "/letters/N.svg", x: 1690.72, width: 402 },
] as const;
export default function AnimatedTipilanLogo() {
const [isAnimationComplete, setIsAnimationComplete] = useState(false);
useEffect(() => {
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
setIsAnimationComplete(true);
}
}, []);
if (isAnimationComplete) {
return (
<Image
src="/tipilan-dark.svg"
width={LOGO_WIDTH}
height={LOGO_HEIGHT}
alt="TipiLAN Logo"
priority
className="relative z-0 w-[max(260px,min(100%,750px))] h-auto"
/>
);
}
return (
<div
aria-label="TipiLAN Logo"
className="relative z-0 w-[max(260px,min(100%,750px))] overflow-visible"
role="img"
style={{ aspectRatio: `${LOGO_WIDTH} / ${LOGO_HEIGHT}` }}
>
{logoLetters.map((letter, index) => {
const isLastLetter = index === logoLetters.length - 1;
return (
<Image
key={`${letter.letter}-${letter.x}`}
src={letter.src}
width={letter.width}
height={LOGO_HEIGHT}
alt=""
aria-hidden
priority
className="tipilan-logo-letter absolute top-0 h-full object-fill"
onAnimationEnd={
isLastLetter
? (event: AnimationEvent<HTMLImageElement>) => {
if (event.animationName === "tipilan-logo-letter-in") {
setIsAnimationComplete(true);
}
}
: undefined
}
style={
{
left: `${(letter.x / LOGO_WIDTH) * 100}%`,
width: `${(letter.width / LOGO_WIDTH) * 100}%`,
zIndex: logoLetters.length - index,
"--tipilan-logo-letter-delay": `${index * 90}ms`,
} as CSSProperties
}
/>
);
})}
</div>
);
}

View File

@@ -1,5 +1,6 @@
import Image from "next/image";
import { Link } from "@/i18n/routing";
import AnimatedTipilanLogo from "@/components/AnimatedTipilanLogo";
import { vipnagorgialla } from "@/components/Vipnagorgialla";
import { useTranslations } from "next-intl";
@@ -23,14 +24,8 @@ export default function HeroSection() {
<div className="relative h-full grid grid-cols-1 md:grid-cols-[3fr_2fr] items-center gap-8 px-8 md:px-12">
{/* Left: logo + info + CTA */}
<div className="flex flex-col gap-5">
<Image
src="/tipilan-dark.svg"
width={750}
height={106}
alt="TipiLAN Logo"
className="w-[max(260px,min(100%,750px))] h-auto"
/>
<div className={`${vipnagorgialla.className} font-bold italic`}>
<AnimatedTipilanLogo />
<div className={`${vipnagorgialla.className} relative z-10 font-bold italic`}>
<p className="text-[clamp(1.1rem,0.9rem+1vw,1.75rem)] text-[#00A3E0] uppercase tracking-wide">
{t("hero.date")}
</p>
@@ -40,7 +35,7 @@ export default function HeroSection() {
</div>
<Link
href="/piletid"
className={`self-start px-6 py-3 bg-[#007CAB] hover:bg-[#00A3E0] text-[#EEE5E5] ${vipnagorgialla.className} font-bold italic text-[clamp(1rem,0.8rem+0.8vw,1.5rem)] uppercase transition`}
className={`relative z-10 self-start px-6 py-3 bg-[#007CAB] hover:bg-[#00A3E0] text-[#EEE5E5] ${vipnagorgialla.className} font-bold italic text-[clamp(1rem,0.8rem+0.8vw,1.5rem)] uppercase transition`}
>
{t("hero.buyTicket")}
</Link>