Browse Source

tweak stroke widths

Ryan Di 2 months ago
parent
commit
b1f3cc50ee

+ 4 - 3
packages/common/src/constants.ts

@@ -385,8 +385,9 @@ export const ROUGHNESS = {
 
 export const STROKE_WIDTH = {
   thin: 1,
-  bold: 2,
-  extraBold: 4,
+  medium: 2,
+  bold: 4,
+  extraBold: 6,
 } as const;
 
 export const DEFAULT_ELEMENT_PROPS: {
@@ -402,7 +403,7 @@ export const DEFAULT_ELEMENT_PROPS: {
   strokeColor: COLOR_PALETTE.black,
   backgroundColor: COLOR_PALETTE.transparent,
   fillStyle: "solid",
-  strokeWidth: 2,
+  strokeWidth: STROKE_WIDTH.medium,
   strokeStyle: "solid",
   roughness: ROUGHNESS.artist,
   opacity: 100,

+ 8 - 14
packages/element/src/freedraw.ts

@@ -10,7 +10,7 @@ import type { ExcalidrawFreeDrawElement } from "./types";
 
 export const DRAWING_CONFIGS = {
   default: {
-    streamline: 0.25,
+    streamline: 0.35,
     simplify: 0.25,
   },
   // for optimal performance, we use a lower streamline and simplify
@@ -62,10 +62,7 @@ const calculateVelocityBasedPressure = (
   return Math.max(0.1, Math.min(1.0, pressure));
 };
 
-export const getFreedrawStroke = (
-  element: ExcalidrawFreeDrawElement,
-  debugParams?: { streamline?: number; simplify?: number },
-) => {
+export const getFreedrawStroke = (element: ExcalidrawFreeDrawElement) => {
   // Compose points as [x, y, pressure]
   let points: [number, number, number][];
   if (element.simulatePressure) {
@@ -105,17 +102,15 @@ export const getFreedrawStroke = (
     streamline,
     simplify,
     sizeMapping: ({ pressure: t }) => {
-      if (element.simulatePressure) {
-        return t + 0.2;
+      if (element.drawingConfigs?.pressureSensitivity === 0) {
+        return 0.5;
       }
 
-      if (element.drawingConfigs?.pressureSensitivity === 0) {
-        return 1;
+      if (element.simulatePressure) {
+        return 0.2 + t * 0.6;
       }
 
-      const minSize = 0.2;
-      const maxSize = 2;
-      return minSize + t * (maxSize - minSize);
+      return 0.2 + t * 0.8;
     },
   });
 
@@ -134,14 +129,13 @@ export const getFreedrawStroke = (
  */
 export const getFreeDrawSvgPath = (
   element: ExcalidrawFreeDrawElement,
-  debugParams?: { streamline?: number; simplify?: number },
 ): string => {
   // legacy, for backwards compatibility
   if (element.drawingConfigs === null) {
     return _legacy_getFreeDrawSvgPath(element);
   }
 
-  return getSvgPathFromStroke(getFreedrawStroke(element, debugParams));
+  return getSvgPathFromStroke(getFreedrawStroke(element));
 };
 
 const roundPoint = (A: Point): string => {

+ 5 - 4
packages/excalidraw/actions/actionProperties.test.tsx

@@ -145,26 +145,27 @@ describe("element locking", () => {
         queryByTestId(document.body, `strokeWidth-thin`),
       ).not.toBeChecked();
       expect(
-        queryByTestId(document.body, `strokeWidth-bold`),
+        queryByTestId(document.body, `strokeWidth-medium`),
       ).not.toBeChecked();
       expect(
-        queryByTestId(document.body, `strokeWidth-extraBold`),
+        queryByTestId(document.body, `strokeWidth-bold`),
       ).not.toBeChecked();
     });
 
     it("should show properties of different element types when selected", () => {
       const rect = API.createElement({
         type: "rectangle",
-        strokeWidth: STROKE_WIDTH.bold,
+        strokeWidth: STROKE_WIDTH.medium,
       });
       const text = API.createElement({
         type: "text",
         fontFamily: FONT_FAMILY["Comic Shanns"],
+        strokeWidth: undefined,
       });
       API.setElements([rect, text]);
       API.setSelectedElements([rect, text]);
 
-      expect(queryByTestId(document.body, `strokeWidth-bold`)).toBeChecked();
+      expect(queryByTestId(document.body, `strokeWidth-medium`)).toBeChecked();
       expect(queryByTestId(document.body, `font-family-code`)).toHaveClass(
         "active",
       );

+ 33 - 20
packages/excalidraw/actions/actionProperties.tsx

@@ -130,6 +130,7 @@ import {
   ArrowheadCrowfootOneOrManyIcon,
   strokeWidthFixedIcon,
   strokeWidthVariableIcon,
+  StrokeWidthMediumIcon,
 } from "../components/icons";
 
 import { Fonts } from "../fonts";
@@ -509,6 +510,33 @@ export const actionChangeFillStyle = register({
   },
 });
 
+const WIDTHS = [
+  {
+    value: STROKE_WIDTH.thin,
+    text: t("labels.thin"),
+    icon: StrokeWidthBaseIcon,
+    testId: "strokeWidth-thin",
+  },
+  {
+    value: STROKE_WIDTH.medium,
+    text: t("labels.medium"),
+    icon: StrokeWidthMediumIcon,
+    testId: "strokeWidth-medium",
+  },
+  {
+    value: STROKE_WIDTH.bold,
+    text: t("labels.bold"),
+    icon: StrokeWidthBoldIcon,
+    testId: "strokeWidth-bold",
+  },
+  {
+    value: STROKE_WIDTH.extraBold,
+    text: t("labels.extraBold"),
+    icon: StrokeWidthExtraBoldIcon,
+    testId: "strokeWidth-extraBold",
+  },
+];
+
 export const actionChangeStrokeWidth = register({
   name: "changeStrokeWidth",
   label: "labels.strokeWidth",
@@ -530,26 +558,11 @@ export const actionChangeStrokeWidth = register({
       <div className="buttonList">
         <RadioSelection
           group="stroke-width"
-          options={[
-            {
-              value: STROKE_WIDTH.thin,
-              text: t("labels.thin"),
-              icon: StrokeWidthBaseIcon,
-              testId: "strokeWidth-thin",
-            },
-            {
-              value: STROKE_WIDTH.bold,
-              text: t("labels.bold"),
-              icon: StrokeWidthBoldIcon,
-              testId: "strokeWidth-bold",
-            },
-            {
-              value: STROKE_WIDTH.extraBold,
-              text: t("labels.extraBold"),
-              icon: StrokeWidthExtraBoldIcon,
-              testId: "strokeWidth-extraBold",
-            },
-          ]}
+          options={
+            appState.activeTool.type === "freedraw"
+              ? WIDTHS
+              : WIDTHS.slice(0, 3)
+          }
           value={getFormValue(
             elements,
             app,

+ 13 - 2
packages/excalidraw/components/icons.tsx

@@ -1136,7 +1136,7 @@ export const StrokeWidthBaseIcon = createIcon(
   modifiedTablerIconProps,
 );
 
-export const StrokeWidthBoldIcon = createIcon(
+export const StrokeWidthMediumIcon = createIcon(
   <path
     d="M5 10h10"
     stroke="currentColor"
@@ -1147,7 +1147,7 @@ export const StrokeWidthBoldIcon = createIcon(
   modifiedTablerIconProps,
 );
 
-export const StrokeWidthExtraBoldIcon = createIcon(
+export const StrokeWidthBoldIcon = createIcon(
   <path
     d="M5 10h10"
     stroke="currentColor"
@@ -1158,6 +1158,17 @@ export const StrokeWidthExtraBoldIcon = createIcon(
   modifiedTablerIconProps,
 );
 
+export const StrokeWidthExtraBoldIcon = createIcon(
+  <path
+    d="M5 10h10"
+    stroke="currentColor"
+    strokeWidth="5"
+    strokeLinecap="round"
+    strokeLinejoin="round"
+  />,
+  modifiedTablerIconProps,
+);
+
 export const StrokeStyleSolidIcon = React.memo(({ theme }: { theme: Theme }) =>
   createIcon(
     <path

+ 37 - 12
packages/excalidraw/tests/__snapshots__/contextmenu.test.tsx.snap

@@ -3127,7 +3127,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
   "currentItemStartArrowhead": null,
   "currentItemStrokeColor": "#e03131",
   "currentItemStrokeStyle": "dotted",
-  "currentItemStrokeWidth": 2,
+  "currentItemStrokeWidth": 4,
   "currentItemTextAlign": "left",
   "cursorButton": "up",
   "defaultSidebarDockedPreference": false,
@@ -3241,11 +3241,11 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
   "seed": 449462985,
   "strokeColor": "#e03131",
   "strokeStyle": "dotted",
-  "strokeWidth": 2,
+  "strokeWidth": 4,
   "type": "rectangle",
   "updated": 1,
   "version": 4,
-  "versionNonce": 941653321,
+  "versionNonce": 1402203177,
   "width": 20,
   "x": -10,
   "y": 0,
@@ -3272,14 +3272,14 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
   "roundness": {
     "type": 3,
   },
-  "seed": 289600103,
+  "seed": 1898319239,
   "strokeColor": "#e03131",
   "strokeStyle": "dotted",
-  "strokeWidth": 2,
+  "strokeWidth": 4,
   "type": "rectangle",
   "updated": 1,
-  "version": 9,
-  "versionNonce": 640725609,
+  "version": 10,
+  "versionNonce": 941653321,
   "width": 20,
   "x": 20,
   "y": 30,
@@ -3288,7 +3288,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
 
 exports[`contextMenu element > selecting 'Paste styles' in context menu pastes styles > [end of test] number of elements 1`] = `2`;
 
-exports[`contextMenu element > selecting 'Paste styles' in context menu pastes styles > [end of test] number of renders 1`] = `16`;
+exports[`contextMenu element > selecting 'Paste styles' in context menu pastes styles > [end of test] number of renders 1`] = `17`;
 
 exports[`contextMenu element > selecting 'Paste styles' in context menu pastes styles > [end of test] redo stack 1`] = `[]`;
 
@@ -3469,6 +3469,29 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
     },
     "id": "id11",
   },
+  {
+    "appState": AppStateDelta {
+      "delta": Delta {
+        "deleted": {},
+        "inserted": {},
+      },
+    },
+    "elements": {
+      "added": {},
+      "removed": {},
+      "updated": {
+        "id3": {
+          "deleted": {
+            "strokeWidth": 4,
+          },
+          "inserted": {
+            "strokeWidth": 2,
+          },
+        },
+      },
+    },
+    "id": "id13",
+  },
   {
     "appState": AppStateDelta {
       "delta": Delta {
@@ -3490,7 +3513,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
         },
       },
     },
-    "id": "id13",
+    "id": "id15",
   },
   {
     "appState": AppStateDelta {
@@ -3513,7 +3536,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
         },
       },
     },
-    "id": "id15",
+    "id": "id17",
   },
   {
     "appState": AppStateDelta {
@@ -3536,7 +3559,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
         },
       },
     },
-    "id": "id17",
+    "id": "id19",
   },
   {
     "appState": AppStateDelta {
@@ -3565,6 +3588,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
             "roughness": 2,
             "strokeColor": "#e03131",
             "strokeStyle": "dotted",
+            "strokeWidth": 4,
           },
           "inserted": {
             "backgroundColor": "transparent",
@@ -3573,11 +3597,12 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
             "roughness": 1,
             "strokeColor": "#1e1e1e",
             "strokeStyle": "solid",
+            "strokeWidth": 2,
           },
         },
       },
     },
-    "id": "id19",
+    "id": "id21",
   },
 ]
 `;

+ 5 - 5
packages/excalidraw/tests/__snapshots__/history.test.tsx.snap

@@ -8913,7 +8913,7 @@ exports[`history > multiplayer undo/redo > should not let remote changes to inte
   "drawingConfigs": {
     "pressureSensitivity": 1,
     "simplify": "0.25000",
-    "streamline": "0.25000",
+    "streamline": "0.35000",
   },
   "fillStyle": "solid",
   "frameId": null,
@@ -9022,7 +9022,7 @@ exports[`history > multiplayer undo/redo > should not let remote changes to inte
             "drawingConfigs": {
               "pressureSensitivity": 1,
               "simplify": "0.25000",
-              "streamline": "0.25000",
+              "streamline": "0.35000",
             },
             "fillStyle": "solid",
             "frameId": null,
@@ -12075,7 +12075,7 @@ exports[`history > singleplayer undo/redo > should create entry when selecting f
   "drawingConfigs": {
     "pressureSensitivity": 1,
     "simplify": "0.25000",
-    "streamline": "0.25000",
+    "streamline": "0.35000",
   },
   "fillStyle": "solid",
   "frameId": null,
@@ -12130,7 +12130,7 @@ exports[`history > singleplayer undo/redo > should create entry when selecting f
   "drawingConfigs": {
     "pressureSensitivity": 1,
     "simplify": "0.25000",
-    "streamline": "0.25000",
+    "streamline": "0.35000",
   },
   "fillStyle": "solid",
   "frameId": null,
@@ -12275,7 +12275,7 @@ exports[`history > singleplayer undo/redo > should create entry when selecting f
             "drawingConfigs": {
               "pressureSensitivity": 1,
               "simplify": "0.25000",
-              "streamline": "0.25000",
+              "streamline": "0.35000",
             },
             "fillStyle": "solid",
             "frameId": null,

+ 3 - 3
packages/excalidraw/tests/__snapshots__/regressionTests.test.tsx.snap

@@ -6880,7 +6880,7 @@ exports[`regression tests > draw every type of shape > [end of test] undo stack
             "drawingConfigs": {
               "pressureSensitivity": 1,
               "simplify": "0.25000",
-              "streamline": "0.25000",
+              "streamline": "0.35000",
             },
             "fillStyle": "solid",
             "frameId": null,
@@ -9159,7 +9159,7 @@ exports[`regression tests > key 7 selects freedraw tool > [end of test] undo sta
             "drawingConfigs": {
               "pressureSensitivity": 1,
               "simplify": "0.25000",
-              "streamline": "0.25000",
+              "streamline": "0.35000",
             },
             "fillStyle": "solid",
             "frameId": null,
@@ -10167,7 +10167,7 @@ exports[`regression tests > key p selects freedraw tool > [end of test] undo sta
             "drawingConfigs": {
               "pressureSensitivity": 1,
               "simplify": "0.25000",
-              "streamline": "0.25000",
+              "streamline": "0.35000",
             },
             "fillStyle": "solid",
             "frameId": null,

+ 1 - 1
packages/excalidraw/tests/actionStyles.test.tsx

@@ -78,7 +78,7 @@ describe("actionStyles", () => {
     expect(firstRect.strokeColor).toBe("#e03131");
     expect(firstRect.backgroundColor).toBe("#a5d8ff");
     expect(firstRect.fillStyle).toBe("cross-hatch");
-    expect(firstRect.strokeWidth).toBe(2); // Bold: 2
+    expect(firstRect.strokeWidth).toBe(4); // Bold: 4
     expect(firstRect.strokeStyle).toBe("dotted");
     expect(firstRect.roughness).toBe(2); // Cartoonist: 2
     expect(firstRect.opacity).toBe(60);

+ 1 - 1
packages/excalidraw/tests/contextmenu.test.tsx

@@ -381,7 +381,7 @@ describe("contextMenu element", () => {
     expect(firstRect.strokeColor).toBe("#e03131");
     expect(firstRect.backgroundColor).toBe("#a5d8ff");
     expect(firstRect.fillStyle).toBe("cross-hatch");
-    expect(firstRect.strokeWidth).toBe(2); // Bold: 2
+    expect(firstRect.strokeWidth).toBe(4); // Bold: 4
     expect(firstRect.strokeStyle).toBe("dotted");
     expect(firstRect.roughness).toBe(2); // Cartoonist: 2
     expect(firstRect.opacity).toBe(60);