The issue you're facing is related to how the scaling and scrolling behavior is managed within your React component. When the canvas element scales up, it goes beyond the boundaries of its parent container, but only the bottom and right edges are scrollable while the left and top edges are not. This occurs due to the handling of CSS overflow and scaling.
To fix this problem, consider making the following adjustments:
Make sure the size of the parent container is fixed or properly controlled to allow scrolling in all directions.
Position the canvas correctly inside the parent container to ensure it remains centered when scaled.
Modify the overflow settings to handle the scaled canvas appropriately.
import { useEffect, useRef, useState } from "react";
export default function App() {
const canvasRef = useRef(null);
const parentRef = useRef(null);
const [scale, setScale] = useState(1);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
canvas.width = 800 * scale;
canvas.height = 450 * scale;
canvas.style.width = `${800 * scale}px`;
canvas.style.height = `${450 * scale}px`;
draw(ctx, scale);
}, [scale]);
const draw = (context, scale) => {
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.save();
context.fillStyle = "red";
context.fillRect(100 * scale, 100 * scale, 200 * scale, 100 * scale);
context.restore();
};
const onZoom = (add) => {
setScale((prev) => prev + add);
};
return (
<div
ref={parentRef}
style={{
// height: "100vh",
// width: "100vw",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
// overflow: "auto",
}}
>
<div
style={{
height: "100vh",
width: "100vw",
overflow: "scroll",
}}
>
<canvas
ref={canvasRef}
style={{ border: "2px solid red" }}
width={800}
height={450}
>
Drawing canvas
</canvas>
</div>
<div>
<button onClick={() => onZoom(0.1)}>+</button>
<button onClick={() => onZoom(-0.1)}>-</button>
</div>
</div>
);
}