diff --git a/packages/common/src/constants.strokeWidth.ts b/packages/common/src/constants.strokeWidth.ts new file mode 100644 index 0000000000..f60b0f57f1 --- /dev/null +++ b/packages/common/src/constants.strokeWidth.ts @@ -0,0 +1,63 @@ +import type { ExcalidrawElement } from "@excalidraw/element/types"; + +export type StrokeWidthKey = "thin" | "medium" | "bold"; + +export const STROKE_WIDTH_KEYS: readonly StrokeWidthKey[] = [ + "thin", + "medium", + "bold", +]; + +export const STROKE_WIDTH: Readonly< + Record +> = { + thin: 1, + medium: 2, + bold: 4, + extraBold: 8, // unused (may be introduced in the future) +}; + +// freedraw schema 2.0 uses thinner stroke, but to maintain backwards and +// forwards compatibility, instead of changing the shape renderer, we scale +// the stroke width by 1/2 (previous, thin was 1, medium 2 etc.) +// +// note that in the UI, STROKE_WIDTH.thin == FREEDRAW_STROKE_WIDTH.thin still +export const FREEDRAW_STROKE_WIDTH: Readonly< + Record +> = { + thin: 0.5, + medium: 1, + bold: 2, + extraBold: 4, // legacy (may be used again in the future) +}; + +const STROKE_WIDTH_TO_KEY = { + generic: Object.fromEntries( + Object.entries(STROKE_WIDTH).map(([key, value]) => [value, key]), + ) as Record, + freedraw: Object.fromEntries( + Object.entries(FREEDRAW_STROKE_WIDTH).map(([key, value]) => [value, key]), + ) as Record, +}; + +export const getStrokeWidthKeyForElement = ( + element: Pick, +): StrokeWidthKey | null => { + const strokeWidthToKey = + element.type === "freedraw" + ? STROKE_WIDTH_TO_KEY.freedraw + : STROKE_WIDTH_TO_KEY.generic; + + return strokeWidthToKey[element.strokeWidth] ?? null; +}; + +export const getStrokeWidthByKey = ( + elementType: ExcalidrawElement["type"], + strokeWidthKey: StrokeWidthKey, +): ExcalidrawElement["strokeWidth"] => { + return elementType === "freedraw" + ? FREEDRAW_STROKE_WIDTH[strokeWidthKey] + : STROKE_WIDTH[strokeWidthKey]; +}; + +export const DEFAULT_ELEMENT_STROKE_WIDTH_KEY: StrokeWidthKey = "medium"; diff --git a/packages/common/src/constants.ts b/packages/common/src/constants.ts index 5e9c797edc..abcbe8a2f3 100644 --- a/packages/common/src/constants.ts +++ b/packages/common/src/constants.ts @@ -5,6 +5,10 @@ import type { import type { AppProps, AppState } from "@excalidraw/excalidraw/types"; import { COLOR_PALETTE } from "./colors"; +import { + STROKE_WIDTH, + DEFAULT_ELEMENT_STROKE_WIDTH_KEY, +} from "./constants.strokeWidth"; export const supportsResizeObserver = typeof window !== "undefined" && "ResizeObserver" in window; @@ -404,68 +408,6 @@ export const ROUGHNESS = { cartoonist: 2, } as const; -export type StrokeWidthKey = "thin" | "medium" | "bold"; - -export const STROKE_WIDTH_KEYS: readonly StrokeWidthKey[] = [ - "thin", - "medium", - "bold", -]; - -export const STROKE_WIDTH: Readonly< - Record -> = { - thin: 1, - medium: 2, - bold: 4, - extraBold: 8, // unused (may be introduced in the future) -}; - -// freedraw schema 2.0 uses thinner stroke, but to maintain backwards and -// forwards compatibility, instead of changing the shape renderer, we scale -// the stroke width by 1/2 (previous, thin was 1, medium 2 etc.) -// -// note that in the UI, STROKE_WIDTH.thin == FREEDRAW_STROKE_WIDTH.thin still -export const FREEDRAW_STROKE_WIDTH: Readonly< - Record -> = { - thin: 0.5, - medium: 1, - bold: 2, - extraBold: 4, // legacy (may be used again in the future) -}; - -const STROKE_WIDTH_TO_KEY = { - generic: Object.fromEntries( - Object.entries(STROKE_WIDTH).map(([key, value]) => [value, key]), - ) as Record, - freedraw: Object.fromEntries( - Object.entries(FREEDRAW_STROKE_WIDTH).map(([key, value]) => [value, key]), - ) as Record, -}; - -export const getStrokeWidthKeyForElement = ( - element: Pick, -): StrokeWidthKey | null => { - const strokeWidthToKey = - element.type === "freedraw" - ? STROKE_WIDTH_TO_KEY.freedraw - : STROKE_WIDTH_TO_KEY.generic; - - return strokeWidthToKey[element.strokeWidth] ?? null; -}; - -export const getStrokeWidthByKey = ( - elementType: ExcalidrawElement["type"], - strokeWidthKey: StrokeWidthKey, -): ExcalidrawElement["strokeWidth"] => { - return elementType === "freedraw" - ? FREEDRAW_STROKE_WIDTH[strokeWidthKey] - : STROKE_WIDTH[strokeWidthKey]; -}; - -export const DEFAULT_ELEMENT_STROKE_WIDTH_KEY: StrokeWidthKey = "medium"; - export const DEFAULT_ELEMENT_PROPS: { strokeColor: ExcalidrawElement["strokeColor"]; backgroundColor: ExcalidrawElement["backgroundColor"]; diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 022f7714bb..fbe282686b 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -2,6 +2,7 @@ export * from "./binary-heap"; export * from "./bounds"; export * from "./colors"; export * from "./constants"; +export * from "./constants.strokeWidth"; export * from "./font-metadata"; export * from "./queue"; export * from "./keys"; diff --git a/packages/excalidraw/data/restore.ts b/packages/excalidraw/data/restore.ts index db75c71099..bc4ced7fba 100644 --- a/packages/excalidraw/data/restore.ts +++ b/packages/excalidraw/data/restore.ts @@ -19,9 +19,8 @@ import { getSizeFromPoints, normalizeLink, getLineHeight, - STROKE_WIDTH, STROKE_WIDTH_KEYS, - type StrokeWidthKey, + STROKE_WIDTH, } from "@excalidraw/common"; import { calculateFixedPointForNonElbowArrowBinding, @@ -58,6 +57,8 @@ import { getNormalizedDimensions } from "@excalidraw/element"; import { isInvisiblySmallElement } from "@excalidraw/element"; +import type { StrokeWidthKey } from "@excalidraw/common"; + import type { LocalPoint, Radians } from "@excalidraw/math"; import type {