Sfoglia il codice sorgente

Revert "Set scale for export images (#416)" (#420)

This reverts commit 82f559f826f4ab0504981a281335e0a25d332a6a.
Timur Khazamov 5 anni fa
parent
commit
d603921234

+ 0 - 6
src/components/ExportDialog.css

@@ -44,9 +44,3 @@
   justify-content: space-between;
   flex-wrap: wrap;
 }
-
-.ExportDialog__scales {
-  display: flex;
-  align-items: baseline;
-  justify-content: flex-end;
-}

+ 6 - 31
src/components/ExportDialog.tsx

@@ -18,11 +18,6 @@ const probablySupportsClipboard =
   "write" in navigator.clipboard &&
   "ClipboardItem" in window;
 
-const scales = [1, 2, 3];
-const defaultScale = scales.includes(devicePixelRatio) ? devicePixelRatio : 1;
-
-type ExportCB = (elements: readonly ExcalidrawElement[], scale: number) => void;
-
 export function ExportDialog({
   elements,
   appState,
@@ -37,12 +32,11 @@ export function ExportDialog({
   exportPadding?: number;
   actionManager: ActionsManagerInterface;
   syncActionResult: UpdaterFn;
-  onExportToPng: ExportCB;
-  onExportToClipboard: ExportCB;
+  onExportToPng(elements: readonly ExcalidrawElement[]): void;
+  onExportToClipboard(elements: readonly ExcalidrawElement[]): void;
 }) {
   const someElementIsSelected = elements.some(element => element.isSelected);
   const [modalIsShown, setModalIsShown] = useState(false);
-  const [scale, setScale] = useState(defaultScale);
   const [exportSelected, setExportSelected] = useState(someElementIsSelected);
   const previeRef = useRef<HTMLDivElement>(null);
   const { exportBackground, viewBackgroundColor } = appState;
@@ -60,8 +54,7 @@ export function ExportDialog({
     const canvas = getExportCanvasPreview(exportedElements, {
       exportBackground,
       viewBackgroundColor,
-      exportPadding,
-      scale
+      exportPadding
     });
     previewNode?.appendChild(canvas);
     return () => {
@@ -72,8 +65,7 @@ export function ExportDialog({
     exportedElements,
     exportBackground,
     exportPadding,
-    viewBackgroundColor,
-    scale
+    viewBackgroundColor
   ]);
 
   function handleClose() {
@@ -106,7 +98,7 @@ export function ExportDialog({
                     icon={downloadFile}
                     title="Export to PNG"
                     aria-label="Export to PNG"
-                    onClick={() => onExportToPng(exportedElements, scale)}
+                    onClick={() => onExportToPng(exportedElements)}
                   />
 
                   {probablySupportsClipboard && (
@@ -115,9 +107,7 @@ export function ExportDialog({
                       icon={clipboard}
                       title="Copy to clipboard"
                       aria-label="Copy to clipboard"
-                      onClick={() =>
-                        onExportToClipboard(exportedElements, scale)
-                      }
+                      onClick={() => onExportToClipboard(exportedElements)}
                     />
                   )}
                 </Stack.Row>
@@ -129,21 +119,6 @@ export function ExportDialog({
                   syncActionResult
                 )}
                 <Stack.Col gap={1}>
-                  <div className="ExportDialog__scales">
-                    <Stack.Row gap={1} align="baseline">
-                      {scales.map(s => (
-                        <ToolIcon
-                          size="s"
-                          type="radio"
-                          icon={"x" + s}
-                          name="export-canvas-scale"
-                          id="export-canvas-scale"
-                          checked={scale === s}
-                          onChange={() => setScale(s)}
-                        />
-                      ))}
-                    </Stack.Row>
-                  </div>
                   {actionManager.renderAction(
                     "changeExportBackground",
                     elements,

+ 1 - 1
src/components/Stack.tsx

@@ -5,7 +5,7 @@ import React from "react";
 type StackProps = {
   children: React.ReactNode;
   gap?: number;
-  align?: "start" | "center" | "end" | "baseline";
+  align?: "start" | "center" | "end";
 };
 
 function RowStack({ children, gap, align }: StackProps) {

+ 0 - 6
src/components/ToolIcon.scss

@@ -20,12 +20,6 @@
   }
 }
 
-.ToolIcon_size_s .ToolIcon__icon {
-  width: 25px;
-  height: 25px;
-  font-size: 0.8em;
-}
-
 .ToolIcon_type_button {
   padding: 0;
   border: none;

+ 2 - 10
src/components/ToolIcon.tsx

@@ -2,8 +2,6 @@ import "./ToolIcon.scss";
 
 import React from "react";
 
-type ToolIconSize = "s" | "m";
-
 type ToolIconProps =
   | {
       type: "button";
@@ -13,7 +11,6 @@ type ToolIconProps =
       name?: string;
       id?: string;
       onClick?(): void;
-      size?: ToolIconSize;
     }
   | {
       type: "radio";
@@ -23,17 +20,12 @@ type ToolIconProps =
       id?: string;
       checked: boolean;
       onChange?(): void;
-      size?: ToolIconSize;
     };
 
-const DEFAULT_SIZE: ToolIconSize = "m";
-
 export function ToolIcon(props: ToolIconProps) {
-  const sizeCn = `ToolIcon_size_${props.size || DEFAULT_SIZE}`;
-
   if (props.type === "button")
     return (
-      <label className={`ToolIcon ${sizeCn}`} title={props.title}>
+      <label className="ToolIcon" title={props.title}>
         <button
           className="ToolIcon_type_button"
           aria-label={props["aria-label"]}
@@ -46,7 +38,7 @@ export function ToolIcon(props: ToolIconProps) {
     );
 
   return (
-    <label className={`ToolIcon ${sizeCn}`} title={props.title}>
+    <label className="ToolIcon" title={props.title}>
       <input
         className="ToolIcon_type_radio"
         type="radio"

+ 9 - 14
src/index.tsx

@@ -478,23 +478,18 @@ export class App extends React.Component<{}, AppState> {
             appState={this.state}
             actionManager={this.actionManager}
             syncActionResult={this.syncActionResult}
-            onExportToPng={(exportedElements, scale) => {
+            onExportToPng={exportedElements => {
               if (this.canvas)
-                exportCanvas("png", exportedElements, this.canvas, {
-                  exportBackground: this.state.exportBackground,
-                  name: this.state.name,
-                  viewBackgroundColor: this.state.viewBackgroundColor,
-                  scale
-                });
+                exportCanvas("png", exportedElements, this.canvas, this.state);
             }}
-            onExportToClipboard={(exportedElements, scale) => {
+            onExportToClipboard={exportedElements => {
               if (this.canvas)
-                exportCanvas("clipboard", exportedElements, this.canvas, {
-                  exportBackground: this.state.exportBackground,
-                  name: this.state.name,
-                  viewBackgroundColor: this.state.viewBackgroundColor,
-                  scale
-                });
+                exportCanvas(
+                  "clipboard",
+                  exportedElements,
+                  this.canvas,
+                  this.state
+                );
             }}
           />
           {this.actionManager.renderAction(

+ 42 - 18
src/scene/data.ts

@@ -174,12 +174,10 @@ export function getExportCanvasPreview(
   {
     exportBackground,
     exportPadding = 10,
-    viewBackgroundColor,
-    scale = 1
+    viewBackgroundColor
   }: {
     exportBackground: boolean;
     exportPadding?: number;
-    scale?: number;
     viewBackgroundColor: string;
   }
 ) {
@@ -202,13 +200,8 @@ export function getExportCanvasPreview(
   }
 
   const tempCanvas = document.createElement("canvas");
-  const width = distance(subCanvasX1, subCanvasX2) + exportPadding * 2;
-  const height = distance(subCanvasY1, subCanvasY2) + exportPadding * 2;
-  tempCanvas.style.width = width + "px";
-  tempCanvas.style.height = height + "px";
-  tempCanvas.width = width * scale;
-  tempCanvas.height = height * scale;
-  tempCanvas.getContext("2d")?.scale(scale, scale);
+  tempCanvas.width = distance(subCanvasX1, subCanvasX2) + exportPadding * 2;
+  tempCanvas.height = distance(subCanvasY1, subCanvasY2) + exportPadding * 2;
 
   renderScene(
     elements,
@@ -237,27 +230,58 @@ export async function exportCanvas(
     exportBackground,
     exportPadding = 10,
     viewBackgroundColor,
-    name,
-    scale = 1
+    name
   }: {
     exportBackground: boolean;
     exportPadding?: number;
     viewBackgroundColor: string;
+    scrollX: number;
+    scrollY: number;
     name: string;
-    scale?: number;
   }
 ) {
   if (!elements.length) return window.alert("Cannot export empty canvas.");
   // calculate smallest area to fit the contents in
 
-  const tempCanvas = getExportCanvasPreview(elements, {
-    exportBackground,
-    viewBackgroundColor,
-    exportPadding,
-    scale
+  let subCanvasX1 = Infinity;
+  let subCanvasX2 = 0;
+  let subCanvasY1 = Infinity;
+  let subCanvasY2 = 0;
+
+  elements.forEach(element => {
+    const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
+    subCanvasX1 = Math.min(subCanvasX1, x1);
+    subCanvasY1 = Math.min(subCanvasY1, y1);
+    subCanvasX2 = Math.max(subCanvasX2, x2);
+    subCanvasY2 = Math.max(subCanvasY2, y2);
   });
+
+  function distance(x: number, y: number) {
+    return Math.abs(x > y ? x - y : y - x);
+  }
+
+  const tempCanvas = document.createElement("canvas");
   tempCanvas.style.display = "none";
   document.body.appendChild(tempCanvas);
+  tempCanvas.width = distance(subCanvasX1, subCanvasX2) + exportPadding * 2;
+  tempCanvas.height = distance(subCanvasY1, subCanvasY2) + exportPadding * 2;
+
+  renderScene(
+    elements,
+    rough.canvas(tempCanvas),
+    tempCanvas,
+    {
+      viewBackgroundColor: exportBackground ? viewBackgroundColor : null,
+      scrollX: 0,
+      scrollY: 0
+    },
+    {
+      offsetX: -subCanvasX1 + exportPadding,
+      offsetY: -subCanvasY1 + exportPadding,
+      renderScrollbars: false,
+      renderSelection: false
+    }
+  );
 
   if (type === "png") {
     const fileName = `${name}.png`;