Implement rigid body Fix saveload bug: having null elements Fix events being duplicated and not being removed
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
import * as React from 'react';
|
|
import { UncontrolledReactSVGPanZoom } from 'react-svg-pan-zoom';
|
|
import { Container } from './Elements/Container';
|
|
import { ContainerModel } from '../../Interfaces/ContainerModel';
|
|
import { Selector } from './Elements/Selector';
|
|
import { BAR_WIDTH } from '../Bar/Bar';
|
|
|
|
interface ISVGProps {
|
|
width: number
|
|
height: number
|
|
children: ContainerModel | ContainerModel[] | null
|
|
selected: ContainerModel | null
|
|
}
|
|
|
|
interface Viewer {
|
|
viewerWidth: number
|
|
viewerHeight: number
|
|
}
|
|
|
|
export const ID = 'svg';
|
|
|
|
function resizeViewBox(
|
|
setViewer: React.Dispatch<React.SetStateAction<Viewer>>
|
|
): void {
|
|
setViewer({
|
|
viewerWidth: window.innerWidth - BAR_WIDTH,
|
|
viewerHeight: window.innerHeight
|
|
});
|
|
}
|
|
|
|
export const SVG: React.FC<ISVGProps> = (props: ISVGProps) => {
|
|
const [viewer, setViewer] = React.useState<Viewer>({
|
|
viewerWidth: window.innerWidth,
|
|
viewerHeight: window.innerHeight
|
|
});
|
|
|
|
React.useEffect(() => {
|
|
const onResize = (): void => resizeViewBox(setViewer);
|
|
window.addEventListener('resize', onResize);
|
|
|
|
return () => {
|
|
window.removeEventListener('resize', onResize);
|
|
};
|
|
});
|
|
|
|
const xmlns = '<http://www.w3.org/2000/svg>';
|
|
const properties = {
|
|
width: props.width,
|
|
height: props.height,
|
|
xmlns
|
|
};
|
|
|
|
let children: React.ReactNode | React.ReactNode[] = [];
|
|
if (Array.isArray(props.children)) {
|
|
children = props.children.map(child => <Container key={`container-${child.properties.id}`} model={child}/>);
|
|
} else if (props.children !== null) {
|
|
children = <Container key={`container-${props.children.properties.id}`} model={props.children}/>;
|
|
}
|
|
|
|
return (
|
|
<div id={ID} className='ml-16'>
|
|
<UncontrolledReactSVGPanZoom
|
|
width={viewer.viewerWidth}
|
|
height={viewer.viewerHeight}
|
|
background={'#ffffff'}
|
|
defaultTool='pan'
|
|
miniatureProps={{
|
|
position: 'left',
|
|
background: '#616264',
|
|
width: window.innerWidth - 12 - BAR_WIDTH,
|
|
height: 120
|
|
}}
|
|
>
|
|
<svg {...properties}>
|
|
{ children }
|
|
<Selector selected={props.selected} />
|
|
</svg>
|
|
</UncontrolledReactSVGPanZoom>
|
|
</div>
|
|
);
|
|
};
|