diff --git a/src/Components/SVG/Elements/Container.tsx b/src/Components/SVG/Elements/Container.tsx index 050d892..c3bce70 100644 --- a/src/Components/SVG/Elements/Container.tsx +++ b/src/Components/SVG/Elements/Container.tsx @@ -5,11 +5,12 @@ import { DIMENSION_MARGIN, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, S import { CancelParentTransform, GetDepth, MakeIterator, Pairwise } from '../../../utils/itertools'; import { Dimension } from './Dimension'; import { IContainerProperties } from '../../../Interfaces/IContainerProperties'; -import { RestoreX, TransformX } from '../../../utils/svg'; +import { TransformX } from '../../../utils/svg'; import { Camelize } from '../../../utils/stringtools'; interface IContainerProps { model: IContainerModel + scale: number } /** @@ -17,7 +18,12 @@ interface IContainerProps { * @returns Render the container */ export function Container(props: IContainerProps): JSX.Element { - const containersElements = props.model.children.map(child => ); + const containersElements = props.model.children.map( + child => ); const width: number = props.model.properties.width; const height: number = props.model.properties.height; @@ -73,7 +79,8 @@ export function Container(props: IContainerProps): JSX.Element { yStart={yChildren} yEnd={yChildren} strokeWidth={strokeWidth} - text={textChildren} />; + text={textChildren} + scale={props.scale} />; } const borrowerDimensions: JSX.Element[] = []; @@ -109,7 +116,9 @@ export function Container(props: IContainerProps): JSX.Element { yStart={props.model.properties.height + yDim * -1} yEnd={props.model.properties.height + yDim * -1} strokeWidth={strokeWidth} - text={(next - cur).toFixed(2).toString()} />); + text={(next - cur).toFixed(2).toString()} + scale={props.scale} + />); count++; } } @@ -128,7 +137,8 @@ export function Container(props: IContainerProps): JSX.Element { yStart={yDim} yEnd={yDim} strokeWidth={strokeWidth} - text={text} /> + text={text} + scale={props.scale} /> : null} {childrenDimensions} {borrowerDimensions} @@ -137,6 +147,10 @@ export function Container(props: IContainerProps): JSX.Element { ? {props.model.properties.displayedText} diff --git a/src/Components/SVG/Elements/DepthDimensionLayer.tsx b/src/Components/SVG/Elements/DepthDimensionLayer.tsx index 685aa7b..0c5d625 100644 --- a/src/Components/SVG/Elements/DepthDimensionLayer.tsx +++ b/src/Components/SVG/Elements/DepthDimensionLayer.tsx @@ -3,13 +3,15 @@ import { ContainerModel } from '../../../Interfaces/IContainerModel'; import { DIMENSION_MARGIN } from '../../../utils/default'; import { GetAbsolutePosition, MakeBFSIterator } from '../../../utils/itertools'; import { TransformX } from '../../../utils/svg'; +import { Properties } from '../../ContainerProperties/ContainerProperties'; import { Dimension } from './Dimension'; interface IDimensionLayerProps { roots: ContainerModel | ContainerModel[] | null + scale?: number } -function GetDimensionsNodes(root: ContainerModel): React.ReactNode[] { +function GetDimensionsNodes(root: ContainerModel, scale: number): React.ReactNode[] { const it = MakeBFSIterator(root); const dimensions: React.ReactNode[] = []; let currentDepth = 0; @@ -18,7 +20,7 @@ function GetDimensionsNodes(root: ContainerModel): React.ReactNode[] { let lastY = 0; for (const { container, depth } of it) { if (currentDepth !== depth) { - AddNewDimension(currentDepth, min, max, lastY, dimensions); + AddNewDimension(currentDepth, min, max, lastY, scale, dimensions); currentDepth = depth; min = Infinity; @@ -37,7 +39,7 @@ function GetDimensionsNodes(root: ContainerModel): React.ReactNode[] { } } - AddNewDimension(currentDepth, min, max, lastY, dimensions); + AddNewDimension(currentDepth, min, max, lastY, scale, dimensions); return dimensions; } @@ -49,12 +51,13 @@ function GetDimensionsNodes(root: ContainerModel): React.ReactNode[] { */ export function DepthDimensionLayer(props: IDimensionLayerProps): JSX.Element { let dimensions: React.ReactNode[] = []; + const scale = props.scale ?? 1; if (Array.isArray(props.roots)) { props.roots.forEach(child => { - dimensions.concat(GetDimensionsNodes(child)); + dimensions.concat(GetDimensionsNodes(child, scale)); }); } else if (props.roots !== null) { - dimensions = GetDimensionsNodes(props.roots); + dimensions = GetDimensionsNodes(props.roots, scale); } return ( @@ -63,7 +66,7 @@ export function DepthDimensionLayer(props: IDimensionLayerProps): JSX.Element { ); } -function AddNewDimension(currentDepth: number, min: number, max: number, lastY: number, dimensions: React.ReactNode[]): void { +function AddNewDimension(currentDepth: number, min: number, max: number, lastY: number, scale: number, dimensions: React.ReactNode[]): void { const id = `dim-depth-${currentDepth}`; const xStart = min; const xEnd = max; @@ -87,6 +90,8 @@ function AddNewDimension(currentDepth: number, min: number, max: number, lastY: xEnd={xEnd} yEnd={y} strokeWidth={strokeWidth} - text={text} /> + text={text} + scale={scale} + /> ); } diff --git a/src/Components/SVG/Elements/Dimension.tsx b/src/Components/SVG/Elements/Dimension.tsx index cf8876c..d59c5b4 100644 --- a/src/Components/SVG/Elements/Dimension.tsx +++ b/src/Components/SVG/Elements/Dimension.tsx @@ -9,6 +9,7 @@ interface IDimensionProps { yEnd: number text: string strokeWidth: number + scale?: number } /** @@ -25,8 +26,10 @@ function ApplyParametric(x0: number, t: number, vx: number): number { } export function Dimension(props: IDimensionProps): JSX.Element { + const scale = props.scale ?? 1; const style: React.CSSProperties = { - stroke: 'black' + stroke: 'black', + strokeWidth: 2 / scale }; /// We need to find the points of the notches @@ -41,15 +44,16 @@ export function Dimension(props: IDimensionProps): JSX.Element { const [perpVecX, perpVecY] = [unitY, -unitX]; // Use the parametric function to get the coordinates (x = x0 + t * v.x) - const startTopX = ApplyParametric(props.xStart, NOTCHES_LENGTH, perpVecX); - const startTopY = ApplyParametric(props.yStart, NOTCHES_LENGTH, perpVecY); - const startBottomX = ApplyParametric(props.xStart, -NOTCHES_LENGTH, perpVecX); - const startBottomY = ApplyParametric(props.yStart, -NOTCHES_LENGTH, perpVecY); + const notchesLength = NOTCHES_LENGTH / scale; + const startTopX = ApplyParametric(props.xStart, notchesLength, perpVecX); + const startTopY = ApplyParametric(props.yStart, notchesLength, perpVecY); + const startBottomX = ApplyParametric(props.xStart, -notchesLength, perpVecX); + const startBottomY = ApplyParametric(props.yStart, -notchesLength, perpVecY); - const endTopX = ApplyParametric(props.xEnd, NOTCHES_LENGTH, perpVecX); - const endTopY = ApplyParametric(props.yEnd, NOTCHES_LENGTH, perpVecY); - const endBottomX = ApplyParametric(props.xEnd, -NOTCHES_LENGTH, perpVecX); - const endBottomY = ApplyParametric(props.yEnd, -NOTCHES_LENGTH, perpVecY); + const endTopX = ApplyParametric(props.xEnd, notchesLength, perpVecX); + const endTopY = ApplyParametric(props.yEnd, notchesLength, perpVecY); + const endBottomX = ApplyParametric(props.xEnd, -notchesLength, perpVecX); + const endBottomY = ApplyParametric(props.yEnd, -notchesLength, perpVecY); return ( @@ -77,6 +81,10 @@ export function Dimension(props: IDimensionProps): JSX.Element { {props.text} diff --git a/src/Components/SVG/Elements/Selector/Selector.tsx b/src/Components/SVG/Elements/Selector/Selector.tsx index 0c2a491..e43e7be 100644 --- a/src/Components/SVG/Elements/Selector/Selector.tsx +++ b/src/Components/SVG/Elements/Selector/Selector.tsx @@ -7,6 +7,7 @@ import { RemoveMargin } from '../../../../utils/svg'; interface ISelectorProps { selected?: IContainerModel + scale?: number } export function Selector(props: ISelectorProps): JSX.Element { @@ -17,6 +18,7 @@ export function Selector(props: ISelectorProps): JSX.Element { ); } + const scale = (props.scale ?? 1); let [x, y] = GetAbsolutePosition(props.selected); let [width, height] = [ props.selected.properties.width, @@ -35,7 +37,7 @@ export function Selector(props: ISelectorProps): JSX.Element { const style: React.CSSProperties = { stroke: '#3B82F6', - strokeWidth: 4, + strokeWidth: 4 / scale, fillOpacity: 0, transitionProperty: 'all', transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)', @@ -57,6 +59,10 @@ export function Selector(props: ISelectorProps): JSX.Element { ? {props.selected.properties.displayedText} diff --git a/src/Components/SVG/SVG.scss b/src/Components/SVG/SVG.scss index f575471..e825efd 100644 --- a/src/Components/SVG/SVG.scss +++ b/src/Components/SVG/SVG.scss @@ -9,6 +9,4 @@ text { stroke-linecap: butt; stroke-linejoin: miter; stroke-opacity: 1; - transform: translateX(-50%); - transform-box: fill-box; } diff --git a/src/Components/SVG/SVG.tsx b/src/Components/SVG/SVG.tsx index 0cc6311..958f410 100644 --- a/src/Components/SVG/SVG.tsx +++ b/src/Components/SVG/SVG.tsx @@ -56,6 +56,8 @@ 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); + const svgViewer = React.useRef(null); // Framerate limiter @@ -78,9 +80,18 @@ export function SVG(props: ISVGProps): JSX.Element { let children: React.ReactNode | React.ReactNode[] = []; if (Array.isArray(props.children)) { - children = props.children.map(child => ); + children = props.children.map(child => + ); } else if (props.children !== null) { - children = ; + children = ; } return ( @@ -103,6 +114,10 @@ export function SVG(props: ISVGProps): JSX.Element { 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={{ @@ -115,10 +130,10 @@ export function SVG(props: ISVGProps): JSX.Element { {children} {SHOW_DIMENSIONS_PER_DEPTH - ? + ? : null} - {/* leave this at the end so it can be removed during the svg export */} + {/* leave this at the end so it can be removed during the svg export */} diff --git a/src/utils/default.ts b/src/utils/default.ts index 98a0758..04fc6c1 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -34,7 +34,7 @@ export const SHOW_CHILDREN_DIMENSIONS = false; export const SHOW_BORROWER_DIMENSIONS = true; export const SHOW_DIMENSIONS_PER_DEPTH = false; export const DIMENSION_MARGIN = 50; -export const NOTCHES_LENGTH = 4; +export const NOTCHES_LENGTH = 10; /// SYMBOL DEFAULTS ///