Files
Nitro-V3/src/common/layout/LayoutRoomPreviewerView.tsx
T
2026-04-10 11:40:39 +02:00

103 lines
2.8 KiB
TypeScript

import { GetRenderer, GetTicker, NitroTicker, RoomPreviewer, TextureUtils } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useEffect, useRef } from 'react';
export const LayoutRoomPreviewerView: FC<{
roomPreviewer: RoomPreviewer;
height?: number;
}> = props =>
{
const { roomPreviewer = null, height = 0 } = props;
const elementRef = useRef<HTMLDivElement>();
const onClick = (event: MouseEvent<HTMLDivElement>) =>
{
if(!roomPreviewer) return;
if(event.shiftKey) roomPreviewer.changeRoomObjectDirection();
else roomPreviewer.changeRoomObjectState();
};
useEffect(() =>
{
if(!elementRef) return;
const width = elementRef.current.parentElement.clientWidth;
const texture = TextureUtils.createRenderTexture(width, height);
const paintToDOM = () =>
{
if(!roomPreviewer || !elementRef.current) return;
const renderingCanvas = roomPreviewer.getRenderingCanvas();
if(!renderingCanvas) return;
GetRenderer().render({
target: texture,
container: renderingCanvas.master,
clear: true
});
const canvas = GetRenderer().texture.generateCanvas(texture);
const base64 = canvas.toDataURL('image/png');
canvas.width = 0;
canvas.height = 0;
elementRef.current.style.backgroundImage = `url(${ base64 })`;
};
const update = (ticker: NitroTicker) =>
{
if(!roomPreviewer || !elementRef.current) return;
roomPreviewer.updatePreviewRoomView();
const renderingCanvas = roomPreviewer.getRenderingCanvas();
if(renderingCanvas && renderingCanvas.canvasUpdated)
{
paintToDOM();
}
};
GetTicker().add(update);
const resizeObserver = new ResizeObserver(() =>
{
if(!roomPreviewer || !elementRef.current) return;
const width = elementRef.current.parentElement.offsetWidth;
roomPreviewer.modifyRoomCanvas(width, height);
paintToDOM();
});
roomPreviewer.getRoomCanvas(width, height);
resizeObserver.observe(elementRef.current);
return () =>
{
GetTicker().remove(update);
resizeObserver.disconnect();
texture.destroy(true);
};
}, [ roomPreviewer, elementRef, height ]);
return (
<div
ref={ elementRef }
className="relative w-full rounded-md shadow-room-previewer"
style={ {
height,
minHeight: height,
maxHeight: height
} }
onClick={ onClick } />
);
};