Use a input type range to zoom ?
Hi ! I would like to know , if it was possible to use a input type range to zoom ? if we can, Could you show me how ?
Thanks
You just need to store the value of the input in state, then you can use it to control the scale.
<TransformWrapper>
{props => (
<>
<TransformComponent>{children}</TransformComponent>
<ZoomControl {...props} />
</>
)}
</TransformWrapper>
const ZoomControl = ({ scale, setScale, options }) => {
const [value, setValue] = useState(scale)
useEffect(() => {
setScale(value)
}, [value])
return (
<input
type="range"
min={options.minScale}
max={options.maxScale}
value={value}
onChange={e => setValue(e.target.value)}
/>
)
}
@arsmth Do you know how using a range make zoom center of the screen?
Do you know how using a range make zoom center of the screen?
Not 100% sure what you want without more information but I'll presume you want to control the position with a range input in which case you could just do the same as above but with position instead of scale. Check the readme for the list of available props.
@arsmth I meant, when you use 'setScale' the screen go to the top-left corner. And how to make when I am using 'setScale' it will scale the center of the screen? (I used props like 'positionX', 'positionY' - they didnt help me)
try it here : codesandbox
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
import { useRef, useState } from "react";
// Style
const MainWrapper = {
background: "salmon",
width: "100%",
height: "100vh",
position: "relative"
};
const InputWrapper = {
position: "fixed",
zIndex: 9999,
width: "100%"
};
const ScaleIndicator = {
textAlign: "right",
position: "absolute",
right: "40px",
background: "blue",
color: "white",
zIndex: "1000",
padding: "10px"
};
const Slider = {
width: "200px",
margin: "10px 30px"
};
export default function App() {
const transformComponentRef = useRef(null);
const [scale, setScale] = useState(0.7);
const updateScale = (e) => {
const targetScale = parseFloat(e.target.value);
const factor = Math.log(targetScale / scale);
const { zoomIn, zoomOut } = transformComponentRef.current;
/*
how react-zoom-pan-pinch calculate new scale :
targetScale = scale * Math.exp(1 * factor);
we need factor(step) for zoomIn and zoomOut, just reverse the previous equation to get factor
factor = Math.log(targetScale / currentScale);
*/
// console.log(scale * Math.exp(1 * factor), targetScale);
if (targetScale > scale) {
zoomIn(factor, 0);
} else {
zoomOut(-factor, 0);
}
setScale(targetScale);
};
return (
<div style={MainWrapper}>
<h1 style={ScaleIndicator}>{(scale * 100).toFixed(0)}%</h1>
<div style={InputWrapper}>
<input
type="range"
min="0.1"
max="1.5"
step="0.01"
value={scale}
onChange={updateScale}
style={Slider}
/>
</div>
<TransformWrapper
ref={transformComponentRef}
onZoomStop={(e) => {
setScale(e.state.scale);
}}
initialScale={scale}
minScale={0.1}
maxScale={1.5}
doubleClick={{
disabled: true
}}
// wheel={{
// activationKeys: ["z"]
// }}
// panning={{
// activationKeys: ["x"],
// }}
limitToBounds={false}
zoomAnimation={{ disabled: true }}
centerOnInit
onZoom={(e) => {
setScale(e.state.scale);
}}
>
{({ zoomIn, zoomOut, setTransform, ...rest }) => {
return (
<TransformComponent
wrapperStyle={{
width: "100%",
height: "100%"
}}
>
<img
src="https://images.pexels.com/photos/2450218/pexels-photo-2450218.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
alt="Cool Astro"
/>
</TransformComponent>
);
}}
</TransformWrapper>
</div>
);
}
try it here : codesandbox
Now it's even easier having hooks for interacting with context 👍