5180 fichiers 38.5 Mo 0 téléchargements 303 vues mis à jour il y a 6 heures ui
FloorplanAirPreview.tsx 4.1 Ko Télécharger le fichier
import { FC, useEffect, useMemo, useRef, useState } from 'react';
import tile0 from '../../../assets/images/floorplaneditor/preview/tile_preview_0.png';
import tile1 from '../../../assets/images/floorplaneditor/preview/tile_preview_1.png';
import tile2 from '../../../assets/images/floorplaneditor/preview/tile_preview_2.png';
import tile3 from '../../../assets/images/floorplaneditor/preview/tile_preview_3.png';
import tile4 from '../../../assets/images/floorplaneditor/preview/tile_preview_4.png';
import tile5 from '../../../assets/images/floorplaneditor/preview/tile_preview_5.png';
import tile6 from '../../../assets/images/floorplaneditor/preview/tile_preview_6.png';
import tile7 from '../../../assets/images/floorplaneditor/preview/tile_preview_7.png';
import tile8 from '../../../assets/images/floorplaneditor/preview/tile_preview_8.png';
import tile9 from '../../../assets/images/floorplaneditor/preview/tile_preview_9.png';
import tileA from '../../../assets/images/floorplaneditor/preview/tile_preview_a.png';
import tileB from '../../../assets/images/floorplaneditor/preview/tile_preview_b.png';
import tileC from '../../../assets/images/floorplaneditor/preview/tile_preview_c.png';
import tileD from '../../../assets/images/floorplaneditor/preview/tile_preview_d.png';
import tileE from '../../../assets/images/floorplaneditor/preview/tile_preview_e.png';
import tileF from '../../../assets/images/floorplaneditor/preview/tile_preview_f.png';
import tileEntry from '../../../assets/images/floorplaneditor/preview/tile_preview_entry.png';
import { layoutAirPreview } from '../state/airPreview';
import { FloorplanState } from '../state/types';
import { NativeTextTree } from '../../../common/native-text/NativeTextTree';

/** AIR's preview tiles in picture order: the 16 neighbour masks, then the door. */
const TILE_SOURCES = [tile0, tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9, tileA, tileB, tileC, tileD, tileE, tileF, tileEntry];

let tileImages: Promise<HTMLImageElement[]> | null = null;

const loadTileImages = (): Promise<HTMLImageElement[]> => {
    if (!tileImages) {
        tileImages = Promise.all(
            TILE_SOURCES.map(
                (source) =>
                    new Promise<HTMLImageElement>((resolve) => {
                        const image = new Image();

                        image.onload = () => resolve(image);
                        image.onerror = () => resolve(image);
                        image.src = source;
                    })
            )
        );
    }

    return tileImages;
};

/**
 * The floor plan preview of AIR's floor plan editor (FloorPlanPreviewer): the floor drawn tile by tile with AIR's
 * small preview pictures on a white bitmap, the door tile in green. A plain 2D canvas, cheap on every device.
 */
export const FloorplanAirPreview: FC<{ state: FloorplanState }> = ({ state }) => {
    const canvasRef = useRef<HTMLCanvasElement>(null);
    const [images, setImages] = useState<HTMLImageElement[] | null>(null);
    const layout = useMemo(() => layoutAirPreview(state.tiles, state.door), [state.tiles, state.door]);

    useEffect(() => {
        let alive = true;

        loadTileImages().then((loaded) => alive && setImages(loaded));

        return () => {
            alive = false;
        };
    }, []);

    useEffect(() => {
        const canvas = canvasRef.current;
        const context = canvas?.getContext('2d');

        if (!canvas || !context) return;

        canvas.width = Math.max(1, layout.width);
        canvas.height = Math.max(1, layout.height);
        context.fillStyle = '#ffffff';
        context.fillRect(0, 0, canvas.width, canvas.height);

        if (!images) return;

        for (const tile of layout.tiles) {
            const image = images[tile.picture];

            if (image?.complete && image.naturalWidth) context.drawImage(image, tile.x, tile.y);
        }
    }, [images, layout]);

    return (
        <NativeTextTree>
            <div className="fp-air-preview" data-testid="floorplan-preview-2d">
                <canvas ref={canvasRef} className="fp-air-preview-canvas" data-tiles={layout.tiles.length} />
            </div>
        </NativeTextTree>
    );
};
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