Browse Source

fix: freehand points (#4031)

Co-authored-by: dwelle <luzar.david@gmail.com>
Steve Ruiz 3 years ago
parent
commit
00c6940851

+ 2 - 1
package.json

@@ -24,6 +24,7 @@
     "@sentry/integrations": "6.2.5",
     "@testing-library/jest-dom": "5.11.10",
     "@testing-library/react": "11.2.6",
+    "@tldraw/vec": "0.0.106",
     "@types/jest": "26.0.22",
     "@types/react": "17.0.3",
     "@types/react-dom": "17.0.3",
@@ -35,7 +36,7 @@
     "nanoid": "3.1.22",
     "open-color": "1.8.0",
     "pako": "1.0.11",
-    "perfect-freehand": "1.0.6",
+    "perfect-freehand": "1.0.15",
     "png-chunk-text": "1.0.0",
     "png-chunks-encode": "1.0.0",
     "png-chunks-extract": "1.0.0",

+ 6 - 5
src/components/App.tsx

@@ -686,7 +686,7 @@ class App extends React.Component<AppProps, AppState> {
       if (initialData?.libraryItems) {
         this.libraryItemsFromStorage = initialData.libraryItems;
       }
-    } catch (error) {
+    } catch (error: any) {
       console.error(error);
       initialData = {
         appState: {
@@ -1400,7 +1400,7 @@ class App extends React.Component<AppProps, AppState> {
         await webShareTargetCache.delete("shared-file");
         window.history.replaceState(null, APP_NAME, window.location.pathname);
       }
-    } catch (error) {
+    } catch (error: any) {
       this.setState({ errorMessage: error.message });
     }
   };
@@ -3494,6 +3494,7 @@ class App extends React.Component<AppProps, AppState> {
         mutateElement(draggingElement, {
           points: [...points, [dx, dy]],
           pressures,
+          lastCommittedPoint: [dx, dy],
         });
 
         this.actionManager.executeAction(actionFinalize);
@@ -3839,7 +3840,7 @@ class App extends React.Component<AppProps, AppState> {
             // but can be safely ignored on older releases.
             const item = event.dataTransfer.items[0];
             (file as any).handle = await (item as any).getAsFileSystemHandle();
-          } catch (error) {
+          } catch (error: any) {
             console.warn(error.name, error.message);
           }
         }
@@ -3859,7 +3860,7 @@ class App extends React.Component<AppProps, AppState> {
         });
         return;
       }
-    } catch (error) {
+    } catch (error: any) {
       return this.setState({
         isLoading: false,
         errorMessage: error.message,
@@ -3899,7 +3900,7 @@ class App extends React.Component<AppProps, AppState> {
           // but can be safely ignored on older releases.
           const item = event.dataTransfer.items[0];
           (file as any).handle = await (item as any).getAsFileSystemHandle();
-        } catch (error) {
+        } catch (error: any) {
           console.warn(error.name, error.message);
         }
       }

+ 6 - 6
src/element/collision.ts

@@ -328,15 +328,15 @@ const hitTestFreeDrawElement = (
   let P: readonly [number, number];
 
   // For freedraw dots
-  if (element.points.length === 2) {
-    return (
-      distance2d(A[0], A[1], x, y) < threshold ||
-      distance2d(B[0], B[1], x, y) < threshold
-    );
+  if (
+    distance2d(A[0], A[1], x, y) < threshold ||
+    distance2d(B[0], B[1], x, y) < threshold
+  ) {
+    return true;
   }
 
   // For freedraw lines
-  for (let i = 1; i < element.points.length - 1; i++) {
+  for (let i = 0; i < element.points.length; i++) {
     const delta = [B[0] - A[0], B[1] - A[1]];
     const length = Math.hypot(delta[1], delta[0]);
 

+ 2 - 2
src/renderer/renderElement.ts

@@ -804,7 +804,7 @@ export function getFreeDrawSvgPath(element: ExcalidrawFreeDrawElement) {
     smoothing: 0.5,
     streamline: 0.5,
     easing: (t) => Math.sin((t * Math.PI) / 2), // https://easings.net/#easeOutSine
-    last: false,
+    last: !!element.lastCommittedPoint, // LastCommittedPoint is added on pointerup
   };
 
   return getSvgPathFromStroke(getStroke(inputPoints as number[][], options));
@@ -839,5 +839,5 @@ function getSvgPathFromStroke(points: number[][]): string {
       ["M", points[0], "Q"],
     )
     .join(" ")
-    .replaceAll(TO_FIXED_PRECISION, "$1");
+    .replace(TO_FIXED_PRECISION, "$1");
 }

+ 24 - 6
src/tests/__snapshots__/regressionTests.test.tsx.snap

@@ -6707,7 +6707,10 @@ Object {
   "height": 10,
   "id": "id7",
   "isDeleted": false,
-  "lastCommittedPoint": null,
+  "lastCommittedPoint": Array [
+    50,
+    10,
+  ],
   "opacity": 100,
   "points": Array [
     Array [
@@ -8374,7 +8377,10 @@ Object {
           "height": 10,
           "id": "id7",
           "isDeleted": false,
-          "lastCommittedPoint": null,
+          "lastCommittedPoint": Array [
+            50,
+            10,
+          ],
           "opacity": 100,
           "points": Array [
             Array [
@@ -10533,7 +10539,10 @@ Object {
   "height": 10,
   "id": "id0",
   "isDeleted": false,
-  "lastCommittedPoint": null,
+  "lastCommittedPoint": Array [
+    10,
+    10,
+  ],
   "opacity": 100,
   "points": Array [
     Array [
@@ -10607,7 +10616,10 @@ Object {
           "height": 10,
           "id": "id0",
           "isDeleted": false,
-          "lastCommittedPoint": null,
+          "lastCommittedPoint": Array [
+            10,
+            10,
+          ],
           "opacity": 100,
           "points": Array [
             Array [
@@ -11637,7 +11649,10 @@ Object {
   "height": 10,
   "id": "id0",
   "isDeleted": false,
-  "lastCommittedPoint": null,
+  "lastCommittedPoint": Array [
+    10,
+    10,
+  ],
   "opacity": 100,
   "points": Array [
     Array [
@@ -11711,7 +11726,10 @@ Object {
           "height": 10,
           "id": "id0",
           "isDeleted": false,
-          "lastCommittedPoint": null,
+          "lastCommittedPoint": Array [
+            10,
+            10,
+          ],
           "opacity": 100,
           "points": Array [
             Array [

+ 9 - 4
yarn.lock

@@ -1916,6 +1916,11 @@
     "@babel/runtime" "^7.12.5"
     "@testing-library/dom" "^7.28.1"
 
+"@tldraw/vec@0.0.106":
+  version "0.0.106"
+  resolved "https://registry.yarnpkg.com/@tldraw/vec/-/vec-0.0.106.tgz#34936176b314c7779a3ad897a07be7434cdbc655"
+  integrity sha512-sOI3/bEb0KbGTHb8s2lSnY+0uWEToehJXPjV9ItFEOPqRXKoKbWRUzN1OAP7AQa1FJA2/w/1oPO9Seycne6JRA==
+
 "@tootallnate/once@1":
   version "1.1.2"
   resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz"
@@ -9260,10 +9265,10 @@ pepjs@0.5.3:
   version "0.5.3"
   resolved "https://registry.npmjs.org/pepjs/-/pepjs-0.5.3.tgz"
 
-perfect-freehand@1.0.6:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-1.0.6.tgz#feeb25450241f036ec13b43fa84bbb16f8e78e0f"
-  integrity sha512-wWkFwpgUirsfBDTb9nG6+VnFR0ge119QKU2Nu96vR4MHZMPGfOsQRD7cUk+9CK5P+TUmnrtX8yOEzUrQ6KHJoA==
+perfect-freehand@1.0.15:
+  version "1.0.15"
+  resolved "https://registry.yarnpkg.com/perfect-freehand/-/perfect-freehand-1.0.15.tgz#d3e4769e0420c0d467c0147487a34793f0b421e7"
+  integrity sha512-uRglBAdRA/wzGTbI0F58fXOfNuDmUHq1S40u92d2oPGhO1YfEUGal7fT2g0N8gwkIwMD14ySeLroUVhs7aBBuw==
 
 performance-now@^2.1.0:
   version "2.1.0"