I need to update viewBox values of SVG when the user triggers a mouse wheel event.
type viewBox = {
x: number;
y: number;
w: number;
h: number;
};
const [viewBox, setViewBox] = useState<viewBox>({
x: 0,
y: 0,
w: canvasArea.clientWidth,
h: canvasArea.clientHeight,
});
useEffect(() => {
svgContainer.onwheel = function (e: any) {
e.preventDefault();
var w = viewBox.w;
var h = viewBox.h;
var mx = e.offsetX;
var my = e.offsetY;
var dw = w * Math.sign(e.deltaY) * 0.05;
var dh = h * Math.sign(e.deltaY) * 0.05;
var dx = (dw * mx) / svgSize.w;
var dy = (dh * my) / svgSize.h;
setViewBox(
{
x: viewBox.x + dx,
y: viewBox.y + dy,
w: viewBox.w - dw,
h: viewBox.h - dh,
}
)
scale = svgSize.w / viewBox.w;
svg?.setAttribute(
"viewBox",
`${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`
);
};
),[viewBox]}
When I update my viewBox state like this, it makes slowing down my page on every mouse wheel event. Why is this happening? Should I use a different method for watching viewBox state?
Changing same state in useEffect which is in the dependency of useEffect will cause the rendering loop thats why it make your page slow. when state change which is use in useEfect dependency the useEffect run again and state change again beacuse of this useEffect run again and again...
just do this in onClick event to avoid re rendering
const onClickUpdateSvg = () => {
svgContainer.onwheel = function (e: any) {
e.preventDefault();
var w = viewBox.w;
var h = viewBox.h;
var mx = e.offsetX; // mouse x
var my = e.offsetY;
var dw = w * Math.sign(e.deltaY) * 0.05;
var dh = h * Math.sign(e.deltaY) * 0.05;
var dx = (dw * mx) / svgSize.w;
var dy = (dh * my) / svgSize.h;
setViewBox({
x: viewBox.x + dx,
y: viewBox.y + dy,
w: viewBox.w - dw,
h: viewBox.h - dh,
});
scale = svgSize.w / viewBox.w;
svg?.setAttribute(
"viewBox",
`${viewBox.x} ${viewBox.y} ${viewBox.w} ${viewBox.h}`
);
};
};