From 4e3bf7e8d2f020db568b581827d2672293c0eb73 Mon Sep 17 00:00:00 2001 From: tk338g Date: Mon, 8 Feb 2021 00:55:22 +0100 Subject: [PATCH] Use one canvas for minimap and preserve viewport borders --- src/components/MiniMap.tsx | 86 +++++++++++++------------------------- 1 file changed, 30 insertions(+), 56 deletions(-) diff --git a/src/components/MiniMap.tsx b/src/components/MiniMap.tsx index c2bc58453..7f3bb9dfb 100644 --- a/src/components/MiniMap.tsx +++ b/src/components/MiniMap.tsx @@ -1,34 +1,17 @@ import "./MiniMap.scss"; import React, { useEffect, useRef } from "react"; -import { unmountComponentAtNode, render } from "react-dom"; -import { canvasToBlob } from "../data/blob"; import { getCommonBounds } from "../element"; import { NonDeletedExcalidrawElement } from "../element/types"; -import { CanvasError } from "../errors"; import { exportToCanvas } from "../scene/export"; import { AppState } from "../types"; import { distance, viewportCoordsToSceneCoords } from "../utils"; -import { ErrorCanvasPreview } from "./ExportDialog"; import { Island } from "./Island"; const RATIO = 1.2; const MINIMAP_HEIGHT = 150; const MINIMAP_WIDTH = MINIMAP_HEIGHT * RATIO; -const renderPreview = ( - content: HTMLCanvasElement | Error, - previewNode: HTMLDivElement, -) => { - unmountComponentAtNode(previewNode); - previewNode.innerHTML = ""; - if (content instanceof HTMLCanvasElement) { - previewNode.appendChild(content); - } else { - render(, previewNode); - } -}; - const MinimapViewport = ({ elements, appState, @@ -40,10 +23,11 @@ const MinimapViewport = ({ return null; } - const [minX, minY, canvasWidth, canvasHeight] = getCanvasSize(elements); + const [minX, minY, maxX, maxY] = getCommonBounds(elements); + const minimapScale = Math.min( - MINIMAP_WIDTH / canvasWidth, - MINIMAP_HEIGHT / canvasHeight, + MINIMAP_WIDTH / distance(minX, maxX), + MINIMAP_HEIGHT / distance(minY, maxY), ); const leftTop = viewportCoordsToSceneCoords( @@ -60,6 +44,20 @@ const MinimapViewport = ({ const width = (rightBot.x - leftTop.x) * minimapScale; const height = (rightBot.y - leftTop.y) * minimapScale; + // Set viewport boundaries + const viewportTop = Math.min(Math.max(0, top), MINIMAP_HEIGHT); + const viewportLeft = Math.min(Math.max(0, left), MINIMAP_WIDTH); + const viewportWidth = Math.min( + MINIMAP_WIDTH - viewportLeft, + width, + width + left, + ); + const viewportHeight = Math.min( + MINIMAP_HEIGHT - viewportTop, + height, + height + top, + ); + return (
); }; -const getCanvasSize = ( - elements: readonly NonDeletedExcalidrawElement[], -): [number, number, number, number] => { - const [minX, minY, maxX, maxY] = getCommonBounds(elements); - const width = distance(minX, maxX); - const height = distance(minY, maxY); - - return [minX, minY, width, height]; -}; - export function MiniMap({ appState, elements, @@ -93,20 +81,16 @@ export function MiniMap({ appState: AppState; elements: readonly NonDeletedExcalidrawElement[]; }) { - const previewRef = useRef(null); + const canvasRef = useRef(null); const appStateRef = useRef(appState); appStateRef.current = appState; useEffect(() => { - const previewNode = previewRef.current; - if (!previewNode) { + const canvasNode = canvasRef.current; + if (!canvasNode) { return; } - if (elements.length === 0) { - unmountComponentAtNode(previewNode); - previewNode.innerHTML = ""; - } - const canvas = exportToCanvas( + exportToCanvas( elements, appStateRef.current, { @@ -115,26 +99,16 @@ export function MiniMap({ shouldAddWatermark: false, }, (width, height) => { - const tempCanvas = document.createElement("canvas"); const scale = Math.min(MINIMAP_WIDTH / width, MINIMAP_HEIGHT / height); - tempCanvas.width = width * scale; - tempCanvas.height = height * scale; + canvasNode.width = width * scale; + canvasNode.height = height * scale; return { - canvas: tempCanvas, + canvas: canvasNode, scale, }; }, ); - - canvasToBlob(canvas) - .then(() => { - renderPreview(canvas, previewNode); - }) - .catch((error) => { - console.error(error); - renderPreview(new CanvasError(), previewNode); - }); }, [elements]); return ( @@ -147,7 +121,7 @@ export function MiniMap({ backgroundColor: appState.viewBackgroundColor, }} > -
+