Procházet zdrojové kódy

fix exporting bg for non-cropped exports

- also refactor and add comments to `exportAsPNG`
dwelle před 5 roky
rodič
revize
f091e9813e
1 změnil soubory, kde provedl 59 přidání a 37 odebrání
  1. 59 37
      src/index.js

+ 59 - 37
src/index.js

@@ -29,10 +29,18 @@ function newElement(type, x, y, width = 0, height = 0) {
   return element;
 }
 
-function exportAsPNG({ background, visibleOnly, padding = 10 }) {
+function exportAsPNG({
+  exportBackground,
+  exportVisibleOnly,
+  exportPadding = 10
+}) {
+  // deselect & rerender
+
   clearSelection();
   drawScene();
 
+  // calculate visible-area coords
+
   let subCanvasX1 = Infinity;
   let subCanvasX2 = 0;
   let subCanvasY1 = Infinity;
@@ -45,40 +53,54 @@ function exportAsPNG({ background, visibleOnly, padding = 10 }) {
     subCanvasY2 = Math.max(subCanvasY2, getElementAbsoluteY2(element));
   });
 
-  let targetCanvas = canvas;
-
-  if ( visibleOnly ) {
-    targetCanvas = document.createElement('canvas');
-    targetCanvas.style.display = 'none';
-    document.body.appendChild(targetCanvas);
-    targetCanvas.width = subCanvasX2 - subCanvasX1 + padding * 2;
-    targetCanvas.height = subCanvasY2 - subCanvasY1 + padding * 2;
-    const targetCanvas_ctx = targetCanvas.getContext('2d');
-
-    if ( background ) {
-      targetCanvas_ctx.fillStyle = "#FFF";
-      targetCanvas_ctx.fillRect(0, 0, canvas.width, canvas.height);
-    }
-
-    targetCanvas_ctx.drawImage(
-      canvas,
-      subCanvasX1 - padding, // x
-      subCanvasY1 - padding, // y
-      subCanvasX2 - subCanvasX1 + padding * 2, // width
-      subCanvasY2 - subCanvasY1 + padding * 2, // height
-      0,
-      0,
-      targetCanvas.width,
-      targetCanvas.height
-    );
+  // create temporary canvas from which we'll export
+
+  const tempCanvas = document.createElement("canvas");
+  const tempCanvasCtx = tempCanvas.getContext("2d");
+  tempCanvas.style.display = "none";
+  document.body.appendChild(tempCanvas);
+  tempCanvas.width = exportVisibleOnly
+    ? subCanvasX2 - subCanvasX1 + exportPadding * 2
+    : canvas.width;
+  tempCanvas.height = exportVisibleOnly
+    ? subCanvasY2 - subCanvasY1 + exportPadding * 2
+    : canvas.height;
+
+  if (exportBackground) {
+    tempCanvasCtx.fillStyle = "#FFF";
+    tempCanvasCtx.fillRect(0, 0, canvas.width, canvas.height);
   }
 
-  const link = document.createElement('a');
-  link.setAttribute('download', 'excalibur.png');
-  link.setAttribute('href', targetCanvas.toDataURL("image/png"));
+  // copy our original canvas onto the temp canvas
+  tempCanvasCtx.drawImage(
+    canvas, // source
+    exportVisibleOnly // sx
+      ? subCanvasX1 - exportPadding
+      : 0,
+    exportVisibleOnly // sy
+      ? subCanvasY1 - exportPadding
+      : 0,
+    exportVisibleOnly // sWidth
+      ? subCanvasX2 - subCanvasX1 + exportPadding * 2
+      : canvas.width,
+    exportVisibleOnly // sHeight
+      ? subCanvasY2 - subCanvasY1 + exportPadding * 2
+      : canvas.height,
+    0, // dx
+    0, // dy
+    exportVisibleOnly ? tempCanvas.width : canvas.width, // dWidth
+    exportVisibleOnly ? tempCanvas.height : canvas.height // dHeight
+  );
+
+  // create a temporary <a> elem which we'll use to download the image
+  const link = document.createElement("a");
+  link.setAttribute("download", "excalibur.png");
+  link.setAttribute("href", tempCanvas.toDataURL("image/png"));
   link.click();
+
+  // clean up the DOM
   link.remove();
-  if ( targetCanvas !== canvas ) targetCanvas.remove();
+  if (tempCanvas !== canvas) tempCanvas.remove();
 }
 
 function rotate(x1, y1, x2, y2, angle) {
@@ -280,9 +302,9 @@ class App extends React.Component {
       <div className="exportWrapper">
         <button onClick={() => {
           exportAsPNG({
-            background: this.state.exportBackground,
-            visibleOnly: this.state.exportVisibleOnly,
-            padding: this.state.exportPadding
+            exportBackground: this.state.exportBackground,
+            exportVisibleOnly: this.state.exportVisibleOnly,
+            exportPadding: this.state.exportPadding
           })
         }}>Export to png</button>
         <label>
@@ -337,7 +359,7 @@ class App extends React.Component {
                   element.isSelected = true
                 }
                 return isSelected
-              }) 
+              })
 
               if (selectedElement) {
                 this.setState({ draggingElement: selectedElement });
@@ -350,7 +372,7 @@ class App extends React.Component {
               if (isDraggingElements) {
                 document.documentElement.style.cursor = "move";
               }
-            } 
+            }
 
             if (this.state.elementType === "text") {
               const text = prompt("What text do you want?");
@@ -441,7 +463,7 @@ class App extends React.Component {
               if (elementType === "selection") {
                 if (isDraggingElements) {
                   isDraggingElements = false;
-                } 
+                }
                 elements.pop()
               } else {
                 draggingElement.isSelected = true;