Files
HaBit/components/character/tinted-sprite-icon.tsx
pricewowen 4705b1a0ec Add initial character creation screen
Created the first version of the character creation feature, including the base layout and starting UI elements for customizing a character.
2026-05-23 19:32:20 -06:00

67 lines
1.3 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import {
drawTintedSprite,
getCachedImage,
hslToRgb,
type HSL,
} from "@/lib/character/color-utils";
import { cn } from "@/lib/utils";
type TintedSpriteIconProps = {
src: string;
color: HSL;
size?: number;
className?: string;
};
export function TintedSpriteIcon({
src,
color,
size = 40,
className,
}: TintedSpriteIconProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
let cancelled = false;
async function render() {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d", { willReadFrequently: true });
if (!ctx) return;
const image = await getCachedImage(src);
if (cancelled) return;
canvas.width = image.width;
canvas.height = image.height;
ctx.clearRect(0, 0, image.width, image.height);
drawTintedSprite(ctx, image, hslToRgb(color.h, color.s, color.l));
}
render();
return () => {
cancelled = true;
};
}, [src, color]);
return (
<canvas
ref={canvasRef}
aria-hidden
className={cn("block max-h-full max-w-full", className)}
style={{
imageRendering: "pixelated",
width: size,
height: size,
}}
/>
);
}