瀏覽代碼

Remove last get/setTransform (#964)

My original hack to put the scale when we create the canvas element doesn't make much sense. It should be done when we are rendering the scene. I moved it there in this PR.

The rest was all about forwarding the scale to where it's needed.
Christopher Chedeau 5 年之前
父節點
當前提交
2937efacde
共有 6 個文件被更改,包括 31 次插入13 次删除
  1. 14 4
      src/components/App.tsx
  2. 4 0
      src/renderer/renderElement.ts
  3. 6 3
      src/renderer/renderScene.ts
  4. 0 1
      src/scene/export.ts
  5. 3 3
      src/scene/zoom.ts
  6. 4 2
      src/utils.ts

+ 14 - 4
src/components/App.tsx

@@ -682,6 +682,7 @@ export class App extends React.Component<any, AppState> {
           { clientX: cursorX, clientY: cursorY },
           this.state,
           this.canvas,
+          window.devicePixelRatio,
         );
 
         const element = newTextElement(
@@ -808,10 +809,6 @@ export class App extends React.Component<any, AppState> {
                 this.canvas.addEventListener("wheel", this.handleWheel, {
                   passive: false,
                 });
-
-                this.canvas
-                  .getContext("2d")
-                  ?.setTransform(canvasScale, 0, 0, canvasScale, 0, 0);
               } else {
                 this.canvas?.removeEventListener("wheel", this.handleWheel);
               }
@@ -823,6 +820,7 @@ export class App extends React.Component<any, AppState> {
                 event,
                 this.state,
                 this.canvas,
+                window.devicePixelRatio,
               );
 
               const element = getElementAtPosition(
@@ -923,6 +921,7 @@ export class App extends React.Component<any, AppState> {
       event,
       this.state,
       this.canvas,
+      window.devicePixelRatio,
     );
 
     const elementAtPosition = getElementAtPosition(
@@ -974,6 +973,7 @@ export class App extends React.Component<any, AppState> {
         { sceneX: centerElementX, sceneY: centerElementY },
         this.state,
         this.canvas,
+        window.devicePixelRatio,
       );
 
       textX = centerElementXInViewport;
@@ -1048,6 +1048,7 @@ export class App extends React.Component<any, AppState> {
       event,
       this.state,
       this.canvas,
+      window.devicePixelRatio,
     );
     this.savePointer(pointerCoords);
     if (gesture.pointers.has(event.pointerId)) {
@@ -1096,6 +1097,7 @@ export class App extends React.Component<any, AppState> {
       event,
       this.state,
       this.canvas,
+      window.devicePixelRatio,
     );
     if (this.state.multiElement) {
       const { multiElement } = this.state;
@@ -1247,6 +1249,7 @@ export class App extends React.Component<any, AppState> {
       event,
       this.state,
       this.canvas,
+      window.devicePixelRatio,
     );
     let lastX = x;
     let lastY = y;
@@ -1657,6 +1660,7 @@ export class App extends React.Component<any, AppState> {
           event,
           this.state,
           this.canvas,
+          window.devicePixelRatio,
         );
         if (distance2d(x, y, originX, originY) < DRAGGING_THRESHOLD) {
           return;
@@ -1675,6 +1679,7 @@ export class App extends React.Component<any, AppState> {
             event,
             this.state,
             this.canvas,
+            window.devicePixelRatio,
           );
           const deltaX = x - lastX;
           const deltaY = y - lastY;
@@ -1891,6 +1896,7 @@ export class App extends React.Component<any, AppState> {
             event,
             this.state,
             this.canvas,
+            window.devicePixelRatio,
           );
 
           selectedElements.forEach(element => {
@@ -1916,6 +1922,7 @@ export class App extends React.Component<any, AppState> {
         event,
         this.state,
         this.canvas,
+        window.devicePixelRatio,
       );
 
       let width = distance(originX, x);
@@ -2019,6 +2026,7 @@ export class App extends React.Component<any, AppState> {
             event,
             this.state,
             this.canvas,
+            window.devicePixelRatio,
           );
           mutateElement(draggingElement, {
             points: [
@@ -2184,6 +2192,7 @@ export class App extends React.Component<any, AppState> {
       { clientX: cursorX, clientY: cursorY },
       this.state,
       this.canvas,
+      window.devicePixelRatio,
     );
 
     const dx = x - elementsCenterX;
@@ -2270,6 +2279,7 @@ export class App extends React.Component<any, AppState> {
         },
         this.state,
         this.canvas,
+        window.devicePixelRatio,
       );
     });
     const { atLeastOneVisibleElement, scrollBars } = renderScene(

+ 4 - 0
src/renderer/renderElement.ts

@@ -64,6 +64,10 @@ function generateElementCanvas(
   const rc = rough.canvas(canvas);
   drawElementOnCanvas(element, rc, context);
   context.translate(-CANVAS_PADDING, -CANVAS_PADDING);
+  context.scale(
+    1 / (window.devicePixelRatio * zoom),
+    1 / (window.devicePixelRatio * zoom),
+  );
   return { element, canvas, canvasZoom: zoom, canvasOffsetX, canvasOffsetY };
 }
 

+ 6 - 3
src/renderer/renderScene.ts

@@ -55,6 +55,7 @@ export function renderScene(
   const elements = allElements.filter(element => !element.isDeleted);
 
   const context = canvas.getContext("2d")!;
+  context.scale(scale, scale);
 
   // When doing calculations based on canvas width we should used normalized one
   const normalizedCanvasWidth = canvas.width / scale;
@@ -205,8 +206,9 @@ export function renderScene(
   }
 
   // Paint scrollbars
+  let scrollBars;
   if (renderScrollbars) {
-    const scrollBars = getScrollBars(
+    scrollBars = getScrollBars(
       elements,
       normalizedCanvasWidth,
       normalizedCanvasHeight,
@@ -231,10 +233,11 @@ export function renderScene(
     });
     context.fillStyle = fillStyle;
     context.strokeStyle = strokeStyle;
-    return { atLeastOneVisibleElement: visibleElements.length > 0, scrollBars };
   }
 
-  return { atLeastOneVisibleElement: visibleElements.length > 0 };
+  context.scale(1 / scale, 1 / scale);
+
+  return { atLeastOneVisibleElement: visibleElements.length > 0, scrollBars };
 }
 
 function isVisibleElement(

+ 0 - 1
src/scene/export.ts

@@ -36,7 +36,6 @@ export function exportToCanvas(
   const height = distance(minY, maxY) + exportPadding * 2;
 
   const tempCanvas: any = createCanvas(width, height);
-  tempCanvas.getContext("2d")?.scale(scale, scale);
 
   renderScene(
     elements,

+ 3 - 3
src/scene/zoom.ts

@@ -1,4 +1,4 @@
-export function getZoomOrigin(canvas: HTMLCanvasElement | null) {
+export function getZoomOrigin(canvas: HTMLCanvasElement | null, scale: number) {
   if (canvas === null) {
     return { x: 0, y: 0 };
   }
@@ -7,8 +7,8 @@ export function getZoomOrigin(canvas: HTMLCanvasElement | null) {
     return { x: 0, y: 0 };
   }
 
-  const normalizedCanvasWidth = canvas.width / context.getTransform().a;
-  const normalizedCanvasHeight = canvas.height / context.getTransform().d;
+  const normalizedCanvasWidth = canvas.width / scale;
+  const normalizedCanvasHeight = canvas.height / scale;
 
   return {
     x: normalizedCanvasWidth / 2,

+ 4 - 2
src/utils.ts

@@ -157,8 +157,9 @@ export function viewportCoordsToSceneCoords(
     zoom: number;
   },
   canvas: HTMLCanvasElement | null,
+  scale: number,
 ) {
-  const zoomOrigin = getZoomOrigin(canvas);
+  const zoomOrigin = getZoomOrigin(canvas, scale);
   const clientXWithZoom = zoomOrigin.x + (clientX - zoomOrigin.x) / zoom;
   const clientYWithZoom = zoomOrigin.y + (clientY - zoomOrigin.y) / zoom;
 
@@ -180,8 +181,9 @@ export function sceneCoordsToViewportCoords(
     zoom: number;
   },
   canvas: HTMLCanvasElement | null,
+  scale: number,
 ) {
-  const zoomOrigin = getZoomOrigin(canvas);
+  const zoomOrigin = getZoomOrigin(canvas, scale);
   const sceneXWithZoomAndScroll =
     zoomOrigin.x - (zoomOrigin.x - sceneX - scrollX) * zoom;
   const sceneYWithZoomAndScroll =