5180 fichiers 38.5 Mo 0 téléchargements 262 vues mis à jour il y a 5 heures ui
nitro-v36-with-renderer-v36 / src / common / layout / LayoutPetImageView.tsx
LayoutPetImageView.tsx 4.5 Ko Télécharger le fichier
import { GetRoomEngine, IPetCustomPart, PetFigureData, Vector3d } from '@octane/renderer';
import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react';
import { Base, BaseProps } from '../Base';
import { PIXEL_ART_RENDERING } from './PixelArtRendering';

const EMPTY_CUSTOM_PARTS: IPetCustomPart[] = [];

interface LayoutPetImageViewProps extends BaseProps<HTMLDivElement> {
    figure?: string;
    typeId?: number;
    paletteId?: number;
    petColor?: number;
    customParts?: IPetCustomPart[];
    posture?: string;
    headOnly?: boolean;
    direction?: number;
    scale?: number;
}

export const LayoutPetImageView: FC<LayoutPetImageViewProps> = (props) => {
    const {
        figure = '',
        typeId = -1,
        paletteId = -1,
        petColor = 0xffffff,
        customParts = EMPTY_CUSTOM_PARTS,
        posture = 'std',
        headOnly = false,
        direction = 0,
        scale = 1,
        style = {},
        ...rest
    } = props;
    const [petUrl, setPetUrl] = useState<string>(null);
    const [width, setWidth] = useState(0);
    const [height, setHeight] = useState(0);
    const isDisposed = useRef(false);
    const imageRequestGeneration = useRef(0);

    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 = PIXEL_ART_RENDERING;
        }

        newStyle.width = width;
        newStyle.height = height;

        if (Object.keys(style).length) newStyle = { ...newStyle, ...style };

        return newStyle;
    }, [petUrl, scale, style, width, height]);

    useEffect(() => {
        const generation = ++imageRequestGeneration.current;
        const isCurrentRequest = () => !isDisposed.current && imageRequestGeneration.current === generation;

        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 (!isCurrentRequest()) {
                        result.dispose();
                        return;
                    }

                    const { image, data: texture } = result;

                    if (image) {
                        setPetUrl(image.src);
                        setWidth(image.width);
                        setHeight(image.height);
                    } else if (texture) {
                        // Read the size first: getImage() releases the render texture.
                        const { width, height } = texture;
                        const generated = await result.getImage();

                        if (!isCurrentRequest()) return;

                        setPetUrl(generated?.src ?? null);
                        setWidth(width);
                        setHeight(height);
                    }
                },
                imageFailed: () => {
                    // no-op
                }
            },
            petHeadOnly,
            0,
            petCustomParts,
            posture
        );

        if (imageResult) {
            (async () => {
                const image = await imageResult.getImage();

                if (image && isCurrentRequest()) {
                    setPetUrl(image.src);
                    setWidth(image.width);
                    setHeight(image.height);
                }
            })();
        }

        return () => {
            if (imageRequestGeneration.current === generation) imageRequestGeneration.current++;
        };
    }, [figure, typeId, paletteId, petColor, customParts, posture, headOnly, direction]);

    useEffect(() => {
        isDisposed.current = false;

        return () => {
            isDisposed.current = true;
        };
    }, []);

    return <Base classNames={['pet-image']} style={getStyle} {...rest} />;
};
15Sujets
1Dépôts
20Membres
2En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser