Skip to content

Instantly share code, notes, and snippets.

@Brayden
Created November 21, 2024 14:13
Show Gist options
  • Save Brayden/5cdaa506c653d509d4615a6795a419ea to your computer and use it in GitHub Desktop.
Save Brayden/5cdaa506c653d509d4615a6795a419ea to your computer and use it in GitHub Desktop.
Shiny Card with Movement
export function Card({
height
}: {
height: number
}) {
const scale = height / 390;
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
const card = e.currentTarget;
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateY = ((x - centerX) / centerX) * 5;
const rotateX = -((y - centerY) / centerY) * 5;
// Calculate the position for the light sheen
const sheenX = ((x / rect.width) * 100);
card.style.transform = `scale(${scale}) perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
const sheenElement = card.querySelector('.sheen-overlay') as HTMLElement;
if (sheenElement) {
sheenElement.style.background = `linear-gradient(
105deg,
transparent 0%,
transparent ${Math.max(0, sheenX - 45)}%,
rgba(255, 255, 255, 0.03) ${sheenX - 10}%,
rgba(255, 255, 255, 0.03) ${sheenX}%,
transparent ${Math.min(100, sheenX + 45)}%,
transparent 100%
)`;
}
};
const handleMouseLeave = (e: React.MouseEvent<HTMLDivElement>) => {
const card = e.currentTarget;
card.style.transform = `scale(${scale})`;
const sheenElement = card.querySelector('.sheen-overlay') as HTMLElement;
if (sheenElement) {
sheenElement.style.background = 'transparent';
}
};
return (
<div className="w-full aspect-[2/3] shadow-xl cursor-pointer select-none">
<div
className="relative w-full h-full bg-neutral-950 rounded-md overflow-hidden
transition-all duration-200 ease-out"
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
{/* Add sheen overlay */}
<div className="sheen-overlay absolute inset-0 pointer-events-none z-[60] transition-all duration-100" />
{/* Stripes section */}
<div className="relative">
<div className="w-full rotate-45 h-2 bg-[#6a894f] absolute -right-28" />
<div className="w-full rotate-45 h-2 bg-[#5e7875] absolute -right-24" />
<div className="w-full rotate-45 h-2 bg-[#d78d39] absolute -right-20" />
<div className="w-full rotate-45 h-2 bg-[#b35439] absolute -right-16" />
<div className="w-full rotate-45 h-2 bg-neutral-200 absolute -right-12" />
<div className="w-full rotate-45 h-2 bg-neutral-500 absolute -right-8 translate-x-8 translate-y-8" />
</div>
<div className="absolute h-[390px] w-full opacity-30">
<div className="w-full rotate-45 h-2 bg-[#6a894f] absolute -left-28 bottom-0" />
<div className="w-full rotate-45 h-2 bg-[#5e7875] absolute -left-24 bottom-0" />
<div className="w-full rotate-45 h-2 bg-[#d78d39] absolute -left-20 bottom-0" />
<div className="w-full rotate-45 h-2 bg-[#b35439] absolute -left-16 bottom-0" />
<div className="w-full rotate-45 h-2 bg-neutral-200 absolute -left-12 bottom-0" />
<div className="w-full rotate-45 h-2 bg-neutral-500 absolute -left-8 bottom-0 -translate-x-8 -translate-y-8" />
</div>
{/* Background container */}
<div className="absolute bg-[#6a894f] rounded left-2 top-10 h-[calc(100%-64px)] w-[calc(100%-16px)] shadow-[1px_1px_3px_black]" />
{/* Primary content area */}
<div className="absolute z-10 p-2 w-full h-full flex flex-col">
{/* Name plate section */}
<div className="relative w-full h-6 bg-[#d6ebc5] shadow-[1px_1px_5px_black]">
<div className="absolute left-0 top-0 w-0.5 h-full bg-[#a3b98f]" />
<div className="absolute left-0.5 bottom-0 h-0.5 w-[calc(100%-2px)] bg-[#a3b98f]" />
<div className="text-sm font-medium ml-3">{`Aye'De Gaph`}</div>
</div>
{/* Card art section */}
<div className="relative w-full px-1.5">
<div className="h-32 bg-white border-2 border-neutral-950">
</div>
</div>
{/* Class section */}
<div className="px-5">
<div className="relative border border-black w-full h-6 bg-[#d6ebc5] overflow-hidden">
<div className="absolute left-0 top-0 w-0.5 h-full bg-[#a3b98f]" />
<div className="absolute left-0.5 bottom-0 h-0.5 w-full bg-[#a3b98f]" />
</div>
</div>
<div className="flex-1">
</div>
<div className="text-xs text-white/80 font-bold w-full text-center translate-y-1">
Level 1
</div>
</div>
</div>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment