music and animation system

This commit is contained in:
2026-03-13 15:49:53 +01:00
parent 4916a2fc7b
commit 166ae50c49
24 changed files with 785 additions and 15 deletions

70
src/app/music/page.tsx Normal file
View File

@@ -0,0 +1,70 @@
'use client'
import { useGSAP } from "@gsap/react";
import { useRef } from "react";
import { trpc } from "~/app/_trpc/Client";
import * as Card from "~/components/ui/card";
import { useGsapContext } from "../_providers/GsapProvicer";
import AnimatedPageTitle from "../_components/Animated/AnimatedPageTitle";
import { Spinner } from "~/components/ui/spinner";
import AnimateTextIn from "../_components/Animated/AnimateIn";
import gsap from 'gsap'
export default function MusicPage() {
const { data: tracks, isLoading } = trpc.music.list.useQuery();
const container = useRef<HTMLDivElement>(null)
const gsapContext = useGsapContext();
useGSAP(() => {
gsapContext?.resetTimeline()
const items = gsap.utils.toArray<HTMLElement>('.gsapan');
const tl = gsap.timeline();
items.map(item => {
const player = item.querySelector('.player');
tl.from(
item, { x: -100, opacity: 0, duration: 0.5, ease: 'power2.inOut', scrollTrigger: item },'<'
).from(
player, { y: 10, opacity: 0, duration: 0.5, ease: 'power2.inOut' }
, '<0.3')
gsapContext?.addAnimation(tl);
})
}, { scope: container, dependencies: [isLoading] });
return (<>
<div ref={container} className="w-full h-full max-w-4xl mx-auto px-4 py-8 flex flex-col gap-4">
<AnimatedPageTitle text="Just Some Music I Made"/>
<AnimateTextIn>
<div className="flex flex-row h-8 content-center items-center">
<p className="mr-[1em]">All works on this page are licensed under:</p>
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
<img className="max-w-[1em] ml-[1em]" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt=""/>
<img className="max-w-[1em] ml-[1em]" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt=""/>
<img className="max-w-[1em] ml-[1em]" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" alt=""/>
<img className="max-w-[1em] ml-[1em]" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt=""/>
</div>
</AnimateTextIn>
{tracks && tracks.map((track) => (
<Card.Card key={track.id} className='gsapan'>
<Card.CardHeader>
<AnimateTextIn animation="slide">
<Card.CardTitle>{track.title}</Card.CardTitle>
</AnimateTextIn>
</Card.CardHeader>
<Card.CardContent className="flex flex-col gap-3">
{track.description && (
<p className="text-sm text-muted-foreground gsapant">{track.description}</p>
)}
<audio controls className="w-full player" src={track.fileUrl}>
Your browser does not support the audio element.
</audio>
</Card.CardContent>
</Card.Card>
))}
{!isLoading && !tracks?.length &&
<div className="flex justify-center items-center min-h-[200px] text-muted-foreground">
No music yet.
</div>
}
{isLoading && <div className="w-full h-full items-center flex flex-row content-center gap-4 justify-center">
<Spinner/> Loading Tracks
</div>}
</div>
</>);
}