ソースを参照

fix: remove rounding to fix jitter when shift-editing (#5543)

Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
David Luzar 2 年 前
コミット
45b592227d

+ 1 - 5
src/element/linearElementEditor.ts

@@ -178,17 +178,13 @@ export class LinearElementEditor {
         const referencePoint =
           element.points[selectedIndex === 0 ? 1 : selectedIndex - 1];
 
-        let [width, height] = LinearElementEditor._getShiftLockedDelta(
+        const [width, height] = LinearElementEditor._getShiftLockedDelta(
           element,
           referencePoint,
           [scenePointerX, scenePointerY],
           appState.gridSize,
         );
 
-        // rounding to stop the dragged point from jiggling
-        width = Math.round(width);
-        height = Math.round(height);
-
         LinearElementEditor.movePoints(element, [
           {
             index: selectedIndex,

+ 18 - 16
src/element/sizeHelpers.test.ts

@@ -1,49 +1,51 @@
 import { getPerfectElementSize } from "./sizeHelpers";
 import * as constants from "../constants";
 
+const EPSILON_DIGITS = 3;
+
 describe("getPerfectElementSize", () => {
   it("should return height:0 if `elementType` is line and locked angle is 0", () => {
     const { height, width } = getPerfectElementSize("line", 149, 10);
-    expect(width).toEqual(149);
-    expect(height).toEqual(0);
+    expect(width).toBeCloseTo(149, EPSILON_DIGITS);
+    expect(height).toBeCloseTo(0, EPSILON_DIGITS);
   });
   it("should return width:0 if `elementType` is line and locked angle is 90 deg (Math.PI/2)", () => {
     const { height, width } = getPerfectElementSize("line", 10, 140);
-    expect(width).toEqual(0);
-    expect(height).toEqual(140);
+    expect(width).toBeCloseTo(0, EPSILON_DIGITS);
+    expect(height).toBeCloseTo(140, EPSILON_DIGITS);
   });
   it("should return height:0 if `elementType` is arrow and locked angle is 0", () => {
     const { height, width } = getPerfectElementSize("arrow", 200, 20);
-    expect(width).toEqual(200);
-    expect(height).toEqual(0);
+    expect(width).toBeCloseTo(200, EPSILON_DIGITS);
+    expect(height).toBeCloseTo(0, EPSILON_DIGITS);
   });
   it("should return width:0 if `elementType` is arrow and locked angle is 90 deg (Math.PI/2)", () => {
     const { height, width } = getPerfectElementSize("arrow", 10, 100);
-    expect(width).toEqual(0);
-    expect(height).toEqual(100);
+    expect(width).toBeCloseTo(0, EPSILON_DIGITS);
+    expect(height).toBeCloseTo(100, EPSILON_DIGITS);
   });
   it("should return adjust height to be width * tan(locked angle)", () => {
     const { height, width } = getPerfectElementSize("arrow", 120, 185);
-    expect(width).toEqual(120);
-    expect(height).toEqual(208);
+    expect(width).toBeCloseTo(120, EPSILON_DIGITS);
+    expect(height).toBeCloseTo(207.846, EPSILON_DIGITS);
   });
   it("should return height equals to width if locked angle is 45 deg", () => {
     const { height, width } = getPerfectElementSize("arrow", 135, 145);
-    expect(width).toEqual(135);
-    expect(height).toEqual(135);
+    expect(width).toBeCloseTo(135, EPSILON_DIGITS);
+    expect(height).toBeCloseTo(135, EPSILON_DIGITS);
   });
   it("should return height:0 and width:0 when width and height are 0", () => {
     const { height, width } = getPerfectElementSize("arrow", 0, 0);
-    expect(width).toEqual(0);
-    expect(height).toEqual(0);
+    expect(width).toBeCloseTo(0, EPSILON_DIGITS);
+    expect(height).toBeCloseTo(0, EPSILON_DIGITS);
   });
 
   describe("should respond to SHIFT_LOCKING_ANGLE constant", () => {
     it("should have only 2 locking angles per section if SHIFT_LOCKING_ANGLE = 45 deg (Math.PI/4)", () => {
       (constants as any).SHIFT_LOCKING_ANGLE = Math.PI / 4;
       const { height, width } = getPerfectElementSize("arrow", 120, 185);
-      expect(width).toEqual(120);
-      expect(height).toEqual(120);
+      expect(width).toBeCloseTo(120, EPSILON_DIGITS);
+      expect(height).toBeCloseTo(120, EPSILON_DIGITS);
     });
   });
 });

+ 3 - 5
src/element/sizeHelpers.ts

@@ -37,9 +37,7 @@ export const getPerfectElementSize = (
     } else if (lockedAngle === Math.PI / 2) {
       width = 0;
     } else {
-      height =
-        Math.round(absWidth * Math.tan(lockedAngle)) * Math.sign(height) ||
-        height;
+      height = absWidth * Math.tan(lockedAngle) * Math.sign(height) || height;
     }
   } else if (elementType !== "selection") {
     height = absWidth * Math.sign(height);
@@ -76,8 +74,8 @@ export const getLockedLinearCursorAlignSize = (
     const c2 = y - a2 * x;
 
     // intersection of the two lines above
-    const intersectX = Math.round((b1 * c2 - b2 * c1) / (a1 * b2 - a2 * b1));
-    const intersectY = Math.round((c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1));
+    const intersectX = (b1 * c2 - b2 * c1) / (a1 * b2 - a2 * b1);
+    const intersectY = (c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1);
 
     // delta
     width = intersectX - originX;