Add fittingScale to toolbar + Add transformation-matrix to dependencies

This commit is contained in:
Eric NGUYEN 2023-02-17 12:46:55 +01:00
parent 4bb9e44b84
commit 61807b621f
4 changed files with 56 additions and 12 deletions

View file

@ -26,7 +26,8 @@
"react-svg-pan-zoom": "^3.12.1", "react-svg-pan-zoom": "^3.12.1",
"react-window": "^1.8.8", "react-window": "^1.8.8",
"sweetalert2": "^11.7.1", "sweetalert2": "^11.7.1",
"sweetalert2-react-content": "^5.0.7" "sweetalert2-react-content": "^5.0.7",
"transformation-matrix": "^2.14.0"
}, },
"devDependencies": { "devDependencies": {
"@testing-library/dom": "^8.20.0", "@testing-library/dom": "^8.20.0",

2
pnpm-lock.yaml generated
View file

@ -39,6 +39,7 @@ specifiers:
sweetalert2: ^11.7.1 sweetalert2: ^11.7.1
sweetalert2-react-content: ^5.0.7 sweetalert2-react-content: ^5.0.7
tailwindcss: ^3.2.4 tailwindcss: ^3.2.4
transformation-matrix: ^2.14.0
typescript: ^4.9.5 typescript: ^4.9.5
vite: ^4.1.1 vite: ^4.1.1
vitest: ^0.28.4 vitest: ^0.28.4
@ -53,6 +54,7 @@ dependencies:
react-window: 1.8.8_biqbaboplfbrettd7655fr4n2y react-window: 1.8.8_biqbaboplfbrettd7655fr4n2y
sweetalert2: 11.7.1 sweetalert2: 11.7.1
sweetalert2-react-content: 5.0.7_5cbezu6w3tvev2ldv5vdmnpfca sweetalert2-react-content: 5.0.7_5cbezu6w3tvev2ldv5vdmnpfca
transformation-matrix: 2.14.0
devDependencies: devDependencies:
'@testing-library/dom': 8.20.0 '@testing-library/dom': 8.20.0

View file

@ -1,5 +1,5 @@
import * as React from 'react'; import * as React from 'react';
import { ReactSVGPanZoom, type Tool, TOOL_PAN, type Value } from 'react-svg-pan-zoom'; import { ReactSVGPanZoom, type Tool, TOOL_PAN, type Value, ALIGN_CENTER } from 'react-svg-pan-zoom';
import { Container } from './Elements/Container'; import { Container } from './Elements/Container';
import { IContainerModel } from '../../Interfaces/IContainerModel'; import { IContainerModel } from '../../Interfaces/IContainerModel';
import { SelectorContainer } from './Elements/SelectorContainer/SelectorContainer'; import { SelectorContainer } from './Elements/SelectorContainer/SelectorContainer';
@ -8,7 +8,7 @@ import { SymbolLayer } from './Elements/SymbolLayer';
import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
import { DimensionLayer } from './Elements/DimensionLayer'; import { DimensionLayer } from './Elements/DimensionLayer';
import { SelectorSymbol } from './Elements/SelectorSymbol/SelectorSymbol'; import { SelectorSymbol } from './Elements/SelectorSymbol/SelectorSymbol';
import { Toolbar } from './SVGReactPanZoom/ui-toolbar/toolbar'; import { IToolbarProps, Toolbar } from './SVGReactPanZoom/ui-toolbar/toolbar';
interface ISVGProps { interface ISVGProps {
className?: string className?: string
@ -121,7 +121,14 @@ export function SVG(props: ISVGProps): JSX.Element {
width: 120, width: 120,
height: 120 height: 120
}} }}
customToolbar={Toolbar} customToolbar={(props: IToolbarProps) => (
<Toolbar
{...props}
SVGAlignX={ALIGN_CENTER}
SVGAlignY={ALIGN_CENTER}
fittingScale={0.8}
/>
)}
> >
<svg {...properties}> <svg {...properties}>
{children} {children}
@ -135,7 +142,7 @@ export function SVG(props: ISVGProps): JSX.Element {
} }
function UseFitOnce(svgViewer: React.RefObject<ReactSVGPanZoom>, width: number, height: number): void { function UseFitOnce(svgViewer: React.RefObject<ReactSVGPanZoom>, width: number, height: number): void {
React.useEffect(() => { React.useCallback(() => {
// TODO: Fix this // TODO: Fix this
svgViewer?.current?.setPointOnViewerCenter(width / 2, height / 2, 0.8); svgViewer?.current?.setPointOnViewerCenter(width / 2, height / 2, 0.8);
}, [svgViewer, width, height]); }, [svgViewer, width, height]);

View file

@ -1,5 +1,12 @@
import { ArrowsPointingOutIcon, CursorArrowRaysIcon, HandRaisedIcon, MagnifyingGlassMinusIcon, MagnifyingGlassPlusIcon } from '@heroicons/react/24/outline'; import {
ArrowsPointingOutIcon,
CursorArrowRaysIcon,
HandRaisedIcon,
MagnifyingGlassMinusIcon,
MagnifyingGlassPlusIcon
} from '@heroicons/react/24/outline';
import React from 'react'; import React from 'react';
import { fromObject, scale, transform, translate } from 'transformation-matrix';
import { import {
fitToViewer, fitToViewer,
@ -10,9 +17,7 @@ import {
TOOL_NONE, TOOL_NONE,
TOOL_PAN, TOOL_PAN,
TOOL_ZOOM_IN, TOOL_ZOOM_IN,
TOOL_ZOOM_OUT, TOOL_ZOOM_OUT, ALIGN_LEFT, ALIGN_TOP,
ALIGN_LEFT,
ALIGN_TOP,
type Value, type Value,
type Tool, type Tool,
type ALIGN_BOTTOM, type ALIGN_BOTTOM,
@ -22,7 +27,7 @@ import {
} from 'react-svg-pan-zoom'; } from 'react-svg-pan-zoom';
import { ToolbarButton } from './toolbar-button'; import { ToolbarButton } from './toolbar-button';
interface IToolbarProps { export interface IToolbarProps {
tool: Tool tool: Tool
value: Value value: Value
onChangeValue: (value: Value) => void onChangeValue: (value: Value) => void
@ -31,6 +36,19 @@ interface IToolbarProps {
position?: ToolbarPosition | undefined position?: ToolbarPosition | undefined
SVGAlignX?: typeof ALIGN_CENTER | typeof ALIGN_LEFT | typeof ALIGN_RIGHT | undefined SVGAlignX?: typeof ALIGN_CENTER | typeof ALIGN_LEFT | typeof ALIGN_RIGHT | undefined
SVGAlignY?: typeof ALIGN_CENTER | typeof ALIGN_TOP | typeof ALIGN_BOTTOM | undefined SVGAlignY?: typeof ALIGN_CENTER | typeof ALIGN_TOP | typeof ALIGN_BOTTOM | undefined
fittingScale?: number | undefined
}
/**
* Change value
* @param value
* @param patch
* @param action
* @returns {Object}
*/
function set(value: Value, patch: object, action = null): Value {
value = Object.assign({}, value, patch, { lastAction: action });
return Object.freeze(value);
} }
export function Toolbar({ export function Toolbar({
@ -41,7 +59,8 @@ export function Toolbar({
activeToolColor = '#1CA6FC', activeToolColor = '#1CA6FC',
position = POSITION_RIGHT, position = POSITION_RIGHT,
SVGAlignX = ALIGN_LEFT, SVGAlignX = ALIGN_LEFT,
SVGAlignY = ALIGN_TOP SVGAlignY = ALIGN_TOP,
fittingScale = undefined
}: IToolbarProps): JSX.Element { }: IToolbarProps): JSX.Element {
function handleChangeTool(event: React.MouseEvent | React.TouchEvent, tool: Tool): void { function handleChangeTool(event: React.MouseEvent | React.TouchEvent, tool: Tool): void {
onChangeTool(tool); onChangeTool(tool);
@ -50,7 +69,22 @@ export function Toolbar({
}; };
function handleFit(event: React.MouseEvent | React.TouchEvent): void { function handleFit(event: React.MouseEvent | React.TouchEvent): void {
onChangeValue(fitToViewer(value, SVGAlignX, SVGAlignY)); let fittedValue: Value = fitToViewer(value, SVGAlignX, SVGAlignY);
if (fittingScale !== undefined) {
const { viewerWidth, viewerHeight } = fittedValue;
const matrix = transform(
fromObject(fittedValue),
translate(viewerWidth, viewerHeight),
scale(fittingScale, fittingScale),
translate(-viewerWidth, -viewerHeight)
);
fittedValue = set(fittedValue, {
...matrix
});
}
onChangeValue(fittedValue);
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
}; };