import { GetRoomEngine, IPetCustomPart, PetFigureData, TextureUtils, Vector3d } from '@nitrots/nitro-renderer'; import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react'; import { Base, BaseProps } from '../Base'; interface LayoutPetImageViewProps extends BaseProps { figure?: string; typeId?: number; paletteId?: number; petColor?: number; customParts?: IPetCustomPart[]; posture?: string; headOnly?: boolean; direction?: number; scale?: number; } export const LayoutPetImageView: FC = props => { const { figure = '', typeId = -1, paletteId = -1, petColor = 0xFFFFFF, customParts = [], posture = 'std', headOnly = false, direction = 0, scale = 1, style = {}, ...rest } = props; const [ petUrl, setPetUrl ] = useState(null); const [ width, setWidth ] = useState(0); const [ height, setHeight ] = useState(0); const isDisposed = useRef(false); const getStyle = useMemo(() => { let newStyle: CSSProperties = {}; if(petUrl && petUrl.length) newStyle.backgroundImage = `url(${ petUrl })`; if(scale !== 1) { newStyle.transform = `scale(${ scale })`; if(!(scale % 1)) newStyle.imageRendering = 'pixelated'; } newStyle.width = width; newStyle.height = height; if(Object.keys(style).length) newStyle = { ...newStyle, ...style }; return newStyle; }, [ petUrl, scale, style, width, height ]); useEffect(() => { let url = null; let petTypeId = typeId; let petPaletteId = paletteId; let petColor1 = petColor; let petCustomParts: IPetCustomPart[] = customParts; let petHeadOnly = headOnly; if(figure && figure.length) { const petFigureData = new PetFigureData(figure); petTypeId = petFigureData.typeId; petPaletteId = petFigureData.paletteId; petColor1 = petFigureData.color; petCustomParts = petFigureData.customParts; } if(petTypeId === 16) petHeadOnly = false; const imageResult = GetRoomEngine().getRoomObjectPetImage(petTypeId, petPaletteId, petColor1, new Vector3d((direction * 45)), 64, { imageReady: async (result) => { if(isDisposed.current) return; const { image, data: texture } = result; if(image) { setPetUrl(image.src); setWidth(image.width); setHeight(image.height); } else if(texture) { setPetUrl(await TextureUtils.generateImageUrl(texture)); setWidth(texture.width); setHeight(texture.height); } }, imageFailed: () => { // no-op } }, petHeadOnly, 0, petCustomParts, posture); if(imageResult) { (async () => { const image = await imageResult.getImage(); if(image) { setPetUrl(image.src); setWidth(image.width); setHeight(image.height); } })(); } }, [ figure, typeId, paletteId, petColor, customParts, posture, headOnly, direction ]); useEffect(() => { isDisposed.current = false; return () => { isDisposed.current = true; }; }, []); const url = `url('${ petUrl }')`; return ; };