Skip to content
CanvasWrapper.tsx 1.91 KiB
Newer Older
Grant's avatar
Grant committed
import React, { createRef, useCallback, useContext, useEffect } from "react";
Grant's avatar
Grant committed
import { Canvas } from "../lib/canvas";
import { useAppContext } from "../contexts/AppContext";
import { PanZoomWrapper } from "@sc07-canvas/lib/src/renderer";
Grant's avatar
Grant committed
import { RendererContext } from "@sc07-canvas/lib/src/renderer/RendererContext";
Grant's avatar
Grant committed
import { ViewportMoveEvent } from "@sc07-canvas/lib/src/renderer/PanZoom";
import throttle from "lodash.throttle";
import { ICanvasPosition } from "../types";
import { Routes } from "../lib/routes";
Grant's avatar
Grant committed

export const CanvasWrapper = () => {
  // to prevent safari from blurring things, use the zoom css property
  return (
    <main>
      <PanZoomWrapper>
        <CanvasInner />
      </PanZoomWrapper>
Grant's avatar
Grant committed
    </main>
  );
};

const CanvasInner = () => {
  const canvasRef = createRef<HTMLCanvasElement>();
Grant's avatar
Grant committed
  const { config, setCanvasPosition } = useAppContext();
Grant's avatar
Grant committed
  const PanZoom = useContext(RendererContext);
  // const { centerView } = useControls();
Grant's avatar
Grant committed

  useEffect(() => {
    if (!config.canvas || !canvasRef.current) return;
    const canvas = canvasRef.current!;
Grant's avatar
Grant committed
    const canvasInstance = new Canvas(config, canvas, PanZoom);
    // centerView();
Grant's avatar
Grant committed

Grant's avatar
Grant committed
    const handleViewportMove = throttle((state: ViewportMoveEvent) => {
      const pos = canvasInstance.panZoomTransformToCanvas();

      const canvasPosition: ICanvasPosition = {
        x: pos.canvasX,
        y: pos.canvasY,
        zoom: state.scale >> 0,
      };

      setCanvasPosition(canvasPosition);

      window.location.replace(Routes.canvas(canvasPosition));
    }, 1000);

    PanZoom.addListener("viewportMove", handleViewportMove);

Grant's avatar
Grant committed
    return () => {
      canvasInstance.destroy();
Grant's avatar
Grant committed
      PanZoom.removeListener("viewportMove", handleViewportMove);
Grant's avatar
Grant committed
    };
Grant's avatar
Grant committed
  }, [PanZoom, canvasRef, config, setCanvasPosition]);
Grant's avatar
Grant committed

  return (
    <canvas
      id="board"
      width="1000"
      height="1000"
      className="pixelate"
      ref={canvasRef}
    ></canvas>
  );
};