68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
import React, { useEffect, useRef } from 'react';
|
||
|
||
interface HeadAvatarProps {
|
||
skinUrl?: string;
|
||
size?: number;
|
||
style?: React.CSSProperties;
|
||
version?: number; // ✅ добавили
|
||
}
|
||
|
||
const DEFAULT_SKIN =
|
||
'https://static.planetminecraft.com/files/resource_media/skin/original-steve-15053860.png';
|
||
|
||
export const HeadAvatar: React.FC<HeadAvatarProps> = ({
|
||
skinUrl,
|
||
size = 24,
|
||
style,
|
||
version = 0, // ✅ дефолт
|
||
...canvasProps
|
||
}) => {
|
||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||
|
||
useEffect(() => {
|
||
const baseUrl = skinUrl?.trim() ? skinUrl : DEFAULT_SKIN;
|
||
|
||
// ✅ cache-bust: чтобы браузер НЕ отдавал старую картинку
|
||
const finalSkinUrl = `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}v=${version}`;
|
||
|
||
const canvas = canvasRef.current;
|
||
if (!canvas) return;
|
||
|
||
const img = new Image();
|
||
img.crossOrigin = 'anonymous';
|
||
img.src = finalSkinUrl;
|
||
|
||
img.onload = () => {
|
||
const ctx = canvas.getContext('2d');
|
||
if (!ctx) return;
|
||
|
||
canvas.width = size;
|
||
canvas.height = size;
|
||
|
||
ctx.clearRect(0, 0, size, size);
|
||
ctx.imageSmoothingEnabled = false;
|
||
|
||
ctx.drawImage(img, 8, 8, 8, 8, 0, 0, size, size);
|
||
ctx.drawImage(img, 40, 8, 8, 8, 0, 0, size, size);
|
||
};
|
||
|
||
img.onerror = (e) => {
|
||
console.error('Не удалось загрузить скин для HeadAvatar:', e);
|
||
};
|
||
}, [skinUrl, size, version]); // ✅ version добавили
|
||
|
||
return (
|
||
<canvas
|
||
ref={canvasRef}
|
||
{...canvasProps}
|
||
style={{
|
||
width: size,
|
||
height: size,
|
||
borderRadius: 4,
|
||
imageRendering: 'pixelated',
|
||
...style,
|
||
}}
|
||
/>
|
||
);
|
||
};
|