Docs
Music Widget
Widget to display music playing/paused.
requires interactionclick
Installation
Install dependencies
npm install lucide-react
Run the following command
It will create a new file called music-widget.tsx
inside the components/animata/widget
directory.
mkdir -p components/animata/widget && touch components/animata/widget/music-widget.tsx
Paste the code
Open the newly created file and paste the following code:
"use client";
import { useState } from "react";
import { Music, Music2, Music3, Pause, Play, SkipBack, SkipForward } from "lucide-react";
import { absoluteUrl, cn } from "@/lib/utils";
const songs = [
{
title: "Never gonna give you up",
artist: "Rick Astley",
},
{
title: "It must have been love",
artist: "Roxette",
},
{
title: "Take on me",
artist: "A-ha",
},
];
export default function MusicWidget() {
const [currentSong, setCurrentSong] = useState(0);
const [play, setPlay] = useState(false);
const handleClick = () => {
setPlay((prevValue) => !prevValue);
};
const handleNext = () => {
setCurrentSong((prevValue) => (prevValue + 1) % songs.length);
};
const handlePrev = () => {
setCurrentSong((prevValue) => (prevValue - 1 + songs.length) % songs.length);
};
const song = songs[currentSong];
const { title, artist } = song;
return (
<div className="flex h-52 w-52 flex-col rounded-3xl bg-gradient-to-bl from-indigo-200 to-indigo-600 p-4 text-white">
<div className="relative flex flex-1 flex-col justify-between">
<div className="flex">
<div className="flex-1">
<img
src={absoluteUrl("/widget/music.jpg")}
alt="Album Pic"
className="h-20 w-20 rounded-2xl"
/>
</div>
<div className={cn("flex h-fit w-12 flex-wrap justify-center gap-1")}>
<Music2
size={16}
className={cn("text-white transition-all", {
hidden: !play,
"delay-500 duration-1000 animate-in zoom-in direction-alternate-reverse repeat-infinite":
play,
})}
/>
<Music3
size={14}
className={cn("text-white transition-all", {
hidden: !play,
"duration-1000 animate-in zoom-in direction-alternate-reverse repeat-infinite":
play,
})}
/>
<Music
size={18}
className={cn("text-white transition-all", {
hidden: !play,
"delay-300 duration-1000 animate-in zoom-in direction-alternate-reverse repeat-infinite":
play,
})}
/>
</div>
</div>
<p title={title} className="line-clamp-1 w-full text-lg font-bold leading-none">
{title}
</p>
<p
title={artist}
className="-mt-6 line-clamp-1 text-xs font-semibold leading-none text-indigo-300"
>
{artist}
</p>
</div>
<div className="mt-2 flex items-center justify-evenly">
<SkipBack
size={20}
className="cursor-pointer fill-white text-white hover:fill-gray-100 hover:text-gray-100 active:fill-gray-200 active:text-gray-200"
onClick={handlePrev}
/>
<div onClick={handleClick}>
{!play ? (
<Play
size={25}
className="cursor-pointer fill-white text-white hover:fill-gray-100 hover:text-gray-100 active:fill-gray-200 active:text-gray-200"
/>
) : (
<Pause
size={25}
className="cursor-pointer fill-white text-white hover:fill-gray-100 hover:text-gray-100 active:fill-gray-200 active:text-gray-200"
/>
)}
</div>
<SkipForward
size={25}
className="cursor-pointer fill-white text-white hover:fill-gray-100 hover:text-gray-100 active:fill-gray-200 active:text-gray-200"
onClick={handleNext}
/>
</div>
</div>
);
}
Credits
Built by Aashish Katila yevhenyurchuk.com