2021-02-24 19:52:17 +05:30
|
|
|
import cssVariables from "./css/variables.module.scss";
|
2021-04-04 15:57:14 +05:30
|
|
|
import { AppProps } from "./types";
|
2023-04-18 18:42:48 +05:30
|
|
|
import { ExcalidrawElement, FontFamilyValues } from "./element/types";
|
2023-05-18 16:06:27 +02:00
|
|
|
import { COLOR_PALETTE } from "./colors";
|
2020-06-25 21:21:27 +02:00
|
|
|
|
2023-01-22 12:33:15 +01:00
|
|
|
export const isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
|
|
|
export const isWindows = /^Win/.test(navigator.platform);
|
|
|
|
export const isAndroid = /\b(android)\b/i.test(navigator.userAgent);
|
|
|
|
export const isFirefox =
|
|
|
|
"netscape" in window &&
|
|
|
|
navigator.userAgent.indexOf("rv:") > 1 &&
|
|
|
|
navigator.userAgent.indexOf("Gecko") > 1;
|
2023-02-23 16:33:10 +05:30
|
|
|
export const isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
|
|
|
|
export const isSafari =
|
|
|
|
!isChrome && navigator.userAgent.indexOf("Safari") !== -1;
|
2023-03-13 19:46:09 +05:30
|
|
|
// keeping function so it can be mocked in test
|
|
|
|
export const isBrave = () =>
|
|
|
|
(navigator as any).brave?.isBrave?.name === "isBrave";
|
2023-01-22 12:33:15 +01:00
|
|
|
|
2020-12-22 11:34:06 +02:00
|
|
|
export const APP_NAME = "Excalidraw";
|
|
|
|
|
2021-02-14 14:43:23 +01:00
|
|
|
export const DRAGGING_THRESHOLD = 10; // px
|
|
|
|
export const LINE_CONFIRM_THRESHOLD = 8; // px
|
2020-03-07 10:20:38 -05:00
|
|
|
export const ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;
|
|
|
|
export const ELEMENT_TRANSLATE_AMOUNT = 1;
|
|
|
|
export const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
|
2020-05-23 17:45:05 +09:00
|
|
|
export const SHIFT_LOCKING_ANGLE = Math.PI / 12;
|
2020-03-07 10:20:38 -05:00
|
|
|
export const CURSOR_TYPE = {
|
|
|
|
TEXT: "text",
|
|
|
|
CROSSHAIR: "crosshair",
|
|
|
|
GRABBING: "grabbing",
|
2021-07-09 18:00:13 -04:00
|
|
|
GRAB: "grab",
|
2020-03-18 16:43:06 +01:00
|
|
|
POINTER: "pointer",
|
2020-08-26 17:37:44 +01:00
|
|
|
MOVE: "move",
|
|
|
|
AUTO: "",
|
2020-03-07 10:20:38 -05:00
|
|
|
};
|
|
|
|
export const POINTER_BUTTON = {
|
|
|
|
MAIN: 0,
|
|
|
|
WHEEL: 1,
|
|
|
|
SECONDARY: 2,
|
|
|
|
TOUCH: -1,
|
2022-02-07 20:01:36 +01:00
|
|
|
} as const;
|
2020-04-12 06:12:02 +05:30
|
|
|
|
|
|
|
export enum EVENT {
|
|
|
|
COPY = "copy",
|
|
|
|
PASTE = "paste",
|
|
|
|
CUT = "cut",
|
|
|
|
KEYDOWN = "keydown",
|
|
|
|
KEYUP = "keyup",
|
|
|
|
MOUSE_MOVE = "mousemove",
|
|
|
|
RESIZE = "resize",
|
|
|
|
UNLOAD = "unload",
|
2021-10-07 13:19:40 +02:00
|
|
|
FOCUS = "focus",
|
2020-04-12 06:12:02 +05:30
|
|
|
BLUR = "blur",
|
|
|
|
DRAG_OVER = "dragover",
|
|
|
|
DROP = "drop",
|
|
|
|
GESTURE_END = "gestureend",
|
|
|
|
BEFORE_UNLOAD = "beforeunload",
|
|
|
|
GESTURE_START = "gesturestart",
|
|
|
|
GESTURE_CHANGE = "gesturechange",
|
|
|
|
POINTER_MOVE = "pointermove",
|
2023-06-02 17:06:11 +02:00
|
|
|
POINTER_DOWN = "pointerdown",
|
2020-04-12 06:12:02 +05:30
|
|
|
POINTER_UP = "pointerup",
|
2020-05-13 19:19:49 +02:00
|
|
|
STATE_CHANGE = "statechange",
|
2020-04-12 06:12:02 +05:30
|
|
|
WHEEL = "wheel",
|
|
|
|
TOUCH_START = "touchstart",
|
2020-06-02 18:41:40 +02:00
|
|
|
TOUCH_END = "touchend",
|
2020-07-10 07:16:28 +02:00
|
|
|
HASHCHANGE = "hashchange",
|
2021-02-04 11:55:43 +01:00
|
|
|
VISIBILITY_CHANGE = "visibilitychange",
|
2021-02-14 18:18:34 +05:30
|
|
|
SCROLL = "scroll",
|
2022-02-08 11:25:35 +01:00
|
|
|
// custom events
|
|
|
|
EXCALIDRAW_LINK = "excalidraw-link",
|
2023-01-23 16:54:35 +01:00
|
|
|
MENU_ITEM_SELECT = "menu.itemSelect",
|
2023-07-24 16:51:53 +02:00
|
|
|
MESSAGE = "message",
|
2020-04-12 06:12:02 +05:30
|
|
|
}
|
|
|
|
|
2023-07-24 16:51:53 +02:00
|
|
|
export const YOUTUBE_STATES = {
|
|
|
|
UNSTARTED: -1,
|
|
|
|
ENDED: 0,
|
|
|
|
PLAYING: 1,
|
|
|
|
PAUSED: 2,
|
|
|
|
BUFFERING: 3,
|
|
|
|
CUED: 5,
|
|
|
|
} as const;
|
|
|
|
|
2020-04-12 06:12:02 +05:30
|
|
|
export const ENV = {
|
|
|
|
TEST: "test",
|
|
|
|
DEVELOPMENT: "development",
|
|
|
|
};
|
2020-04-12 16:24:52 +05:30
|
|
|
|
2020-04-12 15:57:57 +02:00
|
|
|
export const CLASSES = {
|
|
|
|
SHAPE_ACTIONS_MENU: "App-menu__left",
|
|
|
|
};
|
2020-05-27 15:14:50 +02:00
|
|
|
|
|
|
|
// 1-based in case we ever do `if(element.fontFamily)`
|
|
|
|
export const FONT_FAMILY = {
|
2021-06-13 21:26:55 +05:30
|
|
|
Virgil: 1,
|
|
|
|
Helvetica: 2,
|
|
|
|
Cascadia: 3,
|
|
|
|
};
|
2020-05-30 18:56:17 +05:30
|
|
|
|
2021-10-14 14:15:57 +05:30
|
|
|
export const THEME = {
|
|
|
|
LIGHT: "light",
|
|
|
|
DARK: "dark",
|
2023-07-24 16:51:53 +02:00
|
|
|
} as const;
|
2021-10-14 14:15:57 +05:30
|
|
|
|
2023-06-15 00:42:01 +08:00
|
|
|
export const FRAME_STYLE = {
|
|
|
|
strokeColor: "#bbb" as ExcalidrawElement["strokeColor"],
|
|
|
|
strokeWidth: 1 as ExcalidrawElement["strokeWidth"],
|
|
|
|
strokeStyle: "solid" as ExcalidrawElement["strokeStyle"],
|
|
|
|
fillStyle: "solid" as ExcalidrawElement["fillStyle"],
|
|
|
|
roughness: 0 as ExcalidrawElement["roughness"],
|
|
|
|
roundness: null as ExcalidrawElement["roundness"],
|
|
|
|
backgroundColor: "transparent" as ExcalidrawElement["backgroundColor"],
|
|
|
|
radius: 8,
|
|
|
|
};
|
|
|
|
|
2020-07-19 21:14:45 +02:00
|
|
|
export const WINDOWS_EMOJI_FALLBACK_FONT = "Segoe UI Emoji";
|
|
|
|
|
2020-06-25 21:21:27 +02:00
|
|
|
export const DEFAULT_FONT_SIZE = 20;
|
2021-06-13 21:26:55 +05:30
|
|
|
export const DEFAULT_FONT_FAMILY: FontFamilyValues = FONT_FAMILY.Virgil;
|
2020-06-25 21:21:27 +02:00
|
|
|
export const DEFAULT_TEXT_ALIGN = "left";
|
|
|
|
export const DEFAULT_VERTICAL_ALIGN = "top";
|
2021-01-10 20:48:12 +02:00
|
|
|
export const DEFAULT_VERSION = "{version}";
|
2020-06-25 21:21:27 +02:00
|
|
|
|
2020-05-30 18:56:17 +05:30
|
|
|
export const CANVAS_ONLY_ACTIONS = ["selectAll"];
|
2020-06-24 00:24:52 +09:00
|
|
|
|
|
|
|
export const GRID_SIZE = 20; // TODO make it configurable?
|
2020-07-08 22:55:26 +02:00
|
|
|
|
2023-04-21 22:53:49 +02:00
|
|
|
export const IMAGE_MIME_TYPES = {
|
2021-10-21 22:05:48 +02:00
|
|
|
svg: "image/svg+xml",
|
|
|
|
png: "image/png",
|
|
|
|
jpg: "image/jpeg",
|
|
|
|
gif: "image/gif",
|
2022-10-10 04:15:30 +02:00
|
|
|
webp: "image/webp",
|
|
|
|
bmp: "image/bmp",
|
|
|
|
ico: "image/x-icon",
|
2023-04-21 22:53:49 +02:00
|
|
|
avif: "image/avif",
|
|
|
|
jfif: "image/jfif",
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
export const MIME_TYPES = {
|
|
|
|
json: "application/json",
|
|
|
|
// excalidraw data
|
|
|
|
excalidraw: "application/vnd.excalidraw+json",
|
|
|
|
excalidrawlib: "application/vnd.excalidrawlib+json",
|
|
|
|
// image-encoded excalidraw data
|
|
|
|
"excalidraw.svg": "image/svg+xml",
|
|
|
|
"excalidraw.png": "image/png",
|
|
|
|
// binary
|
2021-10-21 22:05:48 +02:00
|
|
|
binary: "application/octet-stream",
|
2023-04-21 22:53:49 +02:00
|
|
|
// image
|
|
|
|
...IMAGE_MIME_TYPES,
|
2021-10-07 13:19:40 +02:00
|
|
|
} as const;
|
2020-10-30 21:01:41 +01:00
|
|
|
|
2023-05-13 22:58:35 +02:00
|
|
|
export const EXPORT_IMAGE_TYPES = {
|
|
|
|
png: "png",
|
|
|
|
svg: "svg",
|
|
|
|
clipboard: "clipboard",
|
|
|
|
} as const;
|
|
|
|
|
2021-03-20 20:20:47 +01:00
|
|
|
export const EXPORT_DATA_TYPES = {
|
|
|
|
excalidraw: "excalidraw",
|
|
|
|
excalidrawClipboard: "excalidraw/clipboard",
|
|
|
|
excalidrawLibrary: "excalidrawlib",
|
|
|
|
} as const;
|
|
|
|
|
2022-04-26 13:28:39 +02:00
|
|
|
export const EXPORT_SOURCE =
|
2022-04-27 10:49:02 +02:00
|
|
|
window.EXCALIDRAW_EXPORT_SOURCE || window.location.origin;
|
2021-04-10 19:17:49 +02:00
|
|
|
|
2020-12-05 20:00:53 +05:30
|
|
|
// time in milliseconds
|
2021-10-21 22:05:48 +02:00
|
|
|
export const IMAGE_RENDER_TIMEOUT = 500;
|
2020-12-05 20:00:53 +05:30
|
|
|
export const TAP_TWICE_TIMEOUT = 300;
|
|
|
|
export const TOUCH_CTX_MENU_TIMEOUT = 500;
|
2020-12-22 11:34:06 +02:00
|
|
|
export const TITLE_TIMEOUT = 10000;
|
2021-01-26 22:22:41 +02:00
|
|
|
export const VERSION_TIMEOUT = 30000;
|
2021-03-06 19:06:42 +05:30
|
|
|
export const SCROLL_TIMEOUT = 100;
|
2021-01-30 18:03:23 +01:00
|
|
|
export const ZOOM_STEP = 0.1;
|
2022-10-31 06:23:05 +01:00
|
|
|
export const MIN_ZOOM = 0.1;
|
2022-02-03 20:34:59 +05:30
|
|
|
export const HYPERLINK_TOOLTIP_DELAY = 300;
|
2021-02-04 11:55:43 +01:00
|
|
|
|
|
|
|
// Report a user inactive after IDLE_THRESHOLD milliseconds
|
|
|
|
export const IDLE_THRESHOLD = 60_000;
|
|
|
|
// Report a user active each ACTIVE_THRESHOLD milliseconds
|
|
|
|
export const ACTIVE_THRESHOLD = 3_000;
|
2021-02-12 14:10:40 +05:30
|
|
|
|
2021-03-13 18:58:06 +05:30
|
|
|
export const THEME_FILTER = cssVariables.themeFilter;
|
2021-03-26 18:10:43 +01:00
|
|
|
|
|
|
|
export const URL_QUERY_KEYS = {
|
|
|
|
addLibrary: "addLibrary",
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
export const URL_HASH_KEYS = {
|
|
|
|
addLibrary: "addLibrary",
|
|
|
|
} as const;
|
2021-04-04 15:57:14 +05:30
|
|
|
|
|
|
|
export const DEFAULT_UI_OPTIONS: AppProps["UIOptions"] = {
|
|
|
|
canvasActions: {
|
|
|
|
changeViewBackgroundColor: true,
|
|
|
|
clearCanvas: true,
|
2021-05-29 02:56:25 +05:30
|
|
|
export: { saveFileToDisk: true },
|
2021-04-04 15:57:14 +05:30
|
|
|
loadScene: true,
|
2021-05-28 02:10:33 +05:30
|
|
|
saveToActiveFile: true,
|
2022-09-16 18:59:03 +05:00
|
|
|
toggleTheme: null,
|
2021-05-29 19:41:50 +05:30
|
|
|
saveAsImage: true,
|
2021-04-04 15:57:14 +05:30
|
|
|
},
|
|
|
|
};
|
2021-04-08 19:54:50 +02:00
|
|
|
|
2022-06-21 20:03:23 +05:00
|
|
|
// breakpoints
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// sm screen
|
|
|
|
export const MQ_SM_MAX_WIDTH = 640;
|
|
|
|
// md screen
|
2021-04-08 19:54:50 +02:00
|
|
|
export const MQ_MAX_WIDTH_PORTRAIT = 730;
|
|
|
|
export const MQ_MAX_WIDTH_LANDSCAPE = 1000;
|
|
|
|
export const MQ_MAX_HEIGHT_LANDSCAPE = 500;
|
2022-06-21 20:03:23 +05:00
|
|
|
// sidebar
|
|
|
|
export const MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
export const LIBRARY_SIDEBAR_WIDTH = parseInt(cssVariables.rightSidebarWidth);
|
2021-05-11 19:35:35 -07:00
|
|
|
|
|
|
|
export const MAX_DECIMALS_FOR_SVG_EXPORT = 2;
|
2021-05-30 15:31:12 +01:00
|
|
|
|
|
|
|
export const EXPORT_SCALES = [1, 2, 3];
|
|
|
|
export const DEFAULT_EXPORT_PADDING = 10; // px
|
2021-10-21 22:05:48 +02:00
|
|
|
|
|
|
|
export const DEFAULT_MAX_IMAGE_WIDTH_OR_HEIGHT = 1440;
|
|
|
|
|
|
|
|
export const MAX_ALLOWED_FILE_BYTES = 2 * 1024 * 1024;
|
|
|
|
|
|
|
|
export const SVG_NS = "http://www.w3.org/2000/svg";
|
2021-11-07 14:33:21 +01:00
|
|
|
|
|
|
|
export const ENCRYPTION_KEY_BITS = 128;
|
2021-11-23 17:59:26 +01:00
|
|
|
|
|
|
|
export const VERSIONS = {
|
|
|
|
excalidraw: 2,
|
|
|
|
excalidrawLibrary: 2,
|
|
|
|
} as const;
|
2021-12-16 21:14:03 +05:30
|
|
|
|
2022-01-03 17:59:26 +05:30
|
|
|
export const BOUND_TEXT_PADDING = 5;
|
2022-03-02 20:06:07 +05:30
|
|
|
|
|
|
|
export const VERTICAL_ALIGN = {
|
|
|
|
TOP: "top",
|
|
|
|
MIDDLE: "middle",
|
|
|
|
BOTTOM: "bottom",
|
|
|
|
};
|
2022-03-22 16:40:28 +05:30
|
|
|
|
2022-09-22 15:40:38 +05:30
|
|
|
export const TEXT_ALIGN = {
|
|
|
|
LEFT: "left",
|
|
|
|
CENTER: "center",
|
|
|
|
RIGHT: "right",
|
|
|
|
};
|
|
|
|
|
2022-03-22 16:40:28 +05:30
|
|
|
export const ELEMENT_READY_TO_ERASE_OPACITY = 20;
|
2022-05-18 18:30:34 +02:00
|
|
|
|
2022-12-08 23:48:49 +08:00
|
|
|
// Radius represented as 25% of element's largest side (width/height).
|
|
|
|
// Used for LEGACY and PROPORTIONAL_RADIUS algorithms, or when the element is
|
|
|
|
// below the cutoff size.
|
|
|
|
export const DEFAULT_PROPORTIONAL_RADIUS = 0.25;
|
|
|
|
// Fixed radius for the ADAPTIVE_RADIUS algorithm. In pixels.
|
|
|
|
export const DEFAULT_ADAPTIVE_RADIUS = 32;
|
|
|
|
// roundness type (algorithm)
|
|
|
|
export const ROUNDNESS = {
|
|
|
|
// Used for legacy rounding (rectangles), which currently works the same
|
|
|
|
// as PROPORTIONAL_RADIUS, but we need to differentiate for UI purposes and
|
|
|
|
// forwards-compat.
|
|
|
|
LEGACY: 1,
|
|
|
|
|
|
|
|
// Used for linear elements & diamonds
|
|
|
|
PROPORTIONAL_RADIUS: 2,
|
|
|
|
|
|
|
|
// Current default algorithm for rectangles, using fixed pixel radius.
|
|
|
|
// It's working similarly to a regular border-radius, but attemps to make
|
|
|
|
// radius visually similar across differnt element sizes, especially
|
|
|
|
// very large and very small elements.
|
|
|
|
//
|
|
|
|
// NOTE right now we don't allow configuration and use a constant radius
|
|
|
|
// (see DEFAULT_ADAPTIVE_RADIUS constant)
|
|
|
|
ADAPTIVE_RADIUS: 3,
|
|
|
|
} as const;
|
|
|
|
|
2022-10-08 21:42:05 +03:00
|
|
|
/** key containt id of precedeing elemnt id we use in reconciliation during
|
|
|
|
* collaboration */
|
|
|
|
export const PRECEDING_ELEMENT_KEY = "__precedingElement__";
|
2023-04-18 18:42:48 +05:30
|
|
|
|
|
|
|
export const DEFAULT_ELEMENT_PROPS: {
|
|
|
|
strokeColor: ExcalidrawElement["strokeColor"];
|
|
|
|
backgroundColor: ExcalidrawElement["backgroundColor"];
|
|
|
|
fillStyle: ExcalidrawElement["fillStyle"];
|
|
|
|
strokeWidth: ExcalidrawElement["strokeWidth"];
|
|
|
|
strokeStyle: ExcalidrawElement["strokeStyle"];
|
|
|
|
roughness: ExcalidrawElement["roughness"];
|
|
|
|
opacity: ExcalidrawElement["opacity"];
|
|
|
|
locked: ExcalidrawElement["locked"];
|
|
|
|
} = {
|
2023-05-18 16:06:27 +02:00
|
|
|
strokeColor: COLOR_PALETTE.black,
|
|
|
|
backgroundColor: COLOR_PALETTE.transparent,
|
2023-04-18 18:42:48 +05:30
|
|
|
fillStyle: "hachure",
|
|
|
|
strokeWidth: 1,
|
|
|
|
strokeStyle: "solid",
|
|
|
|
roughness: 1,
|
|
|
|
opacity: 100,
|
|
|
|
locked: false,
|
|
|
|
};
|
2023-05-04 19:33:31 +02:00
|
|
|
|
|
|
|
export const LIBRARY_SIDEBAR_TAB = "library";
|
|
|
|
|
|
|
|
export const DEFAULT_SIDEBAR = {
|
|
|
|
name: "default",
|
|
|
|
defaultTab: LIBRARY_SIDEBAR_TAB,
|
|
|
|
} as const;
|
2023-07-24 16:51:53 +02:00
|
|
|
|
|
|
|
export const LIBRARY_DISABLED_TYPES = new Set(["embeddable", "image"] as const);
|