Updated answer using hooks and reversed zoom direction:
import React, { useState } from "react";
import Konva from "konva";
import { render } from "react-dom";
import { Stage, Layer, Circle } from "react-konva";
const App = () => {
const [stage, setStage] = useState({
scale: 1,
x: 0,
y: 0
});
const handleWheel = (e) => {
e.evt.preventDefault();
const scaleBy = 1.02;
const stage = e.target.getStage();
const oldScale = stage.scaleX();
const mousePointTo = {
x: stage.getPointerPosition().x / oldScale - stage.x() / oldScale,
y: stage.getPointerPosition().y / oldScale - stage.y() / oldScale
};
const newScale = e.evt.deltaY < 0 ? oldScale * scaleBy : oldScale / scaleBy;
setStage({
scale: newScale,
x: (stage.getPointerPosition().x / newScale - mousePointTo.x) * newScale,
y: (stage.getPointerPosition().y / newScale - mousePointTo.y) * newScale
});
};
return (
<Stage
width={window.innerWidth}
height={window.innerHeight}
onWheel={handleWheel}
scaleX={stage.scale}
scaleY={stage.scale}
x={stage.x}
y={stage.y}
>
<Layer>
<Circle
x={window.innerWidth / 2}
y={window.innerHeight / 2}
radius={50}
fill="green"
shadowBlur={5}
/>
</Layer>
</Stage>
);
};
render(<App />, document.getElementById("root"));
Demo: https://codesandbox.io/s/react-konva-zoom-on-scroll-demo-forked-70vsj