import * as React from 'react'; import { ReactSVGPanZoom, Tool, TOOL_PAN, Value } from 'react-svg-pan-zoom'; import { Container } from './Elements/Container'; import { IContainerModel } from '../../Interfaces/IContainerModel'; import { Selector } from './Elements/Selector/Selector'; import { DepthDimensionLayer } from './Elements/DepthDimensionLayer'; import { MAX_FRAMERATE, SHOW_DIMENSIONS_PER_DEPTH } from '../../utils/default'; import { SymbolLayer } from './Elements/SymbolLayer'; import { ISymbolModel } from '../../Interfaces/ISymbolModel'; import { DimensionLayer } from './Elements/DimensionLayer'; interface ISVGProps { className?: string viewerWidth: number viewerHeight: number width: number height: number containers: Map children: IContainerModel selected?: IContainerModel symbols: Map selectContainer: (containerId: string) => void } export const ID = 'svg'; export function SVG(props: ISVGProps): JSX.Element { const [tool, setTool] = React.useState(TOOL_PAN); const [value, setValue] = React.useState({} as Value); const [scale, setScale] = React.useState(value.a ?? 1); const svgViewer = React.useRef(null); // Framerate limiter const delta = React.useRef(0); const timer = React.useRef(performance.now()); const renderCounter = React.useRef(0); // Debug: FPS counter // const startTimer = React.useRef(Date.now()); // console.log(renderCounter.current / ((Date.now() - startTimer.current) / 1000)); UseFitOnce(svgViewer, props.width, props.height); const xmlns = ''; const properties = { width: props.width, height: props.height, xmlns }; let children: React.ReactNode | React.ReactNode[] = []; children = ; return (
{ // Framerate limiter const newTimer = performance.now(); delta.current += (newTimer - timer.current) / 1000; timer.current = newTimer; if (delta.current <= (1 / MAX_FRAMERATE)) { return; } renderCounter.current = renderCounter.current + 1; delta.current = delta.current % (1 / MAX_FRAMERATE); setValue(value); }} onZoom={(event: unknown) => { const value = event as Value; setScale(value.a); }} background={'#ffffff'} defaultTool='pan' miniatureProps={{ position: 'left', background: '#616264', width: 120, height: 120 }} > {children} {SHOW_DIMENSIONS_PER_DEPTH ? : null} {/* leave this at the end so it can be removed during the svg export */}
); } function UseFitOnce(svgViewer: React.RefObject, width: number, height: number): void { React.useEffect(() => { svgViewer?.current?.fitToViewer(); }, [svgViewer, width, height]); }