Merged PR 203: Improve responsive design and refactor layout

This commit is contained in:
Eric Nguyen 2022-10-03 12:05:16 +00:00
parent 50626218ba
commit 0d05f0959c
27 changed files with 968 additions and 485 deletions

View file

@ -0,0 +1,173 @@
import * as React from 'react';
import { IContainerModel } from '../../Interfaces/IContainerModel';
import { IHistoryState } from '../../Interfaces/IHistoryState';
import { IPoint } from '../../Interfaces/IPoint';
import { DIMENSION_MARGIN, USE_EXPERIMENTAL_CANVAS_API } from '../../utils/default';
import { MakeRecursionDFSIterator } from '../../utils/itertools';
import { BAR_WIDTH } from '../Bar/Bar';
import { Canvas } from '../Canvas/Canvas';
import { AddDimensions } from '../Canvas/DimensionLayer';
import { RenderSelector } from '../Canvas/Selector';
import { SVG } from '../SVG/SVG';
interface IViewerProps {
isLeftSidebarOpen: boolean
isRightSidebarOpen: boolean
current: IHistoryState
selectedContainer: IContainerModel | undefined
selectContainer: (containerId: string) => void
}
interface IViewer {
viewerWidth: number
viewerHeight: number
}
function OnResize(
isLeftSidebarOpen: boolean,
isRightSidebarOpen: boolean,
setViewer: React.Dispatch<React.SetStateAction<IViewer>>
): void {
let marginSidebar = BAR_WIDTH;
if (isLeftSidebarOpen) {
marginSidebar += 256;
}
if (isRightSidebarOpen) {
marginSidebar += 256;
}
const margin = window.innerWidth < 768 ? BAR_WIDTH : marginSidebar;
setViewer({
viewerWidth: window.innerWidth - margin,
viewerHeight: window.innerHeight
});
}
function UseSVGAutoResizerOnWindowResize(
isLeftSidebarOpen: boolean,
isRightSidebarOpen: boolean,
setViewer: React.Dispatch<React.SetStateAction<IViewer>>
): void {
React.useEffect(() => {
function SVGAutoResizer(): void {
OnResize(isLeftSidebarOpen, isRightSidebarOpen, setViewer);
}
window.addEventListener('resize', SVGAutoResizer);
return () => {
window.removeEventListener('resize', SVGAutoResizer);
};
});
}
function UseSVGAutoResizerOnSidebar(
isLeftSidebarOpen: boolean,
isRightSidebarOpen: boolean,
setViewer: React.Dispatch<React.SetStateAction<IViewer>>
): void {
React.useEffect(() => {
OnResize(isLeftSidebarOpen, isRightSidebarOpen, setViewer);
}, [isLeftSidebarOpen, isRightSidebarOpen, setViewer]);
}
export function Viewer({
isLeftSidebarOpen, isRightSidebarOpen,
current,
selectedContainer,
selectContainer
}: IViewerProps): JSX.Element {
let marginClasses = 'ml-16';
let marginSidebar = BAR_WIDTH;
if (isLeftSidebarOpen) {
marginClasses += ' md:ml-80';
marginSidebar += 256;
}
if (isRightSidebarOpen) {
marginClasses += ' md:mr-64';
marginSidebar += 256;
}
const margin = window.innerWidth < 768 ? BAR_WIDTH : marginSidebar;
const [viewer, setViewer] = React.useState<IViewer>({
viewerWidth: window.innerWidth - margin,
viewerHeight: window.innerHeight
});
UseSVGAutoResizerOnWindowResize(isLeftSidebarOpen, isRightSidebarOpen, setViewer);
UseSVGAutoResizerOnSidebar(isLeftSidebarOpen, isRightSidebarOpen, setViewer);
if (USE_EXPERIMENTAL_CANVAS_API) {
function Draw(ctx: CanvasRenderingContext2D, frameCount: number, scale: number, translatePos: IPoint): void {
const topDim = current.mainContainer.properties.y;
const leftDim = current.mainContainer.properties.x;
const rightDim = current.mainContainer.properties.x + current.mainContainer.properties.width;
const bottomDim = current.mainContainer.properties.y + current.mainContainer.properties.height;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.save();
ctx.translate(translatePos.x, translatePos.y);
ctx.scale(scale, scale);
ctx.fillStyle = '#000000';
const it = MakeRecursionDFSIterator(current.mainContainer, 0, [0, 0]);
for (const { container, depth, currentTransform } of it) {
const [x, y] = [
container.properties.x + currentTransform[0],
container.properties.y + currentTransform[1]
];
// Draw container
ctx.strokeStyle = container.properties.style?.stroke ?? '#000000';
ctx.fillStyle = container.properties.style?.fill ?? '#000000';
ctx.lineWidth = Number(container.properties.style?.strokeWidth ?? 1);
ctx.globalAlpha = Number(container.properties.style?.fillOpacity ?? 1);
ctx.fillRect(x, y, container.properties.width, container.properties.height);
ctx.globalAlpha = Number(container.properties.style?.strokeOpacity ?? 1);
ctx.strokeRect(x, y, container.properties.width, container.properties.height);
ctx.globalAlpha = 1;
ctx.lineWidth = 1;
ctx.fillStyle = '#000000';
ctx.strokeStyle = '#000000';
// Draw dimensions
const containerLeftDim = leftDim - (DIMENSION_MARGIN * (depth + 1)) / scale;
const containerTopDim = topDim - (DIMENSION_MARGIN * (depth + 1)) / scale;
const containerBottomDim = bottomDim + (DIMENSION_MARGIN * (depth + 1)) / scale;
const containerRightDim = rightDim + (DIMENSION_MARGIN * (depth + 1)) / scale;
const dimMapped = [containerLeftDim, containerBottomDim, containerTopDim, containerRightDim];
AddDimensions(ctx, container, dimMapped, currentTransform, scale, depth);
// Draw selector
RenderSelector(ctx, frameCount, {
scale,
selected: selectedContainer
});
}
ctx.restore();
}
return (
<Canvas
draw={Draw}
className='ml-16'
width={window.innerWidth - BAR_WIDTH}
height={window.innerHeight}
/>
);
}
return (
<SVG
className={marginClasses}
viewerWidth={viewer.viewerWidth}
viewerHeight={viewer.viewerHeight}
width={current.mainContainer?.properties.width}
height={current.mainContainer?.properties.height}
selected={selectedContainer}
symbols={current.symbols}
selectContainer={selectContainer}
>
{current.mainContainer}
</SVG>
);
}