fix pan-zoom infinite loop
This commit is contained in:
parent
535d6b7426
commit
aaa19f213c
2 changed files with 33 additions and 44 deletions
|
@ -3,10 +3,7 @@ import { forwardRef, useContext } from 'react'
|
||||||
// Hooks
|
// Hooks
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
// Context
|
// Context
|
||||||
import {
|
import { PanZoomContext } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
|
||||||
PanZoomContext,
|
|
||||||
PanZoomCapture,
|
|
||||||
} from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
|
|
||||||
// Components
|
// Components
|
||||||
import { SizeMe } from 'react-sizeme'
|
import { SizeMe } from 'react-sizeme'
|
||||||
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
|
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
|
||||||
|
@ -40,8 +37,6 @@ export const PanZoomPattern = forwardRef((props, ref) => {
|
||||||
const { renderProps = false, components = {} } = props
|
const { renderProps = false, components = {} } = props
|
||||||
const { onTransformed, setZoomFunctions } = useContext(PanZoomContext)
|
const { onTransformed, setZoomFunctions } = useContext(PanZoomContext)
|
||||||
|
|
||||||
if (!renderProps) return null
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SizeMe refreshRate={64}>
|
<SizeMe refreshRate={64}>
|
||||||
{({ size }) => (
|
{({ size }) => (
|
||||||
|
@ -51,17 +46,13 @@ export const PanZoomPattern = forwardRef((props, ref) => {
|
||||||
wheel={{ activationKeys: ['Control'] }}
|
wheel={{ activationKeys: ['Control'] }}
|
||||||
doubleClick={{ mode: 'reset' }}
|
doubleClick={{ mode: 'reset' }}
|
||||||
onTransformed={onTransformed}
|
onTransformed={onTransformed}
|
||||||
|
onInit={setZoomFunctions}
|
||||||
>
|
>
|
||||||
{({ resetTransform, zoomIn, zoomOut }) => (
|
<TransformComponent>
|
||||||
<>
|
<div style={{ width: size.width + 'px' }} className="max-h-screen">
|
||||||
<PanZoomCapture {...{ setZoomFunctions, resetTransform, zoomIn, zoomOut }} />
|
<Pattern {...{ t, components, renderProps }} ref={ref} />
|
||||||
<TransformComponent>
|
</div>
|
||||||
<div style={{ width: size.width + 'px' }} className="max-h-screen">
|
</TransformComponent>
|
||||||
<Pattern {...{ t, components, renderProps }} ref={ref} />
|
|
||||||
</div>
|
|
||||||
</TransformComponent>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</TransformWrapper>
|
</TransformWrapper>
|
||||||
)}
|
)}
|
||||||
</SizeMe>
|
</SizeMe>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useMemo, useEffect } from 'react'
|
import React, { useState, useMemo, useCallback } from 'react'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A context for managing zoom state of a {@see PanZoomPattern}
|
* A context for managing zoom state of a {@see PanZoomPattern}
|
||||||
|
@ -9,40 +9,38 @@ export const PanZoomContext = React.createContext({})
|
||||||
/** Provider for the {@see PanZoomContext} */
|
/** Provider for the {@see PanZoomContext} */
|
||||||
export const PanZoomContextProvider = ({ children }) => {
|
export const PanZoomContextProvider = ({ children }) => {
|
||||||
const [zoomed, setZoomed] = useState(false)
|
const [zoomed, setZoomed] = useState(false)
|
||||||
const [_zoomFunctions, setZoomFunctions] = useState(false)
|
const [zoomFunctions, _setZoomFunctions] = useState(false)
|
||||||
|
|
||||||
|
const setZoomFunctions = useCallback(
|
||||||
|
(zoomInstance) => {
|
||||||
|
const reset = () => {
|
||||||
|
setZoomed(false)
|
||||||
|
zoomInstance.resetTransform()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoomInstance) {
|
||||||
|
const { zoomIn, zoomOut, resetTransform } = zoomInstance
|
||||||
|
_setZoomFunctions({ zoomIn, zoomOut, resetTransform, reset })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[_setZoomFunctions, setZoomed]
|
||||||
|
)
|
||||||
|
|
||||||
|
const onTransformed = useCallback(
|
||||||
|
(_ref, state) => {
|
||||||
|
setZoomed(state.scale !== 1)
|
||||||
|
},
|
||||||
|
[setZoomed]
|
||||||
|
)
|
||||||
|
|
||||||
const value = useMemo(() => {
|
const value = useMemo(() => {
|
||||||
const onTransformed = (_ref, state) => {
|
|
||||||
setZoomed(state.scale !== 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
const reset = () => {
|
|
||||||
setZoomed(false)
|
|
||||||
_zoomFunctions.resetTransform()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
zoomed,
|
zoomed,
|
||||||
zoomFunctions: _zoomFunctions ? { ..._zoomFunctions, reset } : false,
|
zoomFunctions,
|
||||||
setZoomFunctions,
|
setZoomFunctions,
|
||||||
onTransformed,
|
onTransformed,
|
||||||
}
|
}
|
||||||
}, [zoomed, setZoomed, _zoomFunctions, setZoomFunctions])
|
}, [zoomed, zoomFunctions, setZoomFunctions, onTransformed])
|
||||||
|
|
||||||
return <PanZoomContext.Provider value={value}>{children}</PanZoomContext.Provider>
|
return <PanZoomContext.Provider value={value}>{children}</PanZoomContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A component to capture the zoom functions and set them on the zoom context
|
|
||||||
* Place this inside of a TransformWrapper child function.
|
|
||||||
* See {@see PanZoomPattern} for an example
|
|
||||||
* */
|
|
||||||
export const PanZoomCapture = ({ resetTransform, zoomIn, zoomOut, setZoomFunctions }) => {
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof setZoomFunctions === 'function') {
|
|
||||||
setZoomFunctions({ resetTransform, zoomIn, zoomOut })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue