76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
import { useEffect, useMemo, useRef } from "react";
|
|
|
|
export interface KeyImageProps {
|
|
keyRender: string;
|
|
size: number;
|
|
radius?: number;
|
|
colors: string[];
|
|
}
|
|
|
|
export function KeyImage(props: KeyImageProps) {
|
|
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
|
|
|
const colorsArr: string[] = useMemo(() => {
|
|
/**
|
|
* Random color generation based on keyRender
|
|
*/
|
|
let colors : string[] = [];
|
|
for(let i = 0; i < props.keyRender.length; i++){
|
|
const char = props.keyRender.charCodeAt(i);
|
|
const colorIndex = char % props.colors.length;
|
|
colors.push(props.colors[colorIndex]);
|
|
}
|
|
return colors;
|
|
}, [props.colors, props.keyRender]);
|
|
|
|
const composition: string[] = useMemo(() => {
|
|
const align = 64; // 8x8
|
|
const total = colorsArr.length;
|
|
const result: string[] = [];
|
|
for (let i = 0; i < align; i++) {
|
|
let color = colorsArr[i % total] ?? "gray";
|
|
result.push(color);
|
|
}
|
|
return result;
|
|
}, [colorsArr]);
|
|
|
|
useEffect(() => {
|
|
const canvas = canvasRef.current;
|
|
if (!canvas) return;
|
|
const ctx = canvas.getContext("2d");
|
|
if (!ctx) return;
|
|
|
|
const size = props.size;
|
|
const cells = 8;
|
|
const cellSize = size / cells;
|
|
|
|
// Ensure crisp rendering
|
|
canvas.width = size;
|
|
canvas.height = size;
|
|
|
|
// Draw 8x8 grid
|
|
for (let i = 0; i < composition.length; i++) {
|
|
const row = Math.floor(i / cells);
|
|
const col = i % cells;
|
|
const posX = Math.floor(col * cellSize);
|
|
const posY = Math.floor(row * cellSize);
|
|
const sizePx = Math.ceil(cellSize);
|
|
ctx.fillStyle = composition[i];
|
|
ctx.fillRect(posX, posY, sizePx, sizePx);
|
|
}
|
|
}, [composition, props.size]);
|
|
|
|
return (
|
|
<div style={{ width: props.size, height: props.size }}>
|
|
<canvas
|
|
ref={canvasRef}
|
|
style={{
|
|
width: props.size,
|
|
height: props.size,
|
|
borderRadius: props.radius,
|
|
display: "block",
|
|
}}
|
|
/>
|
|
</div>
|
|
);
|
|
} |