Есть вот такой компонент для кастомного Canvas
import { useResize } from "@/hooks";
import {
ComponentPropsWithoutRef,
forwardRef,
useEffect,
useImperativeHandle,
useRef,
} from "react";
export const Canvas = forwardRef<
HTMLCanvasElement,
ComponentPropsWithoutRef<"canvas">
>((props, ref) => {
const innerRef = useRef<HTMLCanvasElement | null>(null);
const canvasRef = (ref as React.RefObject<HTMLCanvasElement>) || innerRef;
const { width } = useResize();
useImperativeHandle(ref, () => canvasRef.current, [canvasRef]);
useEffect(() => {
const dpr = window.devicePixelRatio || 1;
if (dpr < 1 || !canvasRef.current) {
return;
}
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
if (!ctx) {
return;
}
const rect = canvas.getBoundingClientRect();
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
ctx.scale(dpr, dpr);
canvas.style.width = `${rect.width}px`;
canvas.style.height = `${rect.height}px`;
}, [width, canvasRef.current]);
return (
<canvas
{...props}
ref={canvasRef}
/>
);
});
В useEffect описана логика, для high dpr устройств, ну и полагаю для масштабирования на ctrl + mousewheel должно работать также.
Проблема в том, что вроде бы работает масштабирование, но когда доходит дело до стилей (т.е. применение старых размеров, что бы сам canvas не был гигантским), сам canvas меньше становится, а содержимое, как было огромным, так и остается.
На canvas рисуются графики, обновляются каждую секунду.