Replace svg-pan-zoom by react-svg-pan-zoom

This commit is contained in:
Siklos 2022-07-31 17:34:47 +02:00
parent d4a89f7f9d
commit 6db63d5a47
8 changed files with 95 additions and 41 deletions

80
package-lock.json generated
View file

@ -10,11 +10,12 @@
"dependencies": { "dependencies": {
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"svg-pan-zoom": "^3.6.1" "react-svg-pan-zoom": "^3.11.0"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.15", "@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@types/react-svg-pan-zoom": "^3.3.5",
"@typescript-eslint/eslint-plugin": "^5.31.0", "@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0", "@typescript-eslint/parser": "^5.31.0",
"@vitejs/plugin-react": "^2.0.0", "@vitejs/plugin-react": "^2.0.0",
@ -630,6 +631,15 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/react-svg-pan-zoom": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/@types/react-svg-pan-zoom/-/react-svg-pan-zoom-3.3.5.tgz",
"integrity": "sha512-W8GRFCDy7raSDr5OXGjSyvX5KmdWlIQfv0NLa1jfAYVUO4ClVbgorWeAAom7nY3Pl+4h9blXE1Bnu2CW1iMEvQ==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": { "node_modules/@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@ -3239,7 +3249,6 @@
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@ -3630,7 +3639,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"dependencies": { "dependencies": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@ -3704,8 +3712,7 @@
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"dev": true
}, },
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.14.0", "version": "0.14.0",
@ -3716,6 +3723,21 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-svg-pan-zoom": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/react-svg-pan-zoom/-/react-svg-pan-zoom-3.11.0.tgz",
"integrity": "sha512-xK2tpfp4YksHOfyMZH5zXP52ARLSBgkoJgWNJmJ1B+6O1tkuf23TQp7Q4m9GG5IRSK5KWO0JEGEWlNYG9+iiug==",
"dependencies": {
"prop-types": "^15.8.0",
"transformation-matrix": "^2.11.1"
},
"funding": {
"url": "https://www.paypal.me/chrvadala/25"
},
"peerDependencies": {
"react": ">=17.0.0"
}
},
"node_modules/read-cache": { "node_modules/read-cache": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@ -4064,11 +4086,6 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/svg-pan-zoom": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/svg-pan-zoom/-/svg-pan-zoom-3.6.1.tgz",
"integrity": "sha512-JaKkGHHfGvRrcMPdJWkssLBeWqM+Isg/a09H7kgNNajT1cX5AztDTNs+C8UzpCxjCTRrG34WbquwaovZbmSk9g=="
},
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
"version": "3.1.7", "version": "3.1.7",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.7.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.7.tgz",
@ -4142,6 +4159,14 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/transformation-matrix": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.12.0.tgz",
"integrity": "sha512-BbzXM7el7rNwIr1s87m8tcffH5qgY+HYROLn3BStRU9Y6vYTL37YZKadfNPEvGbP813iA1h8qflo4pa2TomkyQ==",
"funding": {
"url": "https://www.paypal.me/chrvadala/25"
}
},
"node_modules/tsconfig-paths": { "node_modules/tsconfig-paths": {
"version": "3.14.1", "version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
@ -4857,6 +4882,15 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"@types/react-svg-pan-zoom": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/@types/react-svg-pan-zoom/-/react-svg-pan-zoom-3.3.5.tgz",
"integrity": "sha512-W8GRFCDy7raSDr5OXGjSyvX5KmdWlIQfv0NLa1jfAYVUO4ClVbgorWeAAom7nY3Pl+4h9blXE1Bnu2CW1iMEvQ==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/scheduler": { "@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@ -6623,8 +6657,7 @@
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
"dev": true
}, },
"object-hash": { "object-hash": {
"version": "3.0.0", "version": "3.0.0",
@ -6879,7 +6912,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"requires": { "requires": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@ -6924,8 +6956,7 @@
"react-is": { "react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"dev": true
}, },
"react-refresh": { "react-refresh": {
"version": "0.14.0", "version": "0.14.0",
@ -6933,6 +6964,15 @@
"integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
"dev": true "dev": true
}, },
"react-svg-pan-zoom": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/react-svg-pan-zoom/-/react-svg-pan-zoom-3.11.0.tgz",
"integrity": "sha512-xK2tpfp4YksHOfyMZH5zXP52ARLSBgkoJgWNJmJ1B+6O1tkuf23TQp7Q4m9GG5IRSK5KWO0JEGEWlNYG9+iiug==",
"requires": {
"prop-types": "^15.8.0",
"transformation-matrix": "^2.11.1"
}
},
"read-cache": { "read-cache": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@ -7170,11 +7210,6 @@
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"dev": true "dev": true
}, },
"svg-pan-zoom": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/svg-pan-zoom/-/svg-pan-zoom-3.6.1.tgz",
"integrity": "sha512-JaKkGHHfGvRrcMPdJWkssLBeWqM+Isg/a09H7kgNNajT1cX5AztDTNs+C8UzpCxjCTRrG34WbquwaovZbmSk9g=="
},
"tailwindcss": { "tailwindcss": {
"version": "3.1.7", "version": "3.1.7",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.7.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.7.tgz",
@ -7234,6 +7269,11 @@
"is-number": "^7.0.0" "is-number": "^7.0.0"
} }
}, },
"transformation-matrix": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/transformation-matrix/-/transformation-matrix-2.12.0.tgz",
"integrity": "sha512-BbzXM7el7rNwIr1s87m8tcffH5qgY+HYROLn3BStRU9Y6vYTL37YZKadfNPEvGbP813iA1h8qflo4pa2TomkyQ=="
},
"tsconfig-paths": { "tsconfig-paths": {
"version": "3.14.1", "version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",

View file

@ -11,11 +11,12 @@
"dependencies": { "dependencies": {
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"svg-pan-zoom": "^3.6.1" "react-svg-pan-zoom": "^3.11.0"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.15", "@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@types/react-svg-pan-zoom": "^3.3.5",
"@typescript-eslint/eslint-plugin": "^5.31.0", "@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0", "@typescript-eslint/parser": "^5.31.0",
"@vitejs/plugin-react": "^2.0.0", "@vitejs/plugin-react": "^2.0.0",

View file

@ -58,9 +58,9 @@ class App extends React.Component<IAppProps> {
return ( return (
<div className="App font-sans h-full"> <div className="App font-sans h-full">
<Sidebar componentOptions={this.state.configuration.AvailableContainers} isOpen={this.state.isSidebarOpen} onClick={() => this.ToggleSidebar()} /> <Sidebar componentOptions={this.state.configuration.AvailableContainers} isOpen={this.state.isSidebarOpen} onClick={() => this.ToggleSidebar()} />
<button className='fixed z-0 top-4 left-4 text-lg bg-blue-200 hover:bg-blue-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleSidebar()}>&#9776; Menu</button> <button className='fixed z-10 top-4 left-4 text-lg bg-blue-200 hover:bg-blue-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleSidebar()}>&#9776; Menu</button>
<SVGSidebar isOpen={this.state.isSVGSidebarOpen} onClick={() => this.ToggleSVGSidebar()}/> <SVGSidebar isOpen={this.state.isSVGSidebarOpen} onClick={() => this.ToggleSVGSidebar()}/>
<button className='fixed z-0 top-4 right-4 text-lg bg-slate-200 hover:bg-slate-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleSVGSidebar()}>&#9776; Menu</button> <button className='fixed z-10 top-4 right-12 text-lg bg-slate-200 hover:bg-slate-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleSVGSidebar()}>&#9776; Menu</button>
<SVG MainContainer={this.state.configuration.MainContainer} /> <SVG MainContainer={this.state.configuration.MainContainer} />
</div> </div>
); );

View file

@ -9,7 +9,7 @@ export class SVGSidebar extends React.Component<ISVGSidebarProps> {
public render() { public render() {
const isOpenClasses = this.props.isOpen ? 'right-0' : '-right-64'; const isOpenClasses = this.props.isOpen ? 'right-0' : '-right-64';
return ( return (
<div className={`fixed bg-slate-400 text-white transition-all h-screen w-64 overflow-y-auto z-10 ${isOpenClasses}`}> <div className={`fixed bg-slate-400 text-white transition-all h-screen w-64 overflow-y-auto z-20 ${isOpenClasses}`}>
<div className='w-full h-auto p-4 flex justify-start' onClick={this.props.onClick}> <div className='w-full h-auto p-4 flex justify-start' onClick={this.props.onClick}>
<button className='text-lg'>&times;</button> <button className='text-lg'>&times;</button>
</div> </div>

View file

@ -17,7 +17,7 @@ export default class Sidebar extends React.Component<ISidebarProps> {
const isOpenClasses = this.props.isOpen ? 'left-0' : '-left-64'; const isOpenClasses = this.props.isOpen ? 'left-0' : '-left-64';
return ( return (
<div className={`fixed bg-blue-500 dark:bg-blue-500 text-white transition-all h-screen w-64 overflow-y-auto z-10 ${isOpenClasses}`}> <div className={`fixed bg-blue-500 dark:bg-blue-500 text-white transition-all h-screen w-64 overflow-y-auto z-20 ${isOpenClasses}`}>
<div className='w-full h-auto p-4 flex justify-end' onClick={this.props.onClick}> <div className='w-full h-auto p-4 flex justify-end' onClick={this.props.onClick}>
<button className='text-lg'>&times;</button> <button className='text-lg'>&times;</button>
</div> </div>

View file

@ -2,14 +2,16 @@ import * as React from 'react';
import { AvailableContainer } from '../Interfaces/AvailableContainer'; import { AvailableContainer } from '../Interfaces/AvailableContainer';
import { Container } from './Elements/Container'; import { Container } from './Elements/Container';
import { MainContainer } from './Elements/MainContainer'; import { MainContainer } from './Elements/MainContainer';
import * as SvgPanZoom from 'svg-pan-zoom'; import { ReactSVGPanZoom, Tool, Value, TOOL_PAN } from 'react-svg-pan-zoom';
interface ISVGProps { interface ISVGProps {
MainContainer: AvailableContainer MainContainer: AvailableContainer
} }
interface ISVGState { interface ISVGState {
viewBox: number[] viewBox: number[],
value: Value,
tool: Tool
} }
export class SVG extends React.Component<ISVGProps> { export class SVG extends React.Component<ISVGProps> {
@ -24,7 +26,14 @@ export class SVG extends React.Component<ISVGProps> {
0, 0,
window.innerWidth, window.innerWidth,
window.innerHeight window.innerHeight
] ],
value: {
viewerWidth: window.innerWidth,
viewerHeight: window.innerHeight,
SVGHeight: this.props.MainContainer.Height,
SVGWidth: this.props.MainContainer.Width
} as Value,
tool: TOOL_PAN
}; };
this.svg = React.createRef<SVGSVGElement>(); this.svg = React.createRef<SVGSVGElement>();
} }
@ -41,16 +50,11 @@ export class SVG extends React.Component<ISVGProps> {
} }
componentDidMount() { componentDidMount() {
if (this.svg === null || window.addEventListener('resize', this.resizeViewBox.bind(this));
this.svg === undefined ||
this.svg.current === null) {
return;
} }
const settings: SvgPanZoom.Options = {
zoomScaleSensitivity: 1
};
SvgPanZoom(this.svg.current, settings); componentWillUnmount() {
window.removeEventListener('resize', this.resizeViewBox.bind(this));
} }
render() { render() {
@ -64,6 +68,14 @@ export class SVG extends React.Component<ISVGProps> {
const children: Container[] = []; const children: Container[] = [];
return ( return (
<ReactSVGPanZoom
width={window.innerWidth}
height={window.innerHeight}
background={'#ffffff'}
defaultTool='pan'
value={this.state.value} onChangeValue={value => this.setState({ value })}
tool={this.state.tool} onChangeTool={tool => this.setState({ tool })}
>
<svg ref={this.svg} {...properties}> <svg ref={this.svg} {...properties}>
<MainContainer <MainContainer
width={this.props.MainContainer.Width} width={this.props.MainContainer.Width}
@ -72,6 +84,7 @@ export class SVG extends React.Component<ISVGProps> {
{ children } { children }
</MainContainer> </MainContainer>
</svg> </svg>
</ReactSVGPanZoom>
); );
}; };
} }

View file

@ -3,7 +3,7 @@
"target": "ESNext", "target": "ESNext",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"], "lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false, "allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"esModuleInterop": false, "esModuleInterop": false,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,

View file

@ -1,7 +1,7 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()] plugins: [react()]
}) });