Skip to content

Commit

Permalink
upgrades to storybook v6 and react v17 (#187)
Browse files Browse the repository at this point in the history
* upgrades to storybook v6 and react v17

* fixes build script

* code clean

* upgrade storybook and react

* adds StandardViewer story

* removes deprecated knobs

* refactors examples to stateless functions, leveraging on hooks

* updates docs

* fixes constant import

* upgrades transformation-matrix
  • Loading branch information
chrvadala authored Jan 6, 2021
1 parent 0a1eee2 commit 08b9d22
Show file tree
Hide file tree
Showing 44 changed files with 8,746 additions and 9,973 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ examples/*/yarn.lock
build-*
.cache
coverage
.eslintcache
54 changes: 34 additions & 20 deletions docs/autosizer-viewer.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,41 @@
# React SVG Pan Zoom - Autosizer viewer

**React SVG Pan Zoom** requires the properties `width` and `height` to be set in order to work properly.
If you need to automatically adapt the viewer size on the parent size you can use the component [AutoSizer](https://github.com/bvaughn/react-virtualized/blob/master/docs/AutoSizer.md).
This component is able to extract `width` and `height` from the parent box and pass them to a children component.
**React SVG Pan Zoom** requires the properties `width` and `height` to be set in order to work properly.
If you need to automatically adapt the viewer size on the parent size you can use the hook [useWindowSize](https://www.npmjs.com/package/@react-hook/window-size).
This component is able to extract `width` and `height` from the parent box and pass them to a children component.

## Example
```jsx harmony
import {AutoSizer} from 'react-virtualized';
import {useWindowSize} from '@react-hook/window-size'

<div style={{width: "100%", height: "100%"}}>
<AutoSizer>
{(({width, height}) => width === 0 || height === 0 ? null : (
<ReactSVGPanZoom width={width} height={height}>
<svg width={1440} height={1440}>
<g>
<rect x="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142"/>
<circle cx="108" cy="108.5" r="100" fill="#0ff" stroke="#0ff"/>
<circle cx="180" cy="209.5" r="100" fill="#ff0" stroke="#ff0"/>
<circle cx="220" cy="109.5" r="100" fill="#f0f" stroke="#f0f"/>
</g>
</svg>
</ReactSVGPanZoom>
))}
</AutoSizer>
</div>
export const Resizable = (args) => {
const Viewer = useRef(null);
const [tool, onChangeTool] = useState(TOOL_NONE)
const [value, onChangeValue] = useState(INITIAL_VALUE)
const [width, height] = useWindowSize({initialWidth: 400, initialHeight: 400})

useLayoutEffect(() => {
Viewer.current.fitToViewer();
}, []);

return (
<div style={{width: "100%", height: "100%"}}>
<ReactSVGPanZoom
width={width} height={height}
ref={Viewer}
value={value} onChangeValue={onChangeValue}
tool={tool} onChangeTool={onChangeTool}
>
<svg width={500} height={500}>
<g>
<rect x="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142"/>
<circle cx="108" cy="108.5" r="100" fill="#0ff" stroke="#0ff"/>
<circle cx="180" cy="209.5" r="100" fill="#ff0" stroke="#ff0"/>
<circle cx="220" cy="109.5" r="100" fill="#f0f" stroke="#f0f"/>
</g>
</svg>
</ReactSVGPanZoom>
</div>
)
}
```
224 changes: 99 additions & 125 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,140 +16,114 @@ yarn add react-svg-pan-zoom
The full source code is available here: [source code](../examples/uncontrolled-component).

```javascript
import React from 'react';
import React, {useRef, useEffect} from 'react';
import {UncontrolledReactSVGPanZoom} from 'react-svg-pan-zoom';

export default class App extends React.PureComponent {

Viewer = null

componentDidMount() {
this.Viewer.fitToViewer();
}

render() {
return (
<div>
<button className="btn" onClick={() => this.Viewer.zoomOnViewerCenter(1.1)}>Zoom in</button>
<button className="btn" onClick={() => this.Viewer.fitSelection(40, 40, 200, 200)}>Zoom area 200x200</button>
<button className="btn" onClick={() => this.Viewer.fitToViewer()}>Fit</button>

<hr/>

<UncontrolledReactSVGPanZoom
width={500} height={500}
ref={Viewer => this.Viewer = Viewer}

onClick={event => console.log('click', event.x, event.y, event.originalEvent)}
>
<svg width={617} height={316}> {/* or <svg viewBox="0 0 617 316" */}
<g fillOpacity=".5" strokeWidth="4">
<rect x="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142"/>
<circle cx="108" cy="108.5" r="100" fill="#0ff" stroke="#0ff"/>
<circle cx="180" cy="209.5" r="100" fill="#ff0" stroke="#ff0"/>
<circle cx="220" cy="109.5" r="100" fill="#f0f" stroke="#f0f"/>
</g>
</svg>
</UncontrolledReactSVGPanZoom>
</div>
);
}

export default function App() {
const Viewer = useRef(null);

useEffect(() => {
Viewer.current.fitToViewer();
}, []);

/* Read all the available methods in the documentation */
const _zoomOnViewerCenter = () => Viewer.current.zoomOnViewerCenter(1.1)
const _fitSelection = () => Viewer.current.fitSelection(40, 40, 200, 200)
const _fitToViewer = () => Viewer.current.fitToViewer()

return (
<div>
<h1>UncontrolledReactSVGPanZoom</h1>
<hr/>

<button className="btn" onClick={() => _zoomOnViewerCenter()}>Zoom on center</button>
<button className="btn" onClick={() => _fitSelection()}>Zoom area 200x200</button>
<button className="btn" onClick={() => _fitToViewer()}>Fit</button>
<hr/>

<UncontrolledReactSVGPanZoom
ref={Viewer}
width={500} height={500}
onZoom={e => console.log('zoom')}
onPan={e => console.log('pan')}
onClick={event => console.log('click', event.x, event.y, event.originalEvent)}
>
<svg width={617} height={316}>
<g fillOpacity=".5" strokeWidth="4">
<rect x="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142"/>
<circle cx="108" cy="108.5" r="100" fill="#0ff" stroke="#0ff"/>
<circle cx="180" cy="209.5" r="100" fill="#ff0" stroke="#ff0"/>
<circle cx="220" cy="109.5" r="100" fill="#f0f" stroke="#f0f"/>
</g>
</svg>
</UncontrolledReactSVGPanZoom>
</div>
)
}
```

## `<ReactSVGPanZoom>`
The full source code is available here: [source code](../examples/controlled-component).

```javascript
import React from 'react';
import {
fitSelection,
fitToViewer,
INITIAL_VALUE,
ReactSVGPanZoom,
TOOL_NONE,
zoomOnViewerCenter
} from 'react-svg-pan-zoom';

export default class App extends React.PureComponent {

state = {tool: TOOL_NONE, value: INITIAL_VALUE}
Viewer = null

componentDidMount() {
this.Viewer.fitToViewer();
}

changeTool(nextTool) {
this.setState({tool: nextTool})
}

changeValue(nextValue) {
this.setState({value: nextValue})
}

fitToViewer_1() {
this.setState(state => ({value: fitToViewer(state.value)}))
}

fitToViewer_2() {
this.Viewer.fitToViewer()
}

fitSelection_1() {
this.setState(state => ({value: fitSelection(state.value, 40, 40, 200, 200)}))
}

fitSelection_2() {
this.Viewer.fitSelection(40, 40, 200, 200)
}

zoomOnViewerCenter_1() {
this.setState(state => ({value: zoomOnViewerCenter(state.value, 1.1)}))
}

zoomOnViewerCenter_2() {
this.Viewer.zoomOnViewerCenter(1.1)
}

render() {
return (
<div>
<button className="btn" onClick={() => this.zoomOnViewerCenter_1()}>Zoom in</button>
<button className="btn" onClick={() => this.fitSelection_1()}>Zoom area 200x200</button>
<button className="btn" onClick={() => this.fitToViewer_1()}>Fit</button>

<strong>OR</strong>
{/* keep attention in this way onZoom and onPan cb aren't called */}
<button className="btn" onClick={() => this.zoomOnViewerCenter_2()}>Zoom in</button>
<button className="btn" onClick={() => this.fitSelection_2()}>Zoom area 200x200</button>
<button className="btn" onClick={() => this.fitToViewer_2()}>Fit</button>

<hr/>

<ReactSVGPanZoom
width={500} height={500}
ref={Viewer => this.Viewer = Viewer}
tool={this.state.tool} onChangeTool={tool => this.changeTool(tool)}
value={this.state.value} onChangeValue={value => this.changeValue(value)}

onZoom={e => console.log('zoom')}
onPan={e => console.log('pan')}

onClick={event => console.log('click', event.x, event.y, event.originalEvent)}
>
<svg width={617} height={316}> {/* or <svg viewBox="0 0 617 316" */}
<g fillOpacity=".5" strokeWidth="4">
<rect x="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142"/>
<circle cx="108" cy="108.5" r="100" fill="#0ff" stroke="#0ff"/>
<circle cx="180" cy="209.5" r="100" fill="#ff0" stroke="#ff0"/>
<circle cx="220" cy="109.5" r="100" fill="#f0f" stroke="#f0f"/>
</g>
</svg>
</ReactSVGPanZoom>
</div>
);
}
import {useRef, useState, useEffect} from 'react';
import {INITIAL_VALUE, ReactSVGPanZoom, TOOL_NONE, fitSelection, zoomOnViewerCenter, fitToViewer} from 'react-svg-pan-zoom';

export default function App() {
const Viewer = useRef(null);
const [tool, setTool] = useState(TOOL_NONE)
const [value, setValue] = useState(INITIAL_VALUE)

useEffect(() => {
Viewer.current.fitToViewer();
}, []);

/* Read all the available methods in the documentation */
const _zoomOnViewerCenter1 = () => Viewer.current.zoomOnViewerCenter(1.1)
const _fitSelection1 = () => Viewer.current.fitSelection(40, 40, 200, 200)
const _fitToViewer1 = () => Viewer.current.fitToViewer()

/* keep attention! handling the state in the following way doesn't fire onZoom and onPam hooks */
const _zoomOnViewerCenter2 = () => setValue(zoomOnViewerCenter(value, 1.1))
const _fitSelection2 = () => setValue(fitSelection(value, 40, 40, 200, 200))
const _fitToViewer2 = () => setValue(fitToViewer(value))

return (
<div>
<h1>ReactSVGPanZoom</h1>
<hr/>

<button className="btn" onClick={() => _zoomOnViewerCenter1()}>Zoom on center (mode 1)</button>
<button className="btn" onClick={() => _fitSelection1()}>Zoom area 200x200 (mode 1)</button>
<button className="btn" onClick={() => _fitToViewer1()}>Fit (mode 1)</button>
<hr/>

<button className="btn" onClick={() => _zoomOnViewerCenter2()}>Zoom on center (mode 2)</button>
<button className="btn" onClick={() => _fitSelection2()}>Zoom area 200x200 (mode 2)</button>
<button className="btn" onClick={() => _fitToViewer2()}>Fit (mode 2)</button>
<hr/>

<ReactSVGPanZoom
ref={Viewer}
width={500} height={500}
tool={tool} onChangeTool={setTool}
value={value} onChangeValue={setValue}
onZoom={e => console.log('zoom')}
onPan={e => console.log('pan')}
onClick={event => console.log('click', event.x, event.y, event.originalEvent)}
>
<svg width={617} height={316}>
<g fillOpacity=".5" strokeWidth="4">
<rect x="400" y="40" width="100" height="200" fill="#4286f4" stroke="#f4f142"/>
<circle cx="108" cy="108.5" r="100" fill="#0ff" stroke="#0ff"/>
<circle cx="180" cy="209.5" r="100" fill="#ff0" stroke="#ff0"/>
<circle cx="220" cy="109.5" r="100" fill="#f0f" stroke="#f0f"/>
</g>
</svg>
</ReactSVGPanZoom>
</div>
)
}
```

Expand Down
1 change: 0 additions & 1 deletion examples/controlled-component-advanced-usage/.env

This file was deleted.

9 changes: 0 additions & 9 deletions examples/controlled-component-advanced-usage/README.md

This file was deleted.

23 changes: 0 additions & 23 deletions examples/controlled-component-advanced-usage/package.json

This file was deleted.

12 changes: 0 additions & 12 deletions examples/controlled-component-advanced-usage/public/index.html

This file was deleted.

Loading

0 comments on commit 08b9d22

Please sign in to comment.