Quellcode durchsuchen

feat: update renderConfig to move and scale content

Arnošt Pleskot vor 2 Jahren
Ursprung
Commit
c731bd13b6
2 geänderte Dateien mit 111 neuen und 32 gelöschten Zeilen
  1. 38 6
      src/scene/export.ts
  2. 73 26
      src/scene/fancyBackground.ts

+ 38 - 6
src/scene/export.ts

@@ -4,7 +4,12 @@ import { getCommonBounds, getElementAbsoluteCoords } from "../element/bounds";
 import { renderSceneToSvg, renderStaticScene } from "../renderer/renderScene";
 import { distance, isOnlyExportingSingleFrame } from "../utils";
 import { AppState, BinaryFiles } from "../types";
-import { DEFAULT_EXPORT_PADDING, SVG_NS, THEME_FILTER } from "../constants";
+import {
+  DEFAULT_EXPORT_PADDING,
+  SVG_NS,
+  THEME,
+  THEME_FILTER,
+} from "../constants";
 import { getDefaultAppState } from "../appState";
 import { serializeAsJSON } from "../data/json";
 import {
@@ -41,7 +46,7 @@ export const exportToCanvas = async (
 ) => {
   const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);
 
-  const { canvas, scale = 1 } = createCanvas(width, height);
+  let { canvas, scale = 1 } = createCanvas(width, height);
 
   const defaultAppState = getDefaultAppState();
 
@@ -55,12 +60,39 @@ export const exportToCanvas = async (
 
   const onlyExportingSingleFrame = isOnlyExportingSingleFrame(elements);
 
+  let renderConfig = {
+    viewBackgroundColor:
+      exportBackground && !appState.fancyBackgroundImageUrl
+        ? viewBackgroundColor
+        : null,
+    scrollX: -minX + (onlyExportingSingleFrame ? 0 : exportPadding),
+    scrollY: -minY + (onlyExportingSingleFrame ? 0 : exportPadding),
+    zoom: defaultAppState.zoom,
+    remotePointerViewportCoords: {},
+    remoteSelectedElementIds: {},
+    shouldCacheIgnoreZoom: false,
+    remotePointerUsernames: {},
+    remotePointerUserStates: {},
+    theme: appState.exportWithDarkMode ? THEME.DARK : THEME.LIGHT,
+    imageCache,
+    renderScrollbars: false,
+    renderSelection: false,
+    renderGrid: false,
+    isExporting: true,
+    exportBackgroundImage: appState.fancyBackgroundImageUrl,
+  };
+
   if (appState.fancyBackgroundImageUrl) {
-    await applyFancyBackground(
+    const updatedRenderProps = await applyFancyBackground({
       canvas,
-      appState.fancyBackgroundImageUrl,
-      viewBackgroundColor,
-    );
+      fancyBackgroundImageUrl: appState.fancyBackgroundImageUrl,
+      backgroundColor: viewBackgroundColor,
+      scale,
+      renderConfig,
+    });
+
+    renderConfig = updatedRenderProps.renderConfig;
+    scale = updatedRenderProps.scale;
   }
 
   renderStaticScene({

+ 73 - 26
src/scene/fancyBackground.ts

@@ -1,7 +1,12 @@
-import { FANCY_BG_BORDER_RADIUS, FANCY_BG_PADDING } from "../constants";
+import {
+  DEFAULT_EXPORT_PADDING,
+  FANCY_BG_BORDER_RADIUS,
+  FANCY_BG_PADDING,
+} from "../constants";
 import { loadHTMLImageElement } from "../element/image";
 import { roundRect } from "../renderer/roundRect";
 import { DataURL } from "../types";
+import { RenderConfig } from "./types";
 
 type Dimensions = { w: number; h: number };
 
@@ -25,23 +30,35 @@ const getScaleToFit = (contentSize: Dimensions, containerSize: Dimensions) => {
 
 const addImageBackground = (
   context: CanvasRenderingContext2D,
-  canvasWidth: number,
-  canvasHeight: number,
+  canvasDimensions: Dimensions,
   fancyBackgroundImage: HTMLImageElement,
 ) => {
   context.save();
   context.beginPath();
   if (context.roundRect) {
-    context.roundRect(0, 0, canvasWidth, canvasHeight, FANCY_BG_BORDER_RADIUS);
+    context.roundRect(
+      0,
+      0,
+      canvasDimensions.w,
+      canvasDimensions.h,
+      FANCY_BG_BORDER_RADIUS,
+    );
   } else {
-    roundRect(context, 0, 0, canvasWidth, canvasHeight, FANCY_BG_BORDER_RADIUS);
+    roundRect(
+      context,
+      0,
+      0,
+      canvasDimensions.w,
+      canvasDimensions.h,
+      FANCY_BG_BORDER_RADIUS,
+    );
   }
   const scale = getScaleToFill(
     { w: fancyBackgroundImage.width, h: fancyBackgroundImage.height },
-    { w: canvasWidth, h: canvasHeight },
+    { w: canvasDimensions.w, h: canvasDimensions.h },
   );
-  const x = (canvasWidth - fancyBackgroundImage.width * scale) / 2;
-  const y = (canvasHeight - fancyBackgroundImage.height * scale) / 2;
+  const x = (canvasDimensions.w - fancyBackgroundImage.width * scale) / 2;
+  const y = (canvasDimensions.h - fancyBackgroundImage.height * scale) / 2;
   context.clip();
   context.drawImage(
     fancyBackgroundImage,
@@ -56,8 +73,7 @@ const addImageBackground = (
 
 const addContentBackground = (
   context: CanvasRenderingContext2D,
-  canvasWidth: number,
-  canvasHeight: number,
+  normalizedDimensions: Dimensions,
   contentBackgroundColor: string,
 ) => {
   const shadows = [
@@ -94,8 +110,8 @@ const addContentBackground = (
       context.roundRect(
         FANCY_BG_PADDING,
         FANCY_BG_PADDING,
-        canvasWidth - FANCY_BG_PADDING * 2,
-        canvasHeight - FANCY_BG_PADDING * 2,
+        normalizedDimensions.w - FANCY_BG_PADDING * 2,
+        normalizedDimensions.h - FANCY_BG_PADDING * 2,
         FANCY_BG_BORDER_RADIUS,
       );
     } else {
@@ -103,8 +119,8 @@ const addContentBackground = (
         context,
         FANCY_BG_PADDING,
         FANCY_BG_PADDING,
-        canvasWidth - FANCY_BG_PADDING * 2,
-        canvasHeight - FANCY_BG_PADDING * 2,
+        normalizedDimensions.w - FANCY_BG_PADDING * 2,
+        normalizedDimensions.h - FANCY_BG_PADDING * 2,
         FANCY_BG_BORDER_RADIUS,
       );
     }
@@ -118,23 +134,54 @@ const addContentBackground = (
   });
 };
 
-export const applyFancyBackground = async (
-  canvas: HTMLCanvasElement,
-  fancyBackgroundImageUrl: DataURL,
-  backgroundColor: string,
-) => {
+const updateRenderConfig = (
+  renderConfig: RenderConfig,
+  canvasDimensions: Dimensions,
+): { scale: number; renderConfig: RenderConfig } => {
+  const totalPadding =
+    FANCY_BG_PADDING + FANCY_BG_BORDER_RADIUS + DEFAULT_EXPORT_PADDING;
+
+  return {
+    renderConfig: {
+      ...renderConfig,
+      scrollX: renderConfig.scrollX + totalPadding,
+      scrollY: renderConfig.scrollY + totalPadding,
+    },
+    scale: getScaleToFit(canvasDimensions, {
+      w: canvasDimensions.w - totalPadding * 2,
+      h: canvasDimensions.h - totalPadding * 2,
+    }),
+  };
+};
+
+export const applyFancyBackground = async ({
+  canvas,
+  fancyBackgroundImageUrl,
+  backgroundColor,
+  renderConfig,
+}: {
+  canvas: HTMLCanvasElement;
+  fancyBackgroundImageUrl: DataURL;
+  backgroundColor: string;
+  scale: number;
+  renderConfig: RenderConfig;
+}) => {
   const context = canvas.getContext("2d")!;
 
   const fancyBackgroundImage = await loadHTMLImageElement(
     fancyBackgroundImageUrl,
   );
 
-  addImageBackground(
-    context,
-    canvas.width,
-    canvas.height,
-    fancyBackgroundImage,
-  );
+  const canvasDimensions: Dimensions = { w: canvas.width, h: canvas.height };
+
+  // const normalizedDimensions: Dimensions = {
+  //   w: canvas.width / scale,
+  //   h: canvas.height / scale,
+  // };
+
+  addImageBackground(context, canvasDimensions, fancyBackgroundImage);
+
+  addContentBackground(context, canvasDimensions, backgroundColor);
 
-  addContentBackground(context, canvas.width, canvas.height, backgroundColor);
+  return updateRenderConfig(renderConfig, canvasDimensions);
 };