Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f5f4ec7528 | |||
| ba705a099a | |||
| 6dee02e320 | |||
| 74a2f16501 | |||
| fd4460be37 | |||
| e82d0493cf | |||
| 083cb4c656 | |||
| d067365c1d | |||
| 273cac6b60 | |||
| b9337b8a36 | |||
| 0e0025921b | |||
| efc01ddab1 | |||
| 7bce22b114 | |||
| aab4965bbb | |||
| 486a9a3da8 | |||
| 2425c06082 | |||
| 79ea844901 | |||
| 6690215cd1 | |||
| 7f5e783fe8 | |||
| 9325109836 | |||
| 69b6fbb3f4 | |||
| 6b6002baae | |||
| 54dcb73701 | |||
| b595d3fcba | |||
| d0867d1c3b | |||
| 0d19e9210c | |||
| 4249de41d4 | |||
| 15f02ba191 | |||
| a2e1199907 | |||
| c08e9c4172 | |||
| abfc58eb24 | |||
| 035c7affff |
@@ -2,5 +2,8 @@
|
|||||||
"firestore": {
|
"firestore": {
|
||||||
"rules": "firestore.rules",
|
"rules": "firestore.rules",
|
||||||
"indexes": "firestore.indexes.json"
|
"indexes": "firestore.indexes.json"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"rules": "storage.rules"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
rules_version = '2';
|
||||||
|
service firebase.storage {
|
||||||
|
match /b/{bucket}/o {
|
||||||
|
match /{migrations} {
|
||||||
|
match /{scenes}/{scene} {
|
||||||
|
allow get, write: if true;
|
||||||
|
// redundant, but let's be explicit'
|
||||||
|
allow list: if false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
"clsx": "1.1.1",
|
"clsx": "1.1.1",
|
||||||
"firebase": "8.3.3",
|
"firebase": "8.3.3",
|
||||||
"i18next-browser-languagedetector": "6.1.0",
|
"i18next-browser-languagedetector": "6.1.0",
|
||||||
|
"idb-keyval": "5.0.6",
|
||||||
"lodash.throttle": "4.1.1",
|
"lodash.throttle": "4.1.1",
|
||||||
"nanoid": "3.1.22",
|
"nanoid": "3.1.22",
|
||||||
"open-color": "1.8.0",
|
"open-color": "1.8.0",
|
||||||
|
|||||||
Binary file not shown.
@@ -34,9 +34,9 @@ export const actionChangeViewBackgroundColor = register({
|
|||||||
type="canvasBackground"
|
type="canvasBackground"
|
||||||
color={appState.viewBackgroundColor}
|
color={appState.viewBackgroundColor}
|
||||||
onChange={(color) => updateData({ viewBackgroundColor: color })}
|
onChange={(color) => updateData({ viewBackgroundColor: color })}
|
||||||
isActive={appState.openMenu === "canvasColorPicker"}
|
isActive={appState.openPopup === "canvasColorPicker"}
|
||||||
setActive={(active) =>
|
setActive={(active) =>
|
||||||
updateData({ openMenu: active ? "canvasColorPicker" : null })
|
updateData({ openPopup: active ? "canvasColorPicker" : null })
|
||||||
}
|
}
|
||||||
data-testid="canvas-background-picker"
|
data-testid="canvas-background-picker"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { trackEvent } from "../analytics";
|
import { trackEvent } from "../analytics";
|
||||||
import { load, questionCircle, save, saveAs } from "../components/icons";
|
import { load, questionCircle, saveAs } from "../components/icons";
|
||||||
import { ProjectName } from "../components/ProjectName";
|
import { ProjectName } from "../components/ProjectName";
|
||||||
import { ToolButton } from "../components/ToolButton";
|
import { ToolButton } from "../components/ToolButton";
|
||||||
import "../components/ToolIcon.scss";
|
import "../components/ToolIcon.scss";
|
||||||
@@ -13,6 +13,12 @@ import { KEYS } from "../keys";
|
|||||||
import { register } from "./register";
|
import { register } from "./register";
|
||||||
import { supported as fsSupported } from "browser-fs-access";
|
import { supported as fsSupported } from "browser-fs-access";
|
||||||
import { CheckboxItem } from "../components/CheckboxItem";
|
import { CheckboxItem } from "../components/CheckboxItem";
|
||||||
|
import { getExportSize } from "../scene/export";
|
||||||
|
import { DEFAULT_EXPORT_PADDING, EXPORT_SCALES, IDB_KEYS } from "../constants";
|
||||||
|
import { getSelectedElements, isSomeElementSelected } from "../scene";
|
||||||
|
import { getNonDeletedElements } from "../element";
|
||||||
|
import { ActiveFile } from "../components/ActiveFile";
|
||||||
|
import * as idb from "idb-keyval";
|
||||||
|
|
||||||
export const actionChangeProjectName = register({
|
export const actionChangeProjectName = register({
|
||||||
name: "changeProjectName",
|
name: "changeProjectName",
|
||||||
@@ -32,6 +38,54 @@ export const actionChangeProjectName = register({
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const actionChangeExportScale = register({
|
||||||
|
name: "changeExportScale",
|
||||||
|
perform: (_elements, appState, value) => {
|
||||||
|
return {
|
||||||
|
appState: { ...appState, exportScale: value },
|
||||||
|
commitToHistory: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
PanelComponent: ({ elements: allElements, appState, updateData }) => {
|
||||||
|
const elements = getNonDeletedElements(allElements);
|
||||||
|
const exportSelected = isSomeElementSelected(elements, appState);
|
||||||
|
const exportedElements = exportSelected
|
||||||
|
? getSelectedElements(elements, appState)
|
||||||
|
: elements;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{EXPORT_SCALES.map((s) => {
|
||||||
|
const [width, height] = getExportSize(
|
||||||
|
exportedElements,
|
||||||
|
DEFAULT_EXPORT_PADDING,
|
||||||
|
s,
|
||||||
|
);
|
||||||
|
|
||||||
|
const scaleButtonTitle = `${t(
|
||||||
|
"buttons.scale",
|
||||||
|
)} ${s}x (${width}x${height})`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ToolButton
|
||||||
|
key={s}
|
||||||
|
size="s"
|
||||||
|
type="radio"
|
||||||
|
icon={`${s}x`}
|
||||||
|
name="export-canvas-scale"
|
||||||
|
title={scaleButtonTitle}
|
||||||
|
aria-label={scaleButtonTitle}
|
||||||
|
id="export-canvas-scale"
|
||||||
|
checked={s === appState.exportScale}
|
||||||
|
onChange={() => updateData(s)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const actionChangeExportBackground = register({
|
export const actionChangeExportBackground = register({
|
||||||
name: "changeExportBackground",
|
name: "changeExportBackground",
|
||||||
perform: (_elements, appState, value) => {
|
perform: (_elements, appState, value) => {
|
||||||
@@ -96,19 +150,30 @@ export const actionSaveToActiveFile = register({
|
|||||||
if (error?.name !== "AbortError") {
|
if (error?.name !== "AbortError") {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
return { commitToHistory: false };
|
|
||||||
|
if (fileHandleExists && error.name === "AbortError") {
|
||||||
|
try {
|
||||||
|
await idb.del(IDB_KEYS.fileHandle);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
commitToHistory: false,
|
||||||
|
appState: { ...appState, fileHandle: null },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
commitToHistory: false,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
keyTest: (event) =>
|
keyTest: (event) =>
|
||||||
event.key === KEYS.S && event[KEYS.CTRL_OR_CMD] && !event.shiftKey,
|
event.key === KEYS.S && event[KEYS.CTRL_OR_CMD] && !event.shiftKey,
|
||||||
PanelComponent: ({ updateData }) => (
|
PanelComponent: ({ updateData, appState }) => (
|
||||||
<ToolButton
|
<ActiveFile
|
||||||
type="icon"
|
onSave={() => updateData(null)}
|
||||||
icon={save}
|
fileName={appState.fileHandle?.name}
|
||||||
title={t("buttons.save")}
|
|
||||||
aria-label={t("buttons.save")}
|
|
||||||
onClick={() => updateData(null)}
|
|
||||||
data-testid="save-button"
|
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@@ -121,6 +186,13 @@ export const actionSaveFileToDisk = register({
|
|||||||
...appState,
|
...appState,
|
||||||
fileHandle: null,
|
fileHandle: null,
|
||||||
});
|
});
|
||||||
|
try {
|
||||||
|
if (fileHandle) {
|
||||||
|
await idb.set(IDB_KEYS.fileHandle, fileHandle);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
return { commitToHistory: false, appState: { ...appState, fileHandle } };
|
return { commitToHistory: false, appState: { ...appState, fileHandle } };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error?.name !== "AbortError") {
|
if (error?.name !== "AbortError") {
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ import {
|
|||||||
FillCrossHatchIcon,
|
FillCrossHatchIcon,
|
||||||
FillHachureIcon,
|
FillHachureIcon,
|
||||||
FillSolidIcon,
|
FillSolidIcon,
|
||||||
|
FontFamilyCodeIcon,
|
||||||
|
FontFamilyHandDrawnIcon,
|
||||||
|
FontFamilyNormalIcon,
|
||||||
|
FontSizeExtraLargeIcon,
|
||||||
|
FontSizeLargeIcon,
|
||||||
|
FontSizeMediumIcon,
|
||||||
|
FontSizeSmallIcon,
|
||||||
SloppinessArchitectIcon,
|
SloppinessArchitectIcon,
|
||||||
SloppinessArtistIcon,
|
SloppinessArtistIcon,
|
||||||
SloppinessCartoonistIcon,
|
SloppinessCartoonistIcon,
|
||||||
@@ -20,18 +27,15 @@ import {
|
|||||||
StrokeStyleDottedIcon,
|
StrokeStyleDottedIcon,
|
||||||
StrokeStyleSolidIcon,
|
StrokeStyleSolidIcon,
|
||||||
StrokeWidthIcon,
|
StrokeWidthIcon,
|
||||||
FontSizeSmallIcon,
|
|
||||||
FontSizeMediumIcon,
|
|
||||||
FontSizeLargeIcon,
|
|
||||||
FontSizeExtraLargeIcon,
|
|
||||||
FontFamilyHandDrawnIcon,
|
|
||||||
FontFamilyNormalIcon,
|
|
||||||
FontFamilyCodeIcon,
|
|
||||||
TextAlignLeftIcon,
|
|
||||||
TextAlignCenterIcon,
|
TextAlignCenterIcon,
|
||||||
|
TextAlignLeftIcon,
|
||||||
TextAlignRightIcon,
|
TextAlignRightIcon,
|
||||||
} from "../components/icons";
|
} from "../components/icons";
|
||||||
import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE } from "../constants";
|
import {
|
||||||
|
DEFAULT_FONT_FAMILY,
|
||||||
|
DEFAULT_FONT_SIZE,
|
||||||
|
FONT_FAMILY,
|
||||||
|
} from "../constants";
|
||||||
import {
|
import {
|
||||||
getNonDeletedElements,
|
getNonDeletedElements,
|
||||||
isTextElement,
|
isTextElement,
|
||||||
@@ -44,7 +48,7 @@ import {
|
|||||||
ExcalidrawElement,
|
ExcalidrawElement,
|
||||||
ExcalidrawLinearElement,
|
ExcalidrawLinearElement,
|
||||||
ExcalidrawTextElement,
|
ExcalidrawTextElement,
|
||||||
FontFamily,
|
FontFamilyValues,
|
||||||
TextAlign,
|
TextAlign,
|
||||||
} from "../element/types";
|
} from "../element/types";
|
||||||
import { getLanguage, t } from "../i18n";
|
import { getLanguage, t } from "../i18n";
|
||||||
@@ -126,9 +130,9 @@ export const actionChangeStrokeColor = register({
|
|||||||
appState.currentItemStrokeColor,
|
appState.currentItemStrokeColor,
|
||||||
)}
|
)}
|
||||||
onChange={(color) => updateData({ currentItemStrokeColor: color })}
|
onChange={(color) => updateData({ currentItemStrokeColor: color })}
|
||||||
isActive={appState.openMenu === "strokeColorPicker"}
|
isActive={appState.openPopup === "strokeColorPicker"}
|
||||||
setActive={(active) =>
|
setActive={(active) =>
|
||||||
updateData({ openMenu: active ? "strokeColorPicker" : null })
|
updateData({ openPopup: active ? "strokeColorPicker" : null })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@@ -166,9 +170,9 @@ export const actionChangeBackgroundColor = register({
|
|||||||
appState.currentItemBackgroundColor,
|
appState.currentItemBackgroundColor,
|
||||||
)}
|
)}
|
||||||
onChange={(color) => updateData({ currentItemBackgroundColor: color })}
|
onChange={(color) => updateData({ currentItemBackgroundColor: color })}
|
||||||
isActive={appState.openMenu === "backgroundColorPicker"}
|
isActive={appState.openPopup === "backgroundColorPicker"}
|
||||||
setActive={(active) =>
|
setActive={(active) =>
|
||||||
updateData({ openMenu: active ? "backgroundColorPicker" : null })
|
updateData({ openPopup: active ? "backgroundColorPicker" : null })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@@ -499,19 +503,23 @@ export const actionChangeFontFamily = register({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
PanelComponent: ({ elements, appState, updateData }) => {
|
PanelComponent: ({ elements, appState, updateData }) => {
|
||||||
const options: { value: FontFamily; text: string; icon: JSX.Element }[] = [
|
const options: {
|
||||||
|
value: FontFamilyValues;
|
||||||
|
text: string;
|
||||||
|
icon: JSX.Element;
|
||||||
|
}[] = [
|
||||||
{
|
{
|
||||||
value: 1,
|
value: FONT_FAMILY.Virgil,
|
||||||
text: t("labels.handDrawn"),
|
text: t("labels.handDrawn"),
|
||||||
icon: <FontFamilyHandDrawnIcon theme={appState.theme} />,
|
icon: <FontFamilyHandDrawnIcon theme={appState.theme} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 2,
|
value: FONT_FAMILY.Helvetica,
|
||||||
text: t("labels.normal"),
|
text: t("labels.normal"),
|
||||||
icon: <FontFamilyNormalIcon theme={appState.theme} />,
|
icon: <FontFamilyNormalIcon theme={appState.theme} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 3,
|
value: FONT_FAMILY.Cascadia,
|
||||||
text: t("labels.code"),
|
text: t("labels.code"),
|
||||||
icon: <FontFamilyCodeIcon theme={appState.theme} />,
|
icon: <FontFamilyCodeIcon theme={appState.theme} />,
|
||||||
},
|
},
|
||||||
@@ -520,7 +528,7 @@ export const actionChangeFontFamily = register({
|
|||||||
return (
|
return (
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t("labels.fontFamily")}</legend>
|
<legend>{t("labels.fontFamily")}</legend>
|
||||||
<ButtonIconSelect<FontFamily | false>
|
<ButtonIconSelect<FontFamilyValues | false>
|
||||||
group="font-family"
|
group="font-family"
|
||||||
options={options}
|
options={options}
|
||||||
value={getFormValue(
|
value={getFormValue(
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ export type ActionName =
|
|||||||
| "changeProjectName"
|
| "changeProjectName"
|
||||||
| "changeExportBackground"
|
| "changeExportBackground"
|
||||||
| "changeExportEmbedScene"
|
| "changeExportEmbedScene"
|
||||||
|
| "changeExportScale"
|
||||||
| "saveToActiveFile"
|
| "saveToActiveFile"
|
||||||
| "saveFileToDisk"
|
| "saveFileToDisk"
|
||||||
| "loadScene"
|
| "loadScene"
|
||||||
|
|||||||
@@ -3,11 +3,16 @@ import {
|
|||||||
DEFAULT_FONT_FAMILY,
|
DEFAULT_FONT_FAMILY,
|
||||||
DEFAULT_FONT_SIZE,
|
DEFAULT_FONT_SIZE,
|
||||||
DEFAULT_TEXT_ALIGN,
|
DEFAULT_TEXT_ALIGN,
|
||||||
|
EXPORT_SCALES,
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import { t } from "./i18n";
|
import { t } from "./i18n";
|
||||||
import { AppState, NormalizedZoomValue } from "./types";
|
import { AppState, NormalizedZoomValue } from "./types";
|
||||||
import { getDateTime } from "./utils";
|
import { getDateTime } from "./utils";
|
||||||
|
|
||||||
|
const defaultExportScale = EXPORT_SCALES.includes(devicePixelRatio)
|
||||||
|
? devicePixelRatio
|
||||||
|
: 1;
|
||||||
|
|
||||||
export const getDefaultAppState = (): Omit<
|
export const getDefaultAppState = (): Omit<
|
||||||
AppState,
|
AppState,
|
||||||
"offsetTop" | "offsetLeft" | "width" | "height"
|
"offsetTop" | "offsetLeft" | "width" | "height"
|
||||||
@@ -39,6 +44,7 @@ export const getDefaultAppState = (): Omit<
|
|||||||
elementType: "selection",
|
elementType: "selection",
|
||||||
errorMessage: null,
|
errorMessage: null,
|
||||||
exportBackground: true,
|
exportBackground: true,
|
||||||
|
exportScale: defaultExportScale,
|
||||||
exportEmbedScene: false,
|
exportEmbedScene: false,
|
||||||
exportWithDarkMode: false,
|
exportWithDarkMode: false,
|
||||||
fileHandle: null,
|
fileHandle: null,
|
||||||
@@ -52,6 +58,7 @@ export const getDefaultAppState = (): Omit<
|
|||||||
multiElement: null,
|
multiElement: null,
|
||||||
name: `${t("labels.untitled")}-${getDateTime()}`,
|
name: `${t("labels.untitled")}-${getDateTime()}`,
|
||||||
openMenu: null,
|
openMenu: null,
|
||||||
|
openPopup: null,
|
||||||
pasteDialog: { shown: false, data: null },
|
pasteDialog: { shown: false, data: null },
|
||||||
previousSelectedElementIds: {},
|
previousSelectedElementIds: {},
|
||||||
resizingElement: null,
|
resizingElement: null,
|
||||||
@@ -116,6 +123,7 @@ const APP_STATE_STORAGE_CONF = (<
|
|||||||
errorMessage: { browser: false, export: false },
|
errorMessage: { browser: false, export: false },
|
||||||
exportBackground: { browser: true, export: false },
|
exportBackground: { browser: true, export: false },
|
||||||
exportEmbedScene: { browser: true, export: false },
|
exportEmbedScene: { browser: true, export: false },
|
||||||
|
exportScale: { browser: true, export: false },
|
||||||
exportWithDarkMode: { browser: true, export: false },
|
exportWithDarkMode: { browser: true, export: false },
|
||||||
fileHandle: { browser: false, export: false },
|
fileHandle: { browser: false, export: false },
|
||||||
gridSize: { browser: true, export: true },
|
gridSize: { browser: true, export: true },
|
||||||
@@ -131,6 +139,7 @@ const APP_STATE_STORAGE_CONF = (<
|
|||||||
offsetLeft: { browser: false, export: false },
|
offsetLeft: { browser: false, export: false },
|
||||||
offsetTop: { browser: false, export: false },
|
offsetTop: { browser: false, export: false },
|
||||||
openMenu: { browser: true, export: false },
|
openMenu: { browser: true, export: false },
|
||||||
|
openPopup: { browser: false, export: false },
|
||||||
pasteDialog: { browser: false, export: false },
|
pasteDialog: { browser: false, export: false },
|
||||||
previousSelectedElementIds: { browser: true, export: false },
|
previousSelectedElementIds: { browser: true, export: false },
|
||||||
resizingElement: { browser: false, export: false },
|
resizingElement: { browser: false, export: false },
|
||||||
|
|||||||
@@ -151,23 +151,14 @@ export const SelectedShapeActions = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const LIBRARY_ICON = (
|
|
||||||
// fa-th-large
|
|
||||||
<svg viewBox="0 0 512 512">
|
|
||||||
<path d="M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
|
|
||||||
export const ShapesSwitcher = ({
|
export const ShapesSwitcher = ({
|
||||||
canvas,
|
canvas,
|
||||||
elementType,
|
elementType,
|
||||||
setAppState,
|
setAppState,
|
||||||
isLibraryOpen,
|
|
||||||
}: {
|
}: {
|
||||||
canvas: HTMLCanvasElement | null;
|
canvas: HTMLCanvasElement | null;
|
||||||
elementType: ExcalidrawElement["type"];
|
elementType: ExcalidrawElement["type"];
|
||||||
setAppState: React.Component<any, AppState>["setState"];
|
setAppState: React.Component<any, AppState>["setState"];
|
||||||
isLibraryOpen: boolean;
|
|
||||||
}) => (
|
}) => (
|
||||||
<>
|
<>
|
||||||
{SHAPES.map(({ value, icon, key }, index) => {
|
{SHAPES.map(({ value, icon, key }, index) => {
|
||||||
@@ -201,19 +192,6 @@ export const ShapesSwitcher = ({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<ToolButton
|
|
||||||
className="Shape ToolIcon_type_button__library"
|
|
||||||
type="button"
|
|
||||||
icon={LIBRARY_ICON}
|
|
||||||
name="editor-library"
|
|
||||||
keyBindingLabel="9"
|
|
||||||
aria-keyshortcuts="9"
|
|
||||||
title={`${capitalizeString(t("toolBar.library"))} — 9`}
|
|
||||||
aria-label={capitalizeString(t("toolBar.library"))}
|
|
||||||
onClick={() => {
|
|
||||||
setAppState({ isLibraryOpen: !isLibraryOpen });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
.excalidraw {
|
||||||
|
.ActiveFile {
|
||||||
|
.ActiveFile__fileName {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 9.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 1.15em;
|
||||||
|
margin-inline-end: 0.3em;
|
||||||
|
transform: scaleY(0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Stack from "../components/Stack";
|
||||||
|
import { ToolButton } from "../components/ToolButton";
|
||||||
|
import { save, file } from "../components/icons";
|
||||||
|
import { t } from "../i18n";
|
||||||
|
|
||||||
|
import "./ActiveFile.scss";
|
||||||
|
|
||||||
|
type ActiveFileProps = {
|
||||||
|
fileName?: string;
|
||||||
|
onSave: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ActiveFile = ({ fileName, onSave }: ActiveFileProps) => (
|
||||||
|
<Stack.Row className="ActiveFile" gap={1} align="center">
|
||||||
|
<span className="ActiveFile__fileName">
|
||||||
|
{file}
|
||||||
|
<span>{fileName}</span>
|
||||||
|
</span>
|
||||||
|
<ToolButton
|
||||||
|
type="icon"
|
||||||
|
icon={save}
|
||||||
|
title={t("buttons.save")}
|
||||||
|
aria-label={t("buttons.save")}
|
||||||
|
onClick={onSave}
|
||||||
|
data-testid="save-button"
|
||||||
|
/>
|
||||||
|
</Stack.Row>
|
||||||
|
);
|
||||||
+37
-90
@@ -52,6 +52,7 @@ import {
|
|||||||
ENV,
|
ENV,
|
||||||
EVENT,
|
EVENT,
|
||||||
GRID_SIZE,
|
GRID_SIZE,
|
||||||
|
IDB_KEYS,
|
||||||
LINE_CONFIRM_THRESHOLD,
|
LINE_CONFIRM_THRESHOLD,
|
||||||
MIME_TYPES,
|
MIME_TYPES,
|
||||||
MQ_MAX_HEIGHT_LANDSCAPE,
|
MQ_MAX_HEIGHT_LANDSCAPE,
|
||||||
@@ -111,7 +112,6 @@ import {
|
|||||||
import { LinearElementEditor } from "../element/linearElementEditor";
|
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||||
import { mutateElement } from "../element/mutateElement";
|
import { mutateElement } from "../element/mutateElement";
|
||||||
import { deepCopyElement, newFreeDrawElement } from "../element/newElement";
|
import { deepCopyElement, newFreeDrawElement } from "../element/newElement";
|
||||||
import { MaybeTransformHandleType } from "../element/transformHandles";
|
|
||||||
import {
|
import {
|
||||||
isBindingElement,
|
isBindingElement,
|
||||||
isBindingElementType,
|
isBindingElementType,
|
||||||
@@ -167,9 +167,11 @@ import { findShapeByKey } from "../shapes";
|
|||||||
import {
|
import {
|
||||||
AppProps,
|
AppProps,
|
||||||
AppState,
|
AppState,
|
||||||
|
ExcalidrawImperativeAPI,
|
||||||
Gesture,
|
Gesture,
|
||||||
GestureEvent,
|
GestureEvent,
|
||||||
LibraryItems,
|
LibraryItems,
|
||||||
|
PointerDownState,
|
||||||
SceneData,
|
SceneData,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import {
|
import {
|
||||||
@@ -180,7 +182,6 @@ import {
|
|||||||
isToolIcon,
|
isToolIcon,
|
||||||
isWritableElement,
|
isWritableElement,
|
||||||
resetCursor,
|
resetCursor,
|
||||||
ResolvablePromise,
|
|
||||||
resolvablePromise,
|
resolvablePromise,
|
||||||
sceneCoordsToViewportCoords,
|
sceneCoordsToViewportCoords,
|
||||||
setCursor,
|
setCursor,
|
||||||
@@ -194,12 +195,14 @@ import LayerUI from "./LayerUI";
|
|||||||
import { Stats } from "./Stats";
|
import { Stats } from "./Stats";
|
||||||
import { Toast } from "./Toast";
|
import { Toast } from "./Toast";
|
||||||
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
|
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
|
||||||
|
import * as idb from "idb-keyval";
|
||||||
|
|
||||||
const IsMobileContext = React.createContext(false);
|
const IsMobileContext = React.createContext(false);
|
||||||
export const useIsMobile = () => useContext(IsMobileContext);
|
export const useIsMobile = () => useContext(IsMobileContext);
|
||||||
const ExcalidrawContainerContext = React.createContext<HTMLDivElement | null>(
|
const ExcalidrawContainerContext = React.createContext<{
|
||||||
null,
|
container: HTMLDivElement | null;
|
||||||
);
|
id: string | null;
|
||||||
|
}>({ container: null, id: null });
|
||||||
export const useExcalidrawContainer = () =>
|
export const useExcalidrawContainer = () =>
|
||||||
useContext(ExcalidrawContainerContext);
|
useContext(ExcalidrawContainerContext);
|
||||||
|
|
||||||
@@ -222,83 +225,6 @@ const gesture: Gesture = {
|
|||||||
initialScale: null,
|
initialScale: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PointerDownState = Readonly<{
|
|
||||||
// The first position at which pointerDown happened
|
|
||||||
origin: Readonly<{ x: number; y: number }>;
|
|
||||||
// Same as "origin" but snapped to the grid, if grid is on
|
|
||||||
originInGrid: Readonly<{ x: number; y: number }>;
|
|
||||||
// Scrollbar checks
|
|
||||||
scrollbars: ReturnType<typeof isOverScrollBars>;
|
|
||||||
// The previous pointer position
|
|
||||||
lastCoords: { x: number; y: number };
|
|
||||||
// map of original elements data
|
|
||||||
originalElements: Map<string, NonDeleted<ExcalidrawElement>>;
|
|
||||||
resize: {
|
|
||||||
// Handle when resizing, might change during the pointer interaction
|
|
||||||
handleType: MaybeTransformHandleType;
|
|
||||||
// This is determined on the initial pointer down event
|
|
||||||
isResizing: boolean;
|
|
||||||
// This is determined on the initial pointer down event
|
|
||||||
offset: { x: number; y: number };
|
|
||||||
// This is determined on the initial pointer down event
|
|
||||||
arrowDirection: "origin" | "end";
|
|
||||||
// This is a center point of selected elements determined on the initial pointer down event (for rotation only)
|
|
||||||
center: { x: number; y: number };
|
|
||||||
};
|
|
||||||
hit: {
|
|
||||||
// The element the pointer is "hitting", is determined on the initial
|
|
||||||
// pointer down event
|
|
||||||
element: NonDeleted<ExcalidrawElement> | null;
|
|
||||||
// The elements the pointer is "hitting", is determined on the initial
|
|
||||||
// pointer down event
|
|
||||||
allHitElements: NonDeleted<ExcalidrawElement>[];
|
|
||||||
// This is determined on the initial pointer down event
|
|
||||||
wasAddedToSelection: boolean;
|
|
||||||
// Whether selected element(s) were duplicated, might change during the
|
|
||||||
// pointer interaction
|
|
||||||
hasBeenDuplicated: boolean;
|
|
||||||
hasHitCommonBoundingBoxOfSelectedElements: boolean;
|
|
||||||
};
|
|
||||||
withCmdOrCtrl: boolean;
|
|
||||||
drag: {
|
|
||||||
// Might change during the pointer interation
|
|
||||||
hasOccurred: boolean;
|
|
||||||
// Might change during the pointer interation
|
|
||||||
offset: { x: number; y: number } | null;
|
|
||||||
};
|
|
||||||
// We need to have these in the state so that we can unsubscribe them
|
|
||||||
eventListeners: {
|
|
||||||
// It's defined on the initial pointer down event
|
|
||||||
onMove: null | ((event: PointerEvent) => void);
|
|
||||||
// It's defined on the initial pointer down event
|
|
||||||
onUp: null | ((event: PointerEvent) => void);
|
|
||||||
// It's defined on the initial pointer down event
|
|
||||||
onKeyDown: null | ((event: KeyboardEvent) => void);
|
|
||||||
// It's defined on the initial pointer down event
|
|
||||||
onKeyUp: null | ((event: KeyboardEvent) => void);
|
|
||||||
};
|
|
||||||
}>;
|
|
||||||
|
|
||||||
export type ExcalidrawImperativeAPI = {
|
|
||||||
updateScene: InstanceType<typeof App>["updateScene"];
|
|
||||||
resetScene: InstanceType<typeof App>["resetScene"];
|
|
||||||
getSceneElementsIncludingDeleted: InstanceType<
|
|
||||||
typeof App
|
|
||||||
>["getSceneElementsIncludingDeleted"];
|
|
||||||
history: {
|
|
||||||
clear: InstanceType<typeof App>["resetHistory"];
|
|
||||||
};
|
|
||||||
scrollToContent: InstanceType<typeof App>["scrollToContent"];
|
|
||||||
getSceneElements: InstanceType<typeof App>["getSceneElements"];
|
|
||||||
getAppState: () => InstanceType<typeof App>["state"];
|
|
||||||
refresh: InstanceType<typeof App>["refresh"];
|
|
||||||
importLibrary: InstanceType<typeof App>["importLibraryFromUrl"];
|
|
||||||
setToastMessage: InstanceType<typeof App>["setToastMessage"];
|
|
||||||
readyPromise: ResolvablePromise<ExcalidrawImperativeAPI>;
|
|
||||||
ready: true;
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
class App extends React.Component<AppProps, AppState> {
|
class App extends React.Component<AppProps, AppState> {
|
||||||
canvas: HTMLCanvasElement | null = null;
|
canvas: HTMLCanvasElement | null = null;
|
||||||
rc: RoughCanvas | null = null;
|
rc: RoughCanvas | null = null;
|
||||||
@@ -321,6 +247,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
public libraryItemsFromStorage: LibraryItems | undefined;
|
public libraryItemsFromStorage: LibraryItems | undefined;
|
||||||
private id: string;
|
private id: string;
|
||||||
private history: History;
|
private history: History;
|
||||||
|
private excalidrawContainerValue: {
|
||||||
|
container: HTMLDivElement | null;
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
constructor(props: AppProps) {
|
constructor(props: AppProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -377,6 +307,12 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
readyPromise.resolve(api);
|
readyPromise.resolve(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.excalidrawContainerValue = {
|
||||||
|
container: this.excalidrawContainerRef.current,
|
||||||
|
id: this.id,
|
||||||
|
};
|
||||||
|
|
||||||
this.scene = new Scene();
|
this.scene = new Scene();
|
||||||
this.library = new Library(this);
|
this.library = new Library(this);
|
||||||
this.history = new History();
|
this.history = new History();
|
||||||
@@ -404,7 +340,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
if (viewModeEnabled) {
|
if (viewModeEnabled) {
|
||||||
return (
|
return (
|
||||||
<canvas
|
<canvas
|
||||||
id="canvas"
|
className="excalidraw__canvas"
|
||||||
style={{
|
style={{
|
||||||
width: canvasDOMWidth,
|
width: canvasDOMWidth,
|
||||||
height: canvasDOMHeight,
|
height: canvasDOMHeight,
|
||||||
@@ -426,7 +362,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<canvas
|
<canvas
|
||||||
id="canvas"
|
className="excalidraw__canvas"
|
||||||
style={{
|
style={{
|
||||||
width: canvasDOMWidth,
|
width: canvasDOMWidth,
|
||||||
height: canvasDOMHeight,
|
height: canvasDOMHeight,
|
||||||
@@ -471,7 +407,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ExcalidrawContainerContext.Provider
|
<ExcalidrawContainerContext.Provider
|
||||||
value={this.excalidrawContainerRef.current}
|
value={this.excalidrawContainerValue}
|
||||||
>
|
>
|
||||||
<IsMobileContext.Provider value={this.isMobile}>
|
<IsMobileContext.Provider value={this.isMobile}>
|
||||||
<LayerUI
|
<LayerUI
|
||||||
@@ -534,7 +470,9 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public focusContainer = () => {
|
public focusContainer = () => {
|
||||||
this.excalidrawContainerRef.current?.focus();
|
if (this.props.autoFocus) {
|
||||||
|
this.excalidrawContainerRef.current?.focus();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public getSceneElementsIncludingDeleted = () => {
|
public getSceneElementsIncludingDeleted = () => {
|
||||||
@@ -800,6 +738,8 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public async componentDidMount() {
|
public async componentDidMount() {
|
||||||
|
this.excalidrawContainerValue.container = this.excalidrawContainerRef.current;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
process.env.NODE_ENV === ENV.TEST ||
|
process.env.NODE_ENV === ENV.TEST ||
|
||||||
process.env.NODE_ENV === ENV.DEVELOPMENT
|
process.env.NODE_ENV === ENV.DEVELOPMENT
|
||||||
@@ -869,6 +809,15 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
} else {
|
} else {
|
||||||
this.updateDOMRect(this.initializeScene);
|
this.updateDOMRect(this.initializeScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fileHandle = await idb.get(IDB_KEYS.fileHandle);
|
||||||
|
if (fileHandle) {
|
||||||
|
this.setState({ fileHandle });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
@@ -1651,10 +1600,10 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
);
|
);
|
||||||
if (selectedElements.length) {
|
if (selectedElements.length) {
|
||||||
if (event.key === KEYS.G) {
|
if (event.key === KEYS.G) {
|
||||||
this.setState({ openMenu: "backgroundColorPicker" });
|
this.setState({ openPopup: "backgroundColorPicker" });
|
||||||
}
|
}
|
||||||
if (event.key === KEYS.S) {
|
if (event.key === KEYS.S) {
|
||||||
this.setState({ openMenu: "strokeColorPicker" });
|
this.setState({ openPopup: "strokeColorPicker" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2308,8 +2257,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
private handleCanvasPointerDown = (
|
private handleCanvasPointerDown = (
|
||||||
event: React.PointerEvent<HTMLCanvasElement>,
|
event: React.PointerEvent<HTMLCanvasElement>,
|
||||||
) => {
|
) => {
|
||||||
event.persist();
|
|
||||||
|
|
||||||
// remove any active selection when we start to interact with canvas
|
// remove any active selection when we start to interact with canvas
|
||||||
// (mainly, we care about removing selection outside the component which
|
// (mainly, we care about removing selection outside the component which
|
||||||
// would prevent our copy handling otherwise)
|
// would prevent our copy handling otherwise)
|
||||||
|
|||||||
@@ -16,10 +16,5 @@ export const BackgroundPickerAndDarkModeToggle = ({
|
|||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
{actionManager.renderAction("changeViewBackgroundColor")}
|
{actionManager.renderAction("changeViewBackgroundColor")}
|
||||||
{showThemeBtn && actionManager.renderAction("toggleTheme")}
|
{showThemeBtn && actionManager.renderAction("toggleTheme")}
|
||||||
{appState.fileHandle && (
|
|
||||||
<div style={{ marginInlineStart: "0.25rem" }}>
|
|
||||||
{actionManager.renderAction("saveToActiveFile")}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import clsx from "clsx";
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useCallbackRefState } from "../hooks/useCallbackRefState";
|
import { useCallbackRefState } from "../hooks/useCallbackRefState";
|
||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
import { useIsMobile } from "../components/App";
|
import { useExcalidrawContainer, useIsMobile } from "../components/App";
|
||||||
import { KEYS } from "../keys";
|
import { KEYS } from "../keys";
|
||||||
import "./Dialog.scss";
|
import "./Dialog.scss";
|
||||||
import { back, close } from "./icons";
|
import { back, close } from "./icons";
|
||||||
@@ -21,6 +21,7 @@ export const Dialog = (props: {
|
|||||||
}) => {
|
}) => {
|
||||||
const [islandNode, setIslandNode] = useCallbackRefState<HTMLDivElement>();
|
const [islandNode, setIslandNode] = useCallbackRefState<HTMLDivElement>();
|
||||||
const [lastActiveElement] = useState(document.activeElement);
|
const [lastActiveElement] = useState(document.activeElement);
|
||||||
|
const { id } = useExcalidrawContainer();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!islandNode) {
|
if (!islandNode) {
|
||||||
@@ -82,7 +83,7 @@ export const Dialog = (props: {
|
|||||||
theme={props.theme}
|
theme={props.theme}
|
||||||
>
|
>
|
||||||
<Island ref={setIslandNode}>
|
<Island ref={setIslandNode}>
|
||||||
<h2 id="dialog-title" className="Dialog__title">
|
<h2 id={`${id}-dialog-title`} className="Dialog__title">
|
||||||
<span className="Dialog__titleContent">{props.title}</span>
|
<span className="Dialog__titleContent">{props.title}</span>
|
||||||
<button
|
<button
|
||||||
className="Modal__close"
|
className="Modal__close"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const ErrorDialog = ({
|
|||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [modalIsShown, setModalIsShown] = useState(!!message);
|
const [modalIsShown, setModalIsShown] = useState(!!message);
|
||||||
const excalidrawContainer = useExcalidrawContainer();
|
const { container: excalidrawContainer } = useExcalidrawContainer();
|
||||||
|
|
||||||
const handleClose = React.useCallback(() => {
|
const handleClose = React.useCallback(() => {
|
||||||
setModalIsShown(false);
|
setModalIsShown(false);
|
||||||
|
|||||||
@@ -97,7 +97,8 @@
|
|||||||
|
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
background-color: var(--button-color);
|
background-color: var(--button-color);
|
||||||
box-shadow: 0 3px 5px -1px rgb(0 0 0 / 28%), 0 6px 10px 0 rgb(0 0 0 / 14%);
|
box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.28),
|
||||||
|
0 6px 10px 0 rgba(0, 0, 0, 0.14);
|
||||||
|
|
||||||
font-family: Cascadia;
|
font-family: Cascadia;
|
||||||
font-size: 1.8em;
|
font-size: 1.8em;
|
||||||
|
|||||||
@@ -157,6 +157,13 @@ export const HelpDialog = ({ onClose }: { onClose?: () => void }) => {
|
|||||||
shortcuts={["Shift+P", "7"]}
|
shortcuts={["Shift+P", "7"]}
|
||||||
/>
|
/>
|
||||||
<Shortcut label={t("toolBar.text")} shortcuts={["T", "8"]} />
|
<Shortcut label={t("toolBar.text")} shortcuts={["T", "8"]} />
|
||||||
|
<Shortcut
|
||||||
|
label={t("helpDialog.editSelectedShape")}
|
||||||
|
shortcuts={[
|
||||||
|
getShortcutKey("Enter"),
|
||||||
|
t("helpDialog.doubleClick"),
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<Shortcut
|
<Shortcut
|
||||||
label={t("helpDialog.textNewLine")}
|
label={t("helpDialog.textNewLine")}
|
||||||
shortcuts={[
|
shortcuts={[
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { getSelectedElements } from "../scene";
|
|||||||
|
|
||||||
import "./HintViewer.scss";
|
import "./HintViewer.scss";
|
||||||
import { AppState } from "../types";
|
import { AppState } from "../types";
|
||||||
import { isLinearElement } from "../element/typeChecks";
|
import { isLinearElement, isTextElement } from "../element/typeChecks";
|
||||||
import { getShortcutKey } from "../utils";
|
import { getShortcutKey } from "../utils";
|
||||||
|
|
||||||
interface Hint {
|
interface Hint {
|
||||||
@@ -57,6 +57,14 @@ const getHints = ({ appState, elements }: Hint) => {
|
|||||||
return t("hints.lineEditor_info");
|
return t("hints.lineEditor_info");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedElements.length === 1 && isTextElement(selectedElements[0])) {
|
||||||
|
return t("hints.text_selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appState.editingElement && isTextElement(appState.editingElement)) {
|
||||||
|
return t("hints.text_editing");
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,20 +8,17 @@ import { CanvasError } from "../errors";
|
|||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
import { useIsMobile } from "./App";
|
import { useIsMobile } from "./App";
|
||||||
import { getSelectedElements, isSomeElementSelected } from "../scene";
|
import { getSelectedElements, isSomeElementSelected } from "../scene";
|
||||||
import { exportToCanvas, getExportSize } from "../scene/export";
|
import { exportToCanvas } from "../scene/export";
|
||||||
import { AppState } from "../types";
|
import { AppState } from "../types";
|
||||||
import { Dialog } from "./Dialog";
|
import { Dialog } from "./Dialog";
|
||||||
import { clipboard, exportImage } from "./icons";
|
import { clipboard, exportImage } from "./icons";
|
||||||
import Stack from "./Stack";
|
import Stack from "./Stack";
|
||||||
import { ToolButton } from "./ToolButton";
|
import { ToolButton } from "./ToolButton";
|
||||||
|
|
||||||
import "./ExportDialog.scss";
|
import "./ExportDialog.scss";
|
||||||
import { supported as fsSupported } from "browser-fs-access";
|
import { supported as fsSupported } from "browser-fs-access";
|
||||||
import OpenColor from "open-color";
|
import OpenColor from "open-color";
|
||||||
import { CheckboxItem } from "./CheckboxItem";
|
import { CheckboxItem } from "./CheckboxItem";
|
||||||
|
import { DEFAULT_EXPORT_PADDING } from "../constants";
|
||||||
const scales = [1, 2, 3];
|
|
||||||
const defaultScale = scales.includes(devicePixelRatio) ? devicePixelRatio : 1;
|
|
||||||
|
|
||||||
const supportsContextFilters =
|
const supportsContextFilters =
|
||||||
"filter" in document.createElement("canvas").getContext("2d")!;
|
"filter" in document.createElement("canvas").getContext("2d")!;
|
||||||
@@ -82,7 +79,7 @@ const ExportButton: React.FC<{
|
|||||||
const ImageExportModal = ({
|
const ImageExportModal = ({
|
||||||
elements,
|
elements,
|
||||||
appState,
|
appState,
|
||||||
exportPadding = 10,
|
exportPadding = DEFAULT_EXPORT_PADDING,
|
||||||
actionManager,
|
actionManager,
|
||||||
onExportToPng,
|
onExportToPng,
|
||||||
onExportToSvg,
|
onExportToSvg,
|
||||||
@@ -98,7 +95,6 @@ const ImageExportModal = ({
|
|||||||
onCloseRequest: () => void;
|
onCloseRequest: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const someElementIsSelected = isSomeElementSelected(elements, appState);
|
const someElementIsSelected = isSomeElementSelected(elements, appState);
|
||||||
const [scale, setScale] = useState(defaultScale);
|
|
||||||
const [exportSelected, setExportSelected] = useState(someElementIsSelected);
|
const [exportSelected, setExportSelected] = useState(someElementIsSelected);
|
||||||
const previewRef = useRef<HTMLDivElement>(null);
|
const previewRef = useRef<HTMLDivElement>(null);
|
||||||
const { exportBackground, viewBackgroundColor } = appState;
|
const { exportBackground, viewBackgroundColor } = appState;
|
||||||
@@ -121,7 +117,6 @@ const ImageExportModal = ({
|
|||||||
exportBackground,
|
exportBackground,
|
||||||
viewBackgroundColor,
|
viewBackgroundColor,
|
||||||
exportPadding,
|
exportPadding,
|
||||||
scale,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// if converting to blob fails, there's some problem that will
|
// if converting to blob fails, there's some problem that will
|
||||||
@@ -144,7 +139,6 @@ const ImageExportModal = ({
|
|||||||
exportBackground,
|
exportBackground,
|
||||||
exportPadding,
|
exportPadding,
|
||||||
viewBackgroundColor,
|
viewBackgroundColor,
|
||||||
scale,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -175,33 +169,8 @@ const ImageExportModal = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: "flex", alignItems: "center", marginTop: ".6em" }}>
|
<div style={{ display: "flex", alignItems: "center", marginTop: ".6em" }}>
|
||||||
<Stack.Row gap={2} justifyContent={"center"}>
|
<Stack.Row gap={2}>
|
||||||
{scales.map((_scale) => {
|
{actionManager.renderAction("changeExportScale")}
|
||||||
const [width, height] = getExportSize(
|
|
||||||
exportedElements,
|
|
||||||
exportPadding,
|
|
||||||
_scale,
|
|
||||||
);
|
|
||||||
|
|
||||||
const scaleButtonTitle = `${t(
|
|
||||||
"buttons.scale",
|
|
||||||
)} ${_scale}x (${width}x${height})`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ToolButton
|
|
||||||
key={_scale}
|
|
||||||
size="s"
|
|
||||||
type="radio"
|
|
||||||
icon={`${_scale}x`}
|
|
||||||
name="export-canvas-scale"
|
|
||||||
title={scaleButtonTitle}
|
|
||||||
aria-label={scaleButtonTitle}
|
|
||||||
id="export-canvas-scale"
|
|
||||||
checked={_scale === scale}
|
|
||||||
onChange={() => setScale(_scale)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Stack.Row>
|
</Stack.Row>
|
||||||
<p style={{ marginLeft: "1em", userSelect: "none" }}>Scale</p>
|
<p style={{ marginLeft: "1em", userSelect: "none" }}>Scale</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -220,7 +189,7 @@ const ImageExportModal = ({
|
|||||||
color="indigo"
|
color="indigo"
|
||||||
title={t("buttons.exportToPng")}
|
title={t("buttons.exportToPng")}
|
||||||
aria-label={t("buttons.exportToPng")}
|
aria-label={t("buttons.exportToPng")}
|
||||||
onClick={() => onExportToPng(exportedElements, scale)}
|
onClick={() => onExportToPng(exportedElements)}
|
||||||
>
|
>
|
||||||
PNG
|
PNG
|
||||||
</ExportButton>
|
</ExportButton>
|
||||||
@@ -228,14 +197,14 @@ const ImageExportModal = ({
|
|||||||
color="red"
|
color="red"
|
||||||
title={t("buttons.exportToSvg")}
|
title={t("buttons.exportToSvg")}
|
||||||
aria-label={t("buttons.exportToSvg")}
|
aria-label={t("buttons.exportToSvg")}
|
||||||
onClick={() => onExportToSvg(exportedElements, scale)}
|
onClick={() => onExportToSvg(exportedElements)}
|
||||||
>
|
>
|
||||||
SVG
|
SVG
|
||||||
</ExportButton>
|
</ExportButton>
|
||||||
{probablySupportsClipboardBlob && (
|
{probablySupportsClipboardBlob && (
|
||||||
<ExportButton
|
<ExportButton
|
||||||
title={t("buttons.copyPngToClipboard")}
|
title={t("buttons.copyPngToClipboard")}
|
||||||
onClick={() => onExportToClipboard(exportedElements, scale)}
|
onClick={() => onExportToClipboard(exportedElements)}
|
||||||
color="gray"
|
color="gray"
|
||||||
shade={7}
|
shade={7}
|
||||||
>
|
>
|
||||||
@@ -250,7 +219,7 @@ const ImageExportModal = ({
|
|||||||
export const ImageExportDialog = ({
|
export const ImageExportDialog = ({
|
||||||
elements,
|
elements,
|
||||||
appState,
|
appState,
|
||||||
exportPadding = 10,
|
exportPadding = DEFAULT_EXPORT_PADDING,
|
||||||
actionManager,
|
actionManager,
|
||||||
onExportToPng,
|
onExportToPng,
|
||||||
onExportToSvg,
|
onExportToSvg,
|
||||||
|
|||||||
+23
-11
@@ -36,7 +36,7 @@ import { Island } from "./Island";
|
|||||||
import "./LayerUI.scss";
|
import "./LayerUI.scss";
|
||||||
import { LibraryUnit } from "./LibraryUnit";
|
import { LibraryUnit } from "./LibraryUnit";
|
||||||
import { LoadingMessage } from "./LoadingMessage";
|
import { LoadingMessage } from "./LoadingMessage";
|
||||||
import { LockIcon } from "./LockIcon";
|
import { LockButton } from "./LockButton";
|
||||||
import { MobileMenu } from "./MobileMenu";
|
import { MobileMenu } from "./MobileMenu";
|
||||||
import { PasteChartDialog } from "./PasteChartDialog";
|
import { PasteChartDialog } from "./PasteChartDialog";
|
||||||
import { Section } from "./Section";
|
import { Section } from "./Section";
|
||||||
@@ -47,6 +47,7 @@ import { Tooltip } from "./Tooltip";
|
|||||||
import { UserList } from "./UserList";
|
import { UserList } from "./UserList";
|
||||||
import Library from "../data/library";
|
import Library from "../data/library";
|
||||||
import { JSONExportDialog } from "./JSONExportDialog";
|
import { JSONExportDialog } from "./JSONExportDialog";
|
||||||
|
import { LibraryButton } from "./LibraryButton";
|
||||||
|
|
||||||
interface LayerUIProps {
|
interface LayerUIProps {
|
||||||
actionManager: ActionManager;
|
actionManager: ActionManager;
|
||||||
@@ -107,6 +108,7 @@ const LibraryMenuItems = ({
|
|||||||
onAddToLibrary,
|
onAddToLibrary,
|
||||||
onInsertShape,
|
onInsertShape,
|
||||||
pendingElements,
|
pendingElements,
|
||||||
|
theme,
|
||||||
setAppState,
|
setAppState,
|
||||||
setLibraryItems,
|
setLibraryItems,
|
||||||
libraryReturnUrl,
|
libraryReturnUrl,
|
||||||
@@ -119,6 +121,7 @@ const LibraryMenuItems = ({
|
|||||||
onRemoveFromLibrary: (index: number) => void;
|
onRemoveFromLibrary: (index: number) => void;
|
||||||
onInsertShape: (elements: LibraryItem) => void;
|
onInsertShape: (elements: LibraryItem) => void;
|
||||||
onAddToLibrary: (elements: LibraryItem) => void;
|
onAddToLibrary: (elements: LibraryItem) => void;
|
||||||
|
theme: AppState["theme"];
|
||||||
setAppState: React.Component<any, AppState>["setState"];
|
setAppState: React.Component<any, AppState>["setState"];
|
||||||
setLibraryItems: (library: LibraryItems) => void;
|
setLibraryItems: (library: LibraryItems) => void;
|
||||||
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
|
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
|
||||||
@@ -192,7 +195,7 @@ const LibraryMenuItems = ({
|
|||||||
<a
|
<a
|
||||||
href={`https://libraries.excalidraw.com?target=${
|
href={`https://libraries.excalidraw.com?target=${
|
||||||
window.name || "_blank"
|
window.name || "_blank"
|
||||||
}&referrer=${referrer}&useHash=true&token=${id}`}
|
}&referrer=${referrer}&useHash=true&token=${id}&theme=${theme}`}
|
||||||
target="_excalidraw_libraries"
|
target="_excalidraw_libraries"
|
||||||
>
|
>
|
||||||
{t("labels.libraries")}
|
{t("labels.libraries")}
|
||||||
@@ -246,6 +249,7 @@ const LibraryMenu = ({
|
|||||||
onInsertShape,
|
onInsertShape,
|
||||||
pendingElements,
|
pendingElements,
|
||||||
onAddToLibrary,
|
onAddToLibrary,
|
||||||
|
theme,
|
||||||
setAppState,
|
setAppState,
|
||||||
libraryReturnUrl,
|
libraryReturnUrl,
|
||||||
focusContainer,
|
focusContainer,
|
||||||
@@ -256,6 +260,7 @@ const LibraryMenu = ({
|
|||||||
onClickOutside: (event: MouseEvent) => void;
|
onClickOutside: (event: MouseEvent) => void;
|
||||||
onInsertShape: (elements: LibraryItem) => void;
|
onInsertShape: (elements: LibraryItem) => void;
|
||||||
onAddToLibrary: () => void;
|
onAddToLibrary: () => void;
|
||||||
|
theme: AppState["theme"];
|
||||||
setAppState: React.Component<any, AppState>["setState"];
|
setAppState: React.Component<any, AppState>["setState"];
|
||||||
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
|
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
|
||||||
focusContainer: () => void;
|
focusContainer: () => void;
|
||||||
@@ -345,6 +350,7 @@ const LibraryMenu = ({
|
|||||||
libraryReturnUrl={libraryReturnUrl}
|
libraryReturnUrl={libraryReturnUrl}
|
||||||
focusContainer={focusContainer}
|
focusContainer={focusContainer}
|
||||||
library={library}
|
library={library}
|
||||||
|
theme={theme}
|
||||||
id={id}
|
id={id}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -400,13 +406,11 @@ const LayerUI = ({
|
|||||||
|
|
||||||
const createExporter = (type: ExportType): ExportCB => async (
|
const createExporter = (type: ExportType): ExportCB => async (
|
||||||
exportedElements,
|
exportedElements,
|
||||||
scale,
|
|
||||||
) => {
|
) => {
|
||||||
await exportCanvas(type, exportedElements, appState, {
|
await exportCanvas(type, exportedElements, appState, {
|
||||||
exportBackground: appState.exportBackground,
|
exportBackground: appState.exportBackground,
|
||||||
name: appState.name,
|
name: appState.name,
|
||||||
viewBackgroundColor: appState.viewBackgroundColor,
|
viewBackgroundColor: appState.viewBackgroundColor,
|
||||||
scale,
|
|
||||||
})
|
})
|
||||||
.catch(muteFSAbortError)
|
.catch(muteFSAbortError)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@@ -484,6 +488,9 @@ const LayerUI = ({
|
|||||||
setAppState={setAppState}
|
setAppState={setAppState}
|
||||||
showThemeBtn={showThemeBtn}
|
showThemeBtn={showThemeBtn}
|
||||||
/>
|
/>
|
||||||
|
{appState.fileHandle && (
|
||||||
|
<>{actionManager.renderAction("saveToActiveFile")}</>
|
||||||
|
)}
|
||||||
</Stack.Col>
|
</Stack.Col>
|
||||||
</Island>
|
</Island>
|
||||||
</Section>
|
</Section>
|
||||||
@@ -502,7 +509,8 @@ const LayerUI = ({
|
|||||||
style={{
|
style={{
|
||||||
// we want to make sure this doesn't overflow so substracting 200
|
// we want to make sure this doesn't overflow so substracting 200
|
||||||
// which is approximately height of zoom footer and top left menu items with some buffer
|
// which is approximately height of zoom footer and top left menu items with some buffer
|
||||||
maxHeight: `${appState.height - 200}px`,
|
// if active file name is displayed, subtracting 248 to account for its height
|
||||||
|
maxHeight: `${appState.height - (appState.fileHandle ? 248 : 200)}px`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectedShapeActions
|
<SelectedShapeActions
|
||||||
@@ -539,6 +547,7 @@ const LayerUI = ({
|
|||||||
libraryReturnUrl={libraryReturnUrl}
|
libraryReturnUrl={libraryReturnUrl}
|
||||||
focusContainer={focusContainer}
|
focusContainer={focusContainer}
|
||||||
library={library}
|
library={library}
|
||||||
|
theme={appState.theme}
|
||||||
id={id}
|
id={id}
|
||||||
/>
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
@@ -566,6 +575,12 @@ const LayerUI = ({
|
|||||||
{(heading) => (
|
{(heading) => (
|
||||||
<Stack.Col gap={4} align="start">
|
<Stack.Col gap={4} align="start">
|
||||||
<Stack.Row gap={1}>
|
<Stack.Row gap={1}>
|
||||||
|
<LockButton
|
||||||
|
zenModeEnabled={zenModeEnabled}
|
||||||
|
checked={appState.elementLocked}
|
||||||
|
onChange={onLockToggle}
|
||||||
|
title={t("toolBar.lock")}
|
||||||
|
/>
|
||||||
<Island
|
<Island
|
||||||
padding={1}
|
padding={1}
|
||||||
className={clsx({ "zen-mode": zenModeEnabled })}
|
className={clsx({ "zen-mode": zenModeEnabled })}
|
||||||
@@ -577,15 +592,12 @@ const LayerUI = ({
|
|||||||
canvas={canvas}
|
canvas={canvas}
|
||||||
elementType={appState.elementType}
|
elementType={appState.elementType}
|
||||||
setAppState={setAppState}
|
setAppState={setAppState}
|
||||||
isLibraryOpen={appState.isLibraryOpen}
|
|
||||||
/>
|
/>
|
||||||
</Stack.Row>
|
</Stack.Row>
|
||||||
</Island>
|
</Island>
|
||||||
<LockIcon
|
<LibraryButton
|
||||||
zenModeEnabled={zenModeEnabled}
|
appState={appState}
|
||||||
checked={appState.elementLocked}
|
setAppState={setAppState}
|
||||||
onChange={onLockToggle}
|
|
||||||
title={t("toolBar.lock")}
|
|
||||||
/>
|
/>
|
||||||
</Stack.Row>
|
</Stack.Row>
|
||||||
{libraryMenu}
|
{libraryMenu}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
|
import { t } from "../i18n";
|
||||||
|
import { AppState } from "../types";
|
||||||
|
import { capitalizeString } from "../utils";
|
||||||
|
|
||||||
|
const LIBRARY_ICON = (
|
||||||
|
<svg viewBox="0 0 576 512">
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M542.22 32.05c-54.8 3.11-163.72 14.43-230.96 55.59-4.64 2.84-7.27 7.89-7.27 13.17v363.87c0 11.55 12.63 18.85 23.28 13.49 69.18-34.82 169.23-44.32 218.7-46.92 16.89-.89 30.02-14.43 30.02-30.66V62.75c.01-17.71-15.35-31.74-33.77-30.7zM264.73 87.64C197.5 46.48 88.58 35.17 33.78 32.05 15.36 31.01 0 45.04 0 62.75V400.6c0 16.24 13.13 29.78 30.02 30.66 49.49 2.6 149.59 12.11 218.77 46.95 10.62 5.35 23.21-1.94 23.21-13.46V100.63c0-5.29-2.62-10.14-7.27-12.99z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const LibraryButton: React.FC<{
|
||||||
|
appState: AppState;
|
||||||
|
setAppState: React.Component<any, AppState>["setState"];
|
||||||
|
}> = ({ appState, setAppState }) => {
|
||||||
|
return (
|
||||||
|
<label
|
||||||
|
className={clsx(
|
||||||
|
"ToolIcon ToolIcon_type_floating ToolIcon__library zen-mode-visibility",
|
||||||
|
`ToolIcon_size_m`,
|
||||||
|
{
|
||||||
|
"zen-mode-visibility--hidden": appState.zenModeEnabled,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
title={`${capitalizeString(t("toolBar.library"))} — 9`}
|
||||||
|
style={{ marginInlineStart: "var(--space-factor)" }}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
className="ToolIcon_type_checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
name="editor-library"
|
||||||
|
onChange={(event) => {
|
||||||
|
setAppState({ isLibraryOpen: event.target.checked });
|
||||||
|
}}
|
||||||
|
checked={appState.isLibraryOpen}
|
||||||
|
aria-label={capitalizeString(t("toolBar.library"))}
|
||||||
|
aria-keyshortcuts="9"
|
||||||
|
/>
|
||||||
|
<div className="ToolIcon__icon">{LIBRARY_ICON}</div>
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -8,10 +8,8 @@ type LockIconSize = "s" | "m";
|
|||||||
type LockIconProps = {
|
type LockIconProps = {
|
||||||
title?: string;
|
title?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
id?: string;
|
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
onChange?(): void;
|
onChange?(): void;
|
||||||
size?: LockIconSize;
|
|
||||||
zenModeEnabled?: boolean;
|
zenModeEnabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,12 +39,12 @@ const ICONS = {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LockIcon = (props: LockIconProps) => {
|
export const LockButton = (props: LockIconProps) => {
|
||||||
return (
|
return (
|
||||||
<label
|
<label
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"ToolIcon ToolIcon__lock ToolIcon_type_floating zen-mode-visibility",
|
"ToolIcon ToolIcon__lock ToolIcon_type_floating zen-mode-visibility",
|
||||||
`ToolIcon_size_${props.size || DEFAULT_SIZE}`,
|
`ToolIcon_size_${DEFAULT_SIZE}`,
|
||||||
{
|
{
|
||||||
"zen-mode-visibility--hidden": props.zenModeEnabled,
|
"zen-mode-visibility--hidden": props.zenModeEnabled,
|
||||||
},
|
},
|
||||||
@@ -57,7 +55,6 @@ export const LockIcon = (props: LockIconProps) => {
|
|||||||
className="ToolIcon_type_checkbox"
|
className="ToolIcon_type_checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name={props.name}
|
name={props.name}
|
||||||
id={props.id}
|
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
checked={props.checked}
|
checked={props.checked}
|
||||||
aria-label={props.title}
|
aria-label={props.title}
|
||||||
@@ -13,9 +13,10 @@ import { SelectedShapeActions, ShapesSwitcher } from "./Actions";
|
|||||||
import { Section } from "./Section";
|
import { Section } from "./Section";
|
||||||
import CollabButton from "./CollabButton";
|
import CollabButton from "./CollabButton";
|
||||||
import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars";
|
import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars";
|
||||||
import { LockIcon } from "./LockIcon";
|
import { LockButton } from "./LockButton";
|
||||||
import { UserList } from "./UserList";
|
import { UserList } from "./UserList";
|
||||||
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
|
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
|
||||||
|
import { LibraryButton } from "./LibraryButton";
|
||||||
|
|
||||||
type MobileMenuProps = {
|
type MobileMenuProps = {
|
||||||
appState: AppState;
|
appState: AppState;
|
||||||
@@ -64,15 +65,15 @@ export const MobileMenu = ({
|
|||||||
canvas={canvas}
|
canvas={canvas}
|
||||||
elementType={appState.elementType}
|
elementType={appState.elementType}
|
||||||
setAppState={setAppState}
|
setAppState={setAppState}
|
||||||
isLibraryOpen={appState.isLibraryOpen}
|
|
||||||
/>
|
/>
|
||||||
</Stack.Row>
|
</Stack.Row>
|
||||||
</Island>
|
</Island>
|
||||||
<LockIcon
|
<LockButton
|
||||||
checked={appState.elementLocked}
|
checked={appState.elementLocked}
|
||||||
onChange={onLockToggle}
|
onChange={onLockToggle}
|
||||||
title={t("toolBar.lock")}
|
title={t("toolBar.lock")}
|
||||||
/>
|
/>
|
||||||
|
<LibraryButton appState={appState} setAppState={setAppState} />
|
||||||
</Stack.Row>
|
</Stack.Row>
|
||||||
{libraryMenu}
|
{libraryMenu}
|
||||||
</Stack.Col>
|
</Stack.Col>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const useBodyRoot = (theme: AppState["theme"]) => {
|
|||||||
const isMobileRef = useRef(isMobile);
|
const isMobileRef = useRef(isMobile);
|
||||||
isMobileRef.current = isMobile;
|
isMobileRef.current = isMobile;
|
||||||
|
|
||||||
const excalidrawContainer = useExcalidrawContainer();
|
const { container: excalidrawContainer } = useExcalidrawContainer();
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (div) {
|
if (div) {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import "./TextInput.scss";
|
import "./TextInput.scss";
|
||||||
|
|
||||||
import React, { Component } from "react";
|
import React, { useState } from "react";
|
||||||
import { focusNearestParent } from "../utils";
|
import { focusNearestParent } from "../utils";
|
||||||
|
|
||||||
import "./ProjectName.scss";
|
import "./ProjectName.scss";
|
||||||
|
import { useExcalidrawContainer } from "./App";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
value: string;
|
value: string;
|
||||||
@@ -12,22 +13,19 @@ type Props = {
|
|||||||
isNameEditable: boolean;
|
isNameEditable: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
export const ProjectName = (props: Props) => {
|
||||||
fileName: string;
|
const { id } = useExcalidrawContainer();
|
||||||
};
|
const [fileName, setFileName] = useState<string>(props.value);
|
||||||
export class ProjectName extends Component<Props, State> {
|
|
||||||
state = {
|
const handleBlur = (event: any) => {
|
||||||
fileName: this.props.value,
|
|
||||||
};
|
|
||||||
private handleBlur = (event: any) => {
|
|
||||||
focusNearestParent(event.target);
|
focusNearestParent(event.target);
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
if (value !== this.props.value) {
|
if (value !== props.value) {
|
||||||
this.props.onChange(value);
|
props.onChange(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (event.nativeEvent.isComposing || event.keyCode === 229) {
|
if (event.nativeEvent.isComposing || event.keyCode === 229) {
|
||||||
@@ -37,29 +35,25 @@ export class ProjectName extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render() {
|
return (
|
||||||
return (
|
<div className="ProjectName">
|
||||||
<div className="ProjectName">
|
<label className="ProjectName-label" htmlFor="filename">
|
||||||
<label className="ProjectName-label" htmlFor="filename">
|
{`${props.label}${props.isNameEditable ? "" : ":"}`}
|
||||||
{`${this.props.label}${this.props.isNameEditable ? "" : ":"}`}
|
</label>
|
||||||
</label>
|
{props.isNameEditable ? (
|
||||||
{this.props.isNameEditable ? (
|
<input
|
||||||
<input
|
className="TextInput"
|
||||||
className="TextInput"
|
onBlur={handleBlur}
|
||||||
onBlur={this.handleBlur}
|
onKeyDown={handleKeyDown}
|
||||||
onKeyDown={this.handleKeyDown}
|
id={`${id}-filename`}
|
||||||
id="filename"
|
value={fileName}
|
||||||
value={this.state.fileName}
|
onChange={(event) => setFileName(event.target.value)}
|
||||||
onChange={(event) =>
|
/>
|
||||||
this.setState({ fileName: event.target.value })
|
) : (
|
||||||
}
|
<span className="TextInput TextInput--readonly" id={`${id}-filename`}>
|
||||||
/>
|
{props.value}
|
||||||
) : (
|
</span>
|
||||||
<span className="TextInput TextInput--readonly" id="filename">
|
)}
|
||||||
{this.props.value}
|
</div>
|
||||||
</span>
|
);
|
||||||
)}
|
};
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
|
import { useExcalidrawContainer } from "./App";
|
||||||
|
|
||||||
interface SectionProps extends React.HTMLProps<HTMLElement> {
|
interface SectionProps extends React.HTMLProps<HTMLElement> {
|
||||||
heading: string;
|
heading: string;
|
||||||
@@ -7,13 +8,14 @@ interface SectionProps extends React.HTMLProps<HTMLElement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Section = ({ heading, children, ...props }: SectionProps) => {
|
export const Section = ({ heading, children, ...props }: SectionProps) => {
|
||||||
|
const { id } = useExcalidrawContainer();
|
||||||
const header = (
|
const header = (
|
||||||
<h2 className="visually-hidden" id={`${heading}-title`}>
|
<h2 className="visually-hidden" id={`${id}-${heading}-title`}>
|
||||||
{t(`headings.${heading}`)}
|
{t(`headings.${heading}`)}
|
||||||
</h2>
|
</h2>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<section {...props} aria-labelledby={`${heading}-title`}>
|
<section {...props} aria-labelledby={`${id}-${heading}-title`}>
|
||||||
{typeof children === "function" ? (
|
{typeof children === "function" ? (
|
||||||
children(header)
|
children(header)
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import "./ToolIcon.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import { useExcalidrawContainer } from "./App";
|
||||||
|
|
||||||
type ToolIconSize = "s" | "m";
|
type ToolIconSize = "s" | "m";
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ type ToolButtonProps =
|
|||||||
const DEFAULT_SIZE: ToolIconSize = "m";
|
const DEFAULT_SIZE: ToolIconSize = "m";
|
||||||
|
|
||||||
export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => {
|
export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => {
|
||||||
|
const { id: excalId } = useExcalidrawContainer();
|
||||||
const innerRef = React.useRef(null);
|
const innerRef = React.useRef(null);
|
||||||
React.useImperativeHandle(ref, () => innerRef.current);
|
React.useImperativeHandle(ref, () => innerRef.current);
|
||||||
const sizeCn = `ToolIcon_size_${props.size || DEFAULT_SIZE}`;
|
const sizeCn = `ToolIcon_size_${props.size || DEFAULT_SIZE}`;
|
||||||
@@ -98,7 +100,7 @@ export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => {
|
|||||||
aria-label={props["aria-label"]}
|
aria-label={props["aria-label"]}
|
||||||
aria-keyshortcuts={props["aria-keyshortcuts"]}
|
aria-keyshortcuts={props["aria-keyshortcuts"]}
|
||||||
data-testid={props["data-testid"]}
|
data-testid={props["data-testid"]}
|
||||||
id={props.id}
|
id={`${excalId}-${props.id}`}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
checked={props.checked}
|
checked={props.checked}
|
||||||
ref={innerRef}
|
ref={innerRef}
|
||||||
|
|||||||
@@ -8,10 +8,18 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
font-family: Cascadia;
|
font-family: Cascadia;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: var(--button-gray-1);
|
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
border-radius: var(--space-factor);
|
border-radius: var(--space-factor);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
background-color: var(--button-gray-1);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--button-gray-2);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: var(--button-gray-3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ToolIcon--plain {
|
.ToolIcon--plain {
|
||||||
@@ -66,14 +74,6 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--button-gray-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: var(--button-gray-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: 0 0 0 2px var(--focus-highlight-color);
|
box-shadow: 0 0 0 2px var(--focus-highlight-color);
|
||||||
}
|
}
|
||||||
@@ -86,6 +86,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--button-gray-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: var(--button-gray-3);
|
||||||
|
}
|
||||||
|
|
||||||
&--show {
|
&--show {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
@@ -103,6 +111,9 @@
|
|||||||
|
|
||||||
&:not(.ToolIcon_toggle_opaque):checked + .ToolIcon__icon {
|
&:not(.ToolIcon_toggle_opaque):checked + .ToolIcon__icon {
|
||||||
background-color: var(--button-gray-2);
|
background-color: var(--button-gray-2);
|
||||||
|
&:active {
|
||||||
|
background-color: var(--button-gray-3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus + .ToolIcon__icon {
|
&:focus + .ToolIcon__icon {
|
||||||
@@ -130,12 +141,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ToolIcon__icon {
|
.ToolIcon__icon {
|
||||||
|
background-color: var(--button-gray-1);
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--button-gray-2);
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: var(--button-gray-3);
|
||||||
|
}
|
||||||
|
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
height: 2em;
|
height: 2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ToolIcon.ToolIcon__lock {
|
.ToolIcon.ToolIcon__lock {
|
||||||
|
margin-inline-end: var(--space-factor);
|
||||||
&.ToolIcon_type_floating {
|
&.ToolIcon_type_floating {
|
||||||
margin-left: 0.1rem;
|
margin-left: 0.1rem;
|
||||||
}
|
}
|
||||||
@@ -166,10 +186,9 @@
|
|||||||
// move the lock button out of the way on small viewports
|
// move the lock button out of the way on small viewports
|
||||||
// it begins to collide with the GitHub icon before we switch to mobile mode
|
// it begins to collide with the GitHub icon before we switch to mobile mode
|
||||||
@media (max-width: 760px) {
|
@media (max-width: 760px) {
|
||||||
.ToolIcon.ToolIcon__lock {
|
.ToolIcon.ToolIcon_type_floating {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 60px;
|
|
||||||
right: -8px;
|
right: -8px;
|
||||||
|
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
@@ -194,6 +213,14 @@
|
|||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.ToolIcon.ToolIcon__library {
|
||||||
|
top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ToolIcon.ToolIcon__lock {
|
||||||
|
margin-inline-end: 0;
|
||||||
|
top: 60px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.unlocked-icon {
|
.unlocked-icon {
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ type Opts = {
|
|||||||
mirror?: true;
|
mirror?: true;
|
||||||
} & React.SVGProps<SVGSVGElement>;
|
} & React.SVGProps<SVGSVGElement>;
|
||||||
|
|
||||||
const createIcon = (d: string | React.ReactNode, opts: number | Opts = 512) => {
|
export const createIcon = (
|
||||||
|
d: string | React.ReactNode,
|
||||||
|
opts: number | Opts = 512,
|
||||||
|
) => {
|
||||||
const { width = 512, height = width, mirror, style } =
|
const { width = 512, height = width, mirror, style } =
|
||||||
typeof opts === "number" ? ({ width: opts } as Opts) : opts;
|
typeof opts === "number" ? ({ width: opts } as Opts) : opts;
|
||||||
return (
|
return (
|
||||||
@@ -474,6 +477,11 @@ export const shield = createIcon(
|
|||||||
{ width: 24 },
|
{ width: 24 },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const file = createIcon(
|
||||||
|
"M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM332.1 128H256V51.9l76.1 76.1zM48 464V48h160v104c0 13.3 10.7 24 24 24h104v288H48zm32-48h224V288l-23.5-23.5c-4.7-4.7-12.3-4.7-17 0L176 352l-39.5-39.5c-4.7-4.7-12.3-4.7-17 0L80 352v64zm48-240c-26.5 0-48 21.5-48 48s21.5 48 48 48 48-21.5 48-48-21.5-48-48-48z",
|
||||||
|
{ width: 384, height: 512 },
|
||||||
|
);
|
||||||
|
|
||||||
export const GroupIcon = React.memo(({ theme }: { theme: "light" | "dark" }) =>
|
export const GroupIcon = React.memo(({ theme }: { theme: "light" | "dark" }) =>
|
||||||
createIcon(
|
createIcon(
|
||||||
<>
|
<>
|
||||||
|
|||||||
+13
-6
@@ -1,6 +1,6 @@
|
|||||||
import { FontFamily } from "./element/types";
|
|
||||||
import cssVariables from "./css/variables.module.scss";
|
import cssVariables from "./css/variables.module.scss";
|
||||||
import { AppProps } from "./types";
|
import { AppProps } from "./types";
|
||||||
|
import { FontFamilyValues } from "./element/types";
|
||||||
|
|
||||||
export const APP_NAME = "Excalidraw";
|
export const APP_NAME = "Excalidraw";
|
||||||
|
|
||||||
@@ -63,15 +63,15 @@ export const CLASSES = {
|
|||||||
|
|
||||||
// 1-based in case we ever do `if(element.fontFamily)`
|
// 1-based in case we ever do `if(element.fontFamily)`
|
||||||
export const FONT_FAMILY = {
|
export const FONT_FAMILY = {
|
||||||
1: "Virgil",
|
Virgil: 1,
|
||||||
2: "Helvetica",
|
Helvetica: 2,
|
||||||
3: "Cascadia",
|
Cascadia: 3,
|
||||||
} as const;
|
};
|
||||||
|
|
||||||
export const WINDOWS_EMOJI_FALLBACK_FONT = "Segoe UI Emoji";
|
export const WINDOWS_EMOJI_FALLBACK_FONT = "Segoe UI Emoji";
|
||||||
|
|
||||||
export const DEFAULT_FONT_SIZE = 20;
|
export const DEFAULT_FONT_SIZE = 20;
|
||||||
export const DEFAULT_FONT_FAMILY: FontFamily = 1;
|
export const DEFAULT_FONT_FAMILY: FontFamilyValues = FONT_FAMILY.Virgil;
|
||||||
export const DEFAULT_TEXT_ALIGN = "left";
|
export const DEFAULT_TEXT_ALIGN = "left";
|
||||||
export const DEFAULT_VERTICAL_ALIGN = "top";
|
export const DEFAULT_VERTICAL_ALIGN = "top";
|
||||||
export const DEFAULT_VERSION = "{version}";
|
export const DEFAULT_VERSION = "{version}";
|
||||||
@@ -97,6 +97,10 @@ export const STORAGE_KEYS = {
|
|||||||
LOCAL_STORAGE_LIBRARY: "excalidraw-library",
|
LOCAL_STORAGE_LIBRARY: "excalidraw-library",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const IDB_KEYS = {
|
||||||
|
fileHandle: "fileHandle",
|
||||||
|
} as const;
|
||||||
|
|
||||||
// time in milliseconds
|
// time in milliseconds
|
||||||
export const TAP_TWICE_TIMEOUT = 300;
|
export const TAP_TWICE_TIMEOUT = 300;
|
||||||
export const TOUCH_CTX_MENU_TIMEOUT = 500;
|
export const TOUCH_CTX_MENU_TIMEOUT = 500;
|
||||||
@@ -144,3 +148,6 @@ export const MQ_MAX_WIDTH_LANDSCAPE = 1000;
|
|||||||
export const MQ_MAX_HEIGHT_LANDSCAPE = 500;
|
export const MQ_MAX_HEIGHT_LANDSCAPE = 500;
|
||||||
|
|
||||||
export const MAX_DECIMALS_FOR_SVG_EXPORT = 2;
|
export const MAX_DECIMALS_FOR_SVG_EXPORT = 2;
|
||||||
|
|
||||||
|
export const EXPORT_SCALES = [1, 2, 3];
|
||||||
|
export const DEFAULT_EXPORT_PADDING = 10; // px
|
||||||
|
|||||||
+3
-2
@@ -51,11 +51,12 @@
|
|||||||
image-rendering: -moz-crisp-edges; // FF
|
image-rendering: -moz-crisp-edges; // FF
|
||||||
|
|
||||||
z-index: var(--zIndex-canvas);
|
z-index: var(--zIndex-canvas);
|
||||||
}
|
|
||||||
|
|
||||||
#canvas {
|
|
||||||
// Remove the main canvas from document flow to avoid resizeObserver
|
// Remove the main canvas from document flow to avoid resizeObserver
|
||||||
// feedback loop (see https://github.com/excalidraw/excalidraw/pull/3379)
|
// feedback loop (see https://github.com/excalidraw/excalidraw/pull/3379)
|
||||||
|
}
|
||||||
|
|
||||||
|
&__canvas {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -3,6 +3,7 @@ import {
|
|||||||
copyBlobToClipboardAsPng,
|
copyBlobToClipboardAsPng,
|
||||||
copyTextToSystemClipboard,
|
copyTextToSystemClipboard,
|
||||||
} from "../clipboard";
|
} from "../clipboard";
|
||||||
|
import { DEFAULT_EXPORT_PADDING } from "../constants";
|
||||||
import { NonDeletedExcalidrawElement } from "../element/types";
|
import { NonDeletedExcalidrawElement } from "../element/types";
|
||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
import { exportToCanvas, exportToSvg } from "../scene/export";
|
import { exportToCanvas, exportToSvg } from "../scene/export";
|
||||||
@@ -20,16 +21,14 @@ export const exportCanvas = async (
|
|||||||
appState: AppState,
|
appState: AppState,
|
||||||
{
|
{
|
||||||
exportBackground,
|
exportBackground,
|
||||||
exportPadding = 10,
|
exportPadding = DEFAULT_EXPORT_PADDING,
|
||||||
viewBackgroundColor,
|
viewBackgroundColor,
|
||||||
name,
|
name,
|
||||||
scale = 1,
|
|
||||||
}: {
|
}: {
|
||||||
exportBackground: boolean;
|
exportBackground: boolean;
|
||||||
exportPadding?: number;
|
exportPadding?: number;
|
||||||
viewBackgroundColor: string;
|
viewBackgroundColor: string;
|
||||||
name: string;
|
name: string;
|
||||||
scale?: number;
|
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
if (elements.length === 0) {
|
if (elements.length === 0) {
|
||||||
@@ -41,7 +40,7 @@ export const exportCanvas = async (
|
|||||||
exportWithDarkMode: appState.exportWithDarkMode,
|
exportWithDarkMode: appState.exportWithDarkMode,
|
||||||
viewBackgroundColor,
|
viewBackgroundColor,
|
||||||
exportPadding,
|
exportPadding,
|
||||||
scale,
|
exportScale: appState.exportScale,
|
||||||
metadata:
|
metadata:
|
||||||
appState.exportEmbedScene && type === "svg"
|
appState.exportEmbedScene && type === "svg"
|
||||||
? await (
|
? await (
|
||||||
@@ -67,7 +66,6 @@ export const exportCanvas = async (
|
|||||||
exportBackground,
|
exportBackground,
|
||||||
viewBackgroundColor,
|
viewBackgroundColor,
|
||||||
exportPadding,
|
exportPadding,
|
||||||
scale,
|
|
||||||
});
|
});
|
||||||
tempCanvas.style.display = "none";
|
tempCanvas.style.display = "none";
|
||||||
document.body.appendChild(tempCanvas);
|
document.body.appendChild(tempCanvas);
|
||||||
|
|||||||
+28
-1
@@ -1,4 +1,4 @@
|
|||||||
import { fileOpen, fileSave } from "browser-fs-access";
|
import { fileOpen, fileSave, FileSystemHandle } from "browser-fs-access";
|
||||||
import { cleanAppStateForExport } from "../appState";
|
import { cleanAppStateForExport } from "../appState";
|
||||||
import { EXPORT_DATA_TYPES, EXPORT_SOURCE, MIME_TYPES } from "../constants";
|
import { EXPORT_DATA_TYPES, EXPORT_SOURCE, MIME_TYPES } from "../constants";
|
||||||
import { clearElementsForExport } from "../element";
|
import { clearElementsForExport } from "../element";
|
||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
ExportedLibraryData,
|
ExportedLibraryData,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import Library from "./library";
|
import Library from "./library";
|
||||||
|
import { AbortError } from "../errors";
|
||||||
|
|
||||||
export const serializeAsJSON = (
|
export const serializeAsJSON = (
|
||||||
elements: readonly ExcalidrawElement[],
|
elements: readonly ExcalidrawElement[],
|
||||||
@@ -28,6 +29,26 @@ export const serializeAsJSON = (
|
|||||||
return JSON.stringify(data, null, 2);
|
return JSON.stringify(data, null, 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// adapted from https://web.dev/file-system-access
|
||||||
|
const verifyPermission = async (fileHandle: FileSystemHandle) => {
|
||||||
|
try {
|
||||||
|
const options = { mode: "readwrite" } as any;
|
||||||
|
// Check if permission was already granted. If so, return true.
|
||||||
|
if ((await fileHandle.queryPermission(options)) === "granted") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Request permission. If the user grants permission, return true.
|
||||||
|
if ((await fileHandle.requestPermission(options)) === "granted") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// The user didn't grant permission, so return false.
|
||||||
|
return false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const saveAsJSON = async (
|
export const saveAsJSON = async (
|
||||||
elements: readonly ExcalidrawElement[],
|
elements: readonly ExcalidrawElement[],
|
||||||
appState: AppState,
|
appState: AppState,
|
||||||
@@ -37,6 +58,12 @@ export const saveAsJSON = async (
|
|||||||
type: MIME_TYPES.excalidraw,
|
type: MIME_TYPES.excalidraw,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (appState.fileHandle) {
|
||||||
|
if (!(await verifyPermission(appState.fileHandle))) {
|
||||||
|
throw new AbortError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const fileHandle = await fileSave(
|
const fileHandle = await fileSave(
|
||||||
blob,
|
blob,
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ import { loadLibraryFromBlob } from "./blob";
|
|||||||
import { LibraryItems, LibraryItem } from "../types";
|
import { LibraryItems, LibraryItem } from "../types";
|
||||||
import { restoreElements } from "./restore";
|
import { restoreElements } from "./restore";
|
||||||
import { getNonDeletedElements } from "../element";
|
import { getNonDeletedElements } from "../element";
|
||||||
import App from "../components/App";
|
import type App from "../components/App";
|
||||||
|
|
||||||
class Library {
|
class Library {
|
||||||
private libraryCache: LibraryItems | null = null;
|
private libraryCache: LibraryItems | null = null;
|
||||||
|
|||||||
+8
-8
@@ -1,18 +1,18 @@
|
|||||||
import {
|
import {
|
||||||
ExcalidrawElement,
|
ExcalidrawElement,
|
||||||
FontFamily,
|
|
||||||
ExcalidrawSelectionElement,
|
ExcalidrawSelectionElement,
|
||||||
|
FontFamilyValues,
|
||||||
} from "../element/types";
|
} from "../element/types";
|
||||||
import { AppState, NormalizedZoomValue } from "../types";
|
import { AppState, NormalizedZoomValue } from "../types";
|
||||||
import { ImportedDataState } from "./types";
|
import { ImportedDataState } from "./types";
|
||||||
import { isInvisiblySmallElement, getNormalizedDimensions } from "../element";
|
import { getNormalizedDimensions, isInvisiblySmallElement } from "../element";
|
||||||
import { isLinearElementType } from "../element/typeChecks";
|
import { isLinearElementType } from "../element/typeChecks";
|
||||||
import { randomId } from "../random";
|
import { randomId } from "../random";
|
||||||
import {
|
import {
|
||||||
FONT_FAMILY,
|
|
||||||
DEFAULT_FONT_FAMILY,
|
DEFAULT_FONT_FAMILY,
|
||||||
DEFAULT_TEXT_ALIGN,
|
DEFAULT_TEXT_ALIGN,
|
||||||
DEFAULT_VERTICAL_ALIGN,
|
DEFAULT_VERTICAL_ALIGN,
|
||||||
|
FONT_FAMILY,
|
||||||
} from "../constants";
|
} from "../constants";
|
||||||
import { getDefaultAppState } from "../appState";
|
import { getDefaultAppState } from "../appState";
|
||||||
import { LinearElementEditor } from "../element/linearElementEditor";
|
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||||
@@ -41,11 +41,11 @@ export type RestoredDataState = {
|
|||||||
appState: RestoredAppState;
|
appState: RestoredAppState;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFontFamilyByName = (fontFamilyName: string): FontFamily => {
|
const getFontFamilyByName = (fontFamilyName: string): FontFamilyValues => {
|
||||||
for (const [id, fontFamilyString] of Object.entries(FONT_FAMILY)) {
|
if (Object.keys(FONT_FAMILY).includes(fontFamilyName)) {
|
||||||
if (fontFamilyString.includes(fontFamilyName)) {
|
return FONT_FAMILY[
|
||||||
return parseInt(id) as FontFamily;
|
fontFamilyName as keyof typeof FONT_FAMILY
|
||||||
}
|
] as FontFamilyValues;
|
||||||
}
|
}
|
||||||
return DEFAULT_FONT_FAMILY;
|
return DEFAULT_FONT_FAMILY;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { mutateElement } from "./mutateElement";
|
|||||||
import { getPerfectElementSize } from "./sizeHelpers";
|
import { getPerfectElementSize } from "./sizeHelpers";
|
||||||
import Scene from "../scene/Scene";
|
import Scene from "../scene/Scene";
|
||||||
import { NonDeletedExcalidrawElement } from "./types";
|
import { NonDeletedExcalidrawElement } from "./types";
|
||||||
import { PointerDownState } from "../components/App";
|
import { PointerDownState } from "../types";
|
||||||
|
|
||||||
export const dragSelectedElements = (
|
export const dragSelectedElements = (
|
||||||
pointerDownState: PointerDownState,
|
pointerDownState: PointerDownState,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { duplicateElement } from "./newElement";
|
import { duplicateElement } from "./newElement";
|
||||||
import { mutateElement } from "./mutateElement";
|
import { mutateElement } from "./mutateElement";
|
||||||
import { API } from "../tests/helpers/api";
|
import { API } from "../tests/helpers/api";
|
||||||
|
import { FONT_FAMILY } from "../constants";
|
||||||
|
|
||||||
const isPrimitive = (val: any) => {
|
const isPrimitive = (val: any) => {
|
||||||
const type = typeof val;
|
const type = typeof val;
|
||||||
@@ -79,7 +80,7 @@ it("clones text element", () => {
|
|||||||
opacity: 100,
|
opacity: 100,
|
||||||
text: "hello",
|
text: "hello",
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontFamily: 1,
|
fontFamily: FONT_FAMILY.Virgil,
|
||||||
textAlign: "left",
|
textAlign: "left",
|
||||||
verticalAlign: "top",
|
verticalAlign: "top",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import {
|
|||||||
ExcalidrawGenericElement,
|
ExcalidrawGenericElement,
|
||||||
NonDeleted,
|
NonDeleted,
|
||||||
TextAlign,
|
TextAlign,
|
||||||
FontFamily,
|
|
||||||
GroupId,
|
GroupId,
|
||||||
VerticalAlign,
|
VerticalAlign,
|
||||||
Arrowhead,
|
Arrowhead,
|
||||||
ExcalidrawFreeDrawElement,
|
ExcalidrawFreeDrawElement,
|
||||||
|
FontFamilyValues,
|
||||||
} from "../element/types";
|
} from "../element/types";
|
||||||
import { measureText, getFontString } from "../utils";
|
import { measureText, getFontString } from "../utils";
|
||||||
import { randomInteger, randomId } from "../random";
|
import { randomInteger, randomId } from "../random";
|
||||||
@@ -109,7 +109,7 @@ export const newTextElement = (
|
|||||||
opts: {
|
opts: {
|
||||||
text: string;
|
text: string;
|
||||||
fontSize: number;
|
fontSize: number;
|
||||||
fontFamily: FontFamily;
|
fontFamily: FontFamilyValues;
|
||||||
textAlign: TextAlign;
|
textAlign: TextAlign;
|
||||||
verticalAlign: VerticalAlign;
|
verticalAlign: VerticalAlign;
|
||||||
} & ElementConstructorOpts,
|
} & ElementConstructorOpts,
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ import {
|
|||||||
MaybeTransformHandleType,
|
MaybeTransformHandleType,
|
||||||
TransformHandleDirection,
|
TransformHandleDirection,
|
||||||
} from "./transformHandles";
|
} from "./transformHandles";
|
||||||
import { PointerDownState } from "../components/App";
|
import { Point, PointerDownState } from "../types";
|
||||||
import { Point } from "../types";
|
|
||||||
|
|
||||||
export const normalizeAngle = (angle: number): number => {
|
export const normalizeAngle = (angle: number): number => {
|
||||||
if (angle >= 2 * Math.PI) {
|
if (angle >= 2 * Math.PI) {
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import { FONT_FAMILY } from "../constants";
|
|||||||
|
|
||||||
export type ChartType = "bar" | "line";
|
export type ChartType = "bar" | "line";
|
||||||
export type FillStyle = "hachure" | "cross-hatch" | "solid";
|
export type FillStyle = "hachure" | "cross-hatch" | "solid";
|
||||||
export type FontFamily = keyof typeof FONT_FAMILY;
|
export type FontFamilyKeys = keyof typeof FONT_FAMILY;
|
||||||
|
export type FontFamilyValues = typeof FONT_FAMILY[FontFamilyKeys];
|
||||||
export type FontString = string & { _brand: "fontString" };
|
export type FontString = string & { _brand: "fontString" };
|
||||||
export type GroupId = string;
|
export type GroupId = string;
|
||||||
export type PointerType = "mouse" | "pen" | "touch";
|
export type PointerType = "mouse" | "pen" | "touch";
|
||||||
@@ -91,7 +92,7 @@ export type ExcalidrawTextElement = _ExcalidrawElementBase &
|
|||||||
Readonly<{
|
Readonly<{
|
||||||
type: "text";
|
type: "text";
|
||||||
fontSize: number;
|
fontSize: number;
|
||||||
fontFamily: FontFamily;
|
fontFamily: FontFamilyValues;
|
||||||
text: string;
|
text: string;
|
||||||
baseline: number;
|
baseline: number;
|
||||||
textAlign: TextAlign;
|
textAlign: TextAlign;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
type CANVAS_ERROR_NAMES = "CANVAS_ERROR" | "CANVAS_POSSIBLY_TOO_BIG";
|
type CANVAS_ERROR_NAMES = "CANVAS_ERROR" | "CANVAS_POSSIBLY_TOO_BIG";
|
||||||
|
|
||||||
export class CanvasError extends Error {
|
export class CanvasError extends Error {
|
||||||
constructor(
|
constructor(
|
||||||
message: string = "Couldn't export canvas.",
|
message: string = "Couldn't export canvas.",
|
||||||
@@ -9,3 +10,11 @@ export class CanvasError extends Error {
|
|||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class AbortError extends Error {
|
||||||
|
constructor(message: string = "Request aborted") {
|
||||||
|
super();
|
||||||
|
this.name = "AbortError";
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import throttle from "lodash.throttle";
|
import throttle from "lodash.throttle";
|
||||||
import React, { PureComponent } from "react";
|
import React, { PureComponent } from "react";
|
||||||
import { ExcalidrawImperativeAPI } from "../../components/App";
|
import { ExcalidrawImperativeAPI } from "../../types";
|
||||||
import { ErrorDialog } from "../../components/ErrorDialog";
|
import { ErrorDialog } from "../../components/ErrorDialog";
|
||||||
import { APP_NAME, ENV, EVENT } from "../../constants";
|
import { APP_NAME, ENV, EVENT } from "../../constants";
|
||||||
import { ImportedDataState } from "../../data/types";
|
import { ImportedDataState } from "../../data/types";
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Card } from "../../components/Card";
|
||||||
|
import { ToolButton } from "../../components/ToolButton";
|
||||||
|
import { serializeAsJSON } from "../../data/json";
|
||||||
|
import { getImportedKey, createIV, generateEncryptionKey } from "../data";
|
||||||
|
import { loadFirebaseStorage } from "../data/firebase";
|
||||||
|
import { NonDeletedExcalidrawElement } from "../../element/types";
|
||||||
|
import { AppState } from "../../types";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { t } from "../../i18n";
|
||||||
|
import { excalidrawPlusIcon } from "./icons";
|
||||||
|
|
||||||
|
const encryptData = async (
|
||||||
|
key: string,
|
||||||
|
json: string,
|
||||||
|
): Promise<{ blob: Blob; iv: Uint8Array }> => {
|
||||||
|
const importedKey = await getImportedKey(key, "encrypt");
|
||||||
|
const iv = createIV();
|
||||||
|
const encoded = new TextEncoder().encode(json);
|
||||||
|
const ciphertext = await window.crypto.subtle.encrypt(
|
||||||
|
{
|
||||||
|
name: "AES-GCM",
|
||||||
|
iv,
|
||||||
|
},
|
||||||
|
importedKey,
|
||||||
|
encoded,
|
||||||
|
);
|
||||||
|
|
||||||
|
return { blob: new Blob([new Uint8Array(ciphertext)]), iv };
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportToExcalidrawPlus = async (
|
||||||
|
elements: readonly NonDeletedExcalidrawElement[],
|
||||||
|
appState: AppState,
|
||||||
|
) => {
|
||||||
|
const firebase = await loadFirebaseStorage();
|
||||||
|
|
||||||
|
const id = `${nanoid(12)}`;
|
||||||
|
|
||||||
|
const key = (await generateEncryptionKey())!;
|
||||||
|
const encryptedData = await encryptData(
|
||||||
|
key,
|
||||||
|
serializeAsJSON(elements, appState),
|
||||||
|
);
|
||||||
|
|
||||||
|
const blob = new Blob([encryptedData.iv, encryptedData.blob], {
|
||||||
|
type: "application/octet-stream",
|
||||||
|
});
|
||||||
|
|
||||||
|
await firebase
|
||||||
|
.storage()
|
||||||
|
.ref(`/migrations/scenes/${id}`)
|
||||||
|
.put(blob, {
|
||||||
|
customMetadata: {
|
||||||
|
data: JSON.stringify({ version: 1, name: appState.name }),
|
||||||
|
created: Date.now().toString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
window.open(`https://plus.excalidraw.com/import?excalidraw=${id},${key}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ExportToExcalidrawPlus: React.FC<{
|
||||||
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
|
appState: AppState;
|
||||||
|
onError: (error: Error) => void;
|
||||||
|
}> = ({ elements, appState, onError }) => {
|
||||||
|
return (
|
||||||
|
<Card color="indigo">
|
||||||
|
<div className="Card-icon">{excalidrawPlusIcon}</div>
|
||||||
|
<h2>Excalidraw+</h2>
|
||||||
|
<div className="Card-details">
|
||||||
|
{t("exportDialog.excalidrawplus_description")}
|
||||||
|
</div>
|
||||||
|
<ToolButton
|
||||||
|
className="Card-button"
|
||||||
|
type="button"
|
||||||
|
title={t("exportDialog.excalidrawplus_button")}
|
||||||
|
aria-label={t("exportDialog.excalidrawplus_button")}
|
||||||
|
showAriaLabel={true}
|
||||||
|
onClick={async () => {
|
||||||
|
try {
|
||||||
|
await exportToExcalidrawPlus(elements, appState);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
onError(new Error(t("exportDialog.excalidrawplus_exportError")));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
@@ -5,15 +5,19 @@ import { getSceneVersion } from "../../element";
|
|||||||
import Portal from "../collab/Portal";
|
import Portal from "../collab/Portal";
|
||||||
import { restoreElements } from "../../data/restore";
|
import { restoreElements } from "../../data/restore";
|
||||||
|
|
||||||
|
// private
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
let firebasePromise: Promise<
|
let firebasePromise: Promise<
|
||||||
typeof import("firebase/app").default
|
typeof import("firebase/app").default
|
||||||
> | null = null;
|
> | null = null;
|
||||||
|
let firestorePromise: Promise<any> | null = null;
|
||||||
|
let firebseStoragePromise: Promise<any> | null = null;
|
||||||
|
|
||||||
const loadFirebase = async () => {
|
const _loadFirebase = async () => {
|
||||||
const firebase = (
|
const firebase = (
|
||||||
await import(/* webpackChunkName: "firebase" */ "firebase/app")
|
await import(/* webpackChunkName: "firebase" */ "firebase/app")
|
||||||
).default;
|
).default;
|
||||||
await import(/* webpackChunkName: "firestore" */ "firebase/firestore");
|
|
||||||
|
|
||||||
const firebaseConfig = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG);
|
const firebaseConfig = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG);
|
||||||
firebase.initializeApp(firebaseConfig);
|
firebase.initializeApp(firebaseConfig);
|
||||||
@@ -21,13 +25,37 @@ const loadFirebase = async () => {
|
|||||||
return firebase;
|
return firebase;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFirebase = async (): Promise<
|
const _getFirebase = async (): Promise<
|
||||||
typeof import("firebase/app").default
|
typeof import("firebase/app").default
|
||||||
> => {
|
> => {
|
||||||
if (!firebasePromise) {
|
if (!firebasePromise) {
|
||||||
firebasePromise = loadFirebase();
|
firebasePromise = _loadFirebase();
|
||||||
}
|
}
|
||||||
return await firebasePromise!;
|
return firebasePromise;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const loadFirestore = async () => {
|
||||||
|
const firebase = await _getFirebase();
|
||||||
|
if (!firestorePromise) {
|
||||||
|
firestorePromise = import(
|
||||||
|
/* webpackChunkName: "firestore" */ "firebase/firestore"
|
||||||
|
);
|
||||||
|
await firestorePromise;
|
||||||
|
}
|
||||||
|
return firebase;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const loadFirebaseStorage = async () => {
|
||||||
|
const firebase = await _getFirebase();
|
||||||
|
if (!firebseStoragePromise) {
|
||||||
|
firebseStoragePromise = import(
|
||||||
|
/* webpackChunkName: "storage" */ "firebase/storage"
|
||||||
|
);
|
||||||
|
await firebseStoragePromise;
|
||||||
|
}
|
||||||
|
return firebase;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface FirebaseStoredScene {
|
interface FirebaseStoredScene {
|
||||||
@@ -108,7 +136,7 @@ export const saveToFirebase = async (
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const firebase = await getFirebase();
|
const firebase = await loadFirestore();
|
||||||
const sceneVersion = getSceneVersion(elements);
|
const sceneVersion = getSceneVersion(elements);
|
||||||
const { ciphertext, iv } = await encryptElements(roomKey, elements);
|
const { ciphertext, iv } = await encryptElements(roomKey, elements);
|
||||||
|
|
||||||
@@ -150,7 +178,7 @@ export const loadFromFirebase = async (
|
|||||||
roomKey: string,
|
roomKey: string,
|
||||||
socket: SocketIOClient.Socket | null,
|
socket: SocketIOClient.Socket | null,
|
||||||
): Promise<readonly ExcalidrawElement[] | null> => {
|
): Promise<readonly ExcalidrawElement[] | null> => {
|
||||||
const firebase = await getFirebase();
|
const firebase = await loadFirestore();
|
||||||
const db = firebase.firestore();
|
const db = firebase.firestore();
|
||||||
|
|
||||||
const docRef = db.collection("scenes").doc(roomId);
|
const docRef = db.collection("scenes").doc(roomId);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const generateRandomID = async () => {
|
|||||||
return Array.from(arr, byteToHex).join("");
|
return Array.from(arr, byteToHex).join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateEncryptionKey = async () => {
|
export const generateEncryptionKey = async () => {
|
||||||
const key = await window.crypto.subtle.generateKey(
|
const key = await window.crypto.subtle.generateKey(
|
||||||
{
|
{
|
||||||
name: "AES-GCM",
|
name: "AES-GCM",
|
||||||
@@ -176,7 +176,7 @@ export const getImportedKey = (key: string, usage: KeyUsage) =>
|
|||||||
[usage],
|
[usage],
|
||||||
);
|
);
|
||||||
|
|
||||||
const decryptImported = async (
|
export const decryptImported = async (
|
||||||
iv: ArrayBuffer,
|
iv: ArrayBuffer,
|
||||||
encrypted: ArrayBuffer,
|
encrypted: ArrayBuffer,
|
||||||
privateKey: string,
|
privateKey: string,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import React, {
|
|||||||
} from "react";
|
} from "react";
|
||||||
import { trackEvent } from "../analytics";
|
import { trackEvent } from "../analytics";
|
||||||
import { getDefaultAppState } from "../appState";
|
import { getDefaultAppState } from "../appState";
|
||||||
import { ExcalidrawImperativeAPI } from "../components/App";
|
|
||||||
import { ErrorDialog } from "../components/ErrorDialog";
|
import { ErrorDialog } from "../components/ErrorDialog";
|
||||||
import { TopErrorBoundary } from "../components/TopErrorBoundary";
|
import { TopErrorBoundary } from "../components/TopErrorBoundary";
|
||||||
import {
|
import {
|
||||||
@@ -31,7 +30,7 @@ import Excalidraw, {
|
|||||||
defaultLang,
|
defaultLang,
|
||||||
languages,
|
languages,
|
||||||
} from "../packages/excalidraw/index";
|
} from "../packages/excalidraw/index";
|
||||||
import { AppState, LibraryItems } from "../types";
|
import { AppState, LibraryItems, ExcalidrawImperativeAPI } from "../types";
|
||||||
import {
|
import {
|
||||||
debounce,
|
debounce,
|
||||||
getVersion,
|
getVersion,
|
||||||
@@ -56,6 +55,7 @@ import { Tooltip } from "../components/Tooltip";
|
|||||||
import { shield } from "../components/icons";
|
import { shield } from "../components/icons";
|
||||||
|
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
|
import { ExportToExcalidrawPlus } from "./components/ExportToExcalidrawPlus";
|
||||||
|
|
||||||
const languageDetector = new LanguageDetector();
|
const languageDetector = new LanguageDetector();
|
||||||
languageDetector.init({
|
languageDetector.init({
|
||||||
@@ -428,6 +428,21 @@ const ExcalidrawWrapper = () => {
|
|||||||
canvasActions: {
|
canvasActions: {
|
||||||
export: {
|
export: {
|
||||||
onExportToBackend,
|
onExportToBackend,
|
||||||
|
renderCustomUI: (elements, appState) => {
|
||||||
|
return (
|
||||||
|
<ExportToExcalidrawPlus
|
||||||
|
elements={elements}
|
||||||
|
appState={appState}
|
||||||
|
onError={(error) => {
|
||||||
|
excalidrawAPI?.updateScene({
|
||||||
|
appState: {
|
||||||
|
errorMessage: error.message,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@@ -438,6 +453,7 @@ const ExcalidrawWrapper = () => {
|
|||||||
detectScroll={false}
|
detectScroll={false}
|
||||||
handleKeyboardGlobally={true}
|
handleKeyboardGlobally={true}
|
||||||
onLibraryChange={onLibraryChange}
|
onLibraryChange={onLibraryChange}
|
||||||
|
autoFocus={true}
|
||||||
/>
|
/>
|
||||||
{excalidrawAPI && <CollabWrapper excalidrawAPI={excalidrawAPI} />}
|
{excalidrawAPI && <CollabWrapper excalidrawAPI={excalidrawAPI} />}
|
||||||
{errorMessage && (
|
{errorMessage && (
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ const canvas = exportToCanvas(
|
|||||||
{
|
{
|
||||||
exportBackground: true,
|
exportBackground: true,
|
||||||
viewBackgroundColor: "#ffffff",
|
viewBackgroundColor: "#ffffff",
|
||||||
scale: 1,
|
|
||||||
},
|
},
|
||||||
createCanvas,
|
createCanvas,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "نمط العرض",
|
"viewMode": "نمط العرض",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "مشاركة",
|
"share": "مشاركة",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": "غير النمط"
|
"toggleTheme": "غير النمط"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "إحفظ لملف",
|
"disk_button": "إحفظ لملف",
|
||||||
"link_title": "رابط قابل للمشاركة",
|
"link_title": "رابط قابل للمشاركة",
|
||||||
"link_details": "صدر الملف للمشاهدة فقط.",
|
"link_details": "صدر الملف للمشاهدة فقط.",
|
||||||
"link_button": "التصدير كرابط"
|
"link_button": "التصدير كرابط",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "اقرأ مدونتنا",
|
"blog": "اقرأ مدونتنا",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Изглед",
|
"viewMode": "Изглед",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Прочетете нашия блог",
|
"blog": "Прочетете нашия блог",
|
||||||
|
|||||||
+14
-9
@@ -20,8 +20,8 @@
|
|||||||
"background": "Color del fons",
|
"background": "Color del fons",
|
||||||
"fill": "Estil del fons",
|
"fill": "Estil del fons",
|
||||||
"strokeWidth": "Amplada del traç",
|
"strokeWidth": "Amplada del traç",
|
||||||
"strokeShape": "",
|
"strokeShape": "Estil del traç",
|
||||||
"strokeShape_gel": "",
|
"strokeShape_gel": "Bolígraf de gel",
|
||||||
"strokeShape_fountain": "",
|
"strokeShape_fountain": "",
|
||||||
"strokeShape_brush": "",
|
"strokeShape_brush": "",
|
||||||
"strokeStyle": "Estil del traç",
|
"strokeStyle": "Estil del traç",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
"fontSize": "Mida de lletra",
|
"fontSize": "Mida de lletra",
|
||||||
"fontFamily": "Tipus de lletra",
|
"fontFamily": "Tipus de lletra",
|
||||||
"onlySelected": "Només seleccionats",
|
"onlySelected": "Només seleccionats",
|
||||||
"withBackground": "",
|
"withBackground": "Fons",
|
||||||
"exportEmbedScene": "",
|
"exportEmbedScene": "",
|
||||||
"exportEmbedScene_details": "Les dades de l’escena es desaran al fitxer PNG/SVG de manera que es pugui restaurar l’escena.\nAugmentarà la mida del fitxer exportat.",
|
"exportEmbedScene_details": "Les dades de l’escena es desaran al fitxer PNG/SVG de manera que es pugui restaurar l’escena.\nAugmentarà la mida del fitxer exportat.",
|
||||||
"addWatermark": "Afegir \"Fet amb Excalidraw\"",
|
"addWatermark": "Afegir \"Fet amb Excalidraw\"",
|
||||||
@@ -101,19 +101,21 @@
|
|||||||
"viewMode": "Mode de visualització",
|
"viewMode": "Mode de visualització",
|
||||||
"toggleExportColorScheme": "Canvia l'esquema de colors de l'exportació",
|
"toggleExportColorScheme": "Canvia l'esquema de colors de l'exportació",
|
||||||
"share": "Compartir",
|
"share": "Compartir",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"clearReset": "Netejar el llenç",
|
"clearReset": "Netejar el llenç",
|
||||||
"exportJSON": "",
|
"exportJSON": "Exporta a un fitxer",
|
||||||
"exportImage": "",
|
"exportImage": "Desa com a imatge",
|
||||||
"export": "Exportar",
|
"export": "Exportar",
|
||||||
"exportToPng": "Exportar a PNG",
|
"exportToPng": "Exportar a PNG",
|
||||||
"exportToSvg": "Exportar a SNG",
|
"exportToSvg": "Exportar a SNG",
|
||||||
"copyToClipboard": "Copiar al porta-retalls",
|
"copyToClipboard": "Copiar al porta-retalls",
|
||||||
"copyPngToClipboard": "Copiar PNG al porta-retalls",
|
"copyPngToClipboard": "Copiar PNG al porta-retalls",
|
||||||
"scale": "Escala",
|
"scale": "Escala",
|
||||||
"save": "",
|
"save": "Desa al fitxer actual",
|
||||||
"saveAs": "Desar com",
|
"saveAs": "Desar com",
|
||||||
"load": "Carregar",
|
"load": "Carregar",
|
||||||
"getShareableLink": "Obtenir enllaç per compartir",
|
"getShareableLink": "Obtenir enllaç per compartir",
|
||||||
@@ -218,12 +220,15 @@
|
|||||||
"title": "Error"
|
"title": "Error"
|
||||||
},
|
},
|
||||||
"exportDialog": {
|
"exportDialog": {
|
||||||
"disk_title": "",
|
"disk_title": "Desa la disc",
|
||||||
"disk_details": "",
|
"disk_details": "",
|
||||||
"disk_button": "",
|
"disk_button": "Desa en un fitxer",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "Exporta",
|
||||||
|
"excalidrawplus_exportError": "No és possible exportar a Excalidraw+ ara mateix..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Llegiu el nostre blog",
|
"blog": "Llegiu el nostre blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Náhled",
|
"viewMode": "Náhled",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "Sdílet",
|
"share": "Sdílet",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": "Přepnout tmavý řežim"
|
"toggleTheme": "Přepnout tmavý řežim"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "",
|
"blog": "",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Ansichtsmodus",
|
"viewMode": "Ansichtsmodus",
|
||||||
"toggleExportColorScheme": "Exportfarbschema umschalten",
|
"toggleExportColorScheme": "Exportfarbschema umschalten",
|
||||||
"share": "Teilen",
|
"share": "Teilen",
|
||||||
|
"showStroke": "Auswahl für Strichfarbe anzeigen",
|
||||||
|
"showBackground": "Auswahl für Hintergrundfarbe anzeigen",
|
||||||
"toggleTheme": "Design umschalten"
|
"toggleTheme": "Design umschalten"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "In Datei speichern",
|
"disk_button": "In Datei speichern",
|
||||||
"link_title": "Teilbarer Link",
|
"link_title": "Teilbarer Link",
|
||||||
"link_details": "Als schreibgeschützten Link exportieren.",
|
"link_details": "Als schreibgeschützten Link exportieren.",
|
||||||
"link_button": "Als Link exportieren"
|
"link_button": "Als Link exportieren",
|
||||||
|
"excalidrawplus_description": "Speichere die Szene in deinem Excalidraw+ Arbeitsbereich.",
|
||||||
|
"excalidrawplus_button": "Exportieren",
|
||||||
|
"excalidrawplus_exportError": "Konnte nicht nach Excalidraw+ exportieren..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Lies unseren Blog",
|
"blog": "Lies unseren Blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Λειτουργία προβολής",
|
"viewMode": "Λειτουργία προβολής",
|
||||||
"toggleExportColorScheme": "Εναλλαγή εξαγωγής θέματος χρωμάτων",
|
"toggleExportColorScheme": "Εναλλαγή εξαγωγής θέματος χρωμάτων",
|
||||||
"share": "Κοινοποίηση",
|
"share": "Κοινοποίηση",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Διαβάστε το Blog μας",
|
"blog": "Διαβάστε το Blog μας",
|
||||||
|
|||||||
+10
-3
@@ -180,6 +180,8 @@
|
|||||||
"linearElement": "Click to start multiple points, drag for single line",
|
"linearElement": "Click to start multiple points, drag for single line",
|
||||||
"freeDraw": "Click and drag, release when you're finished",
|
"freeDraw": "Click and drag, release when you're finished",
|
||||||
"text": "Tip: you can also add text by double-clicking anywhere with the selection tool",
|
"text": "Tip: you can also add text by double-clicking anywhere with the selection tool",
|
||||||
|
"text_selected": "Double-click or press ENTER to edit text",
|
||||||
|
"text_editing": "Press Escape or CtrlOrCmd+ENTER to finish editing",
|
||||||
"linearElementMulti": "Click on last point or press Escape or Enter to finish",
|
"linearElementMulti": "Click on last point or press Escape or Enter to finish",
|
||||||
"lockAngle": "You can constrain angle by holding SHIFT",
|
"lockAngle": "You can constrain angle by holding SHIFT",
|
||||||
"resize": "You can constrain proportions by holding SHIFT while resizing,\nhold ALT to resize from the center",
|
"resize": "You can constrain proportions by holding SHIFT while resizing,\nhold ALT to resize from the center",
|
||||||
@@ -225,7 +227,10 @@
|
|||||||
"disk_button": "Save to file",
|
"disk_button": "Save to file",
|
||||||
"link_title": "Shareable link",
|
"link_title": "Shareable link",
|
||||||
"link_details": "Export as a read-only link.",
|
"link_details": "Export as a read-only link.",
|
||||||
"link_button": "Export to Link"
|
"link_button": "Export to Link",
|
||||||
|
"excalidrawplus_description": "Save the scene to your Excalidraw+ workspace.",
|
||||||
|
"excalidrawplus_button": "Export",
|
||||||
|
"excalidrawplus_exportError": "Couldn't export to Excalidraw+ at this moment..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Read our blog",
|
"blog": "Read our blog",
|
||||||
@@ -233,16 +238,18 @@
|
|||||||
"curvedArrow": "Curved arrow",
|
"curvedArrow": "Curved arrow",
|
||||||
"curvedLine": "Curved line",
|
"curvedLine": "Curved line",
|
||||||
"documentation": "Documentation",
|
"documentation": "Documentation",
|
||||||
|
"doubleClick": "double-click",
|
||||||
"drag": "drag",
|
"drag": "drag",
|
||||||
"editor": "Editor",
|
"editor": "Editor",
|
||||||
|
"editSelectedShape": "Edit selected shape (text/arrow/line)",
|
||||||
"github": "Found an issue? Submit",
|
"github": "Found an issue? Submit",
|
||||||
"howto": "Follow our guides",
|
"howto": "Follow our guides",
|
||||||
"or": "or",
|
"or": "or",
|
||||||
"preventBinding": "Prevent arrow binding",
|
"preventBinding": "Prevent arrow binding",
|
||||||
"shapes": "Shapes",
|
"shapes": "Shapes",
|
||||||
"shortcuts": "Keyboard shortcuts",
|
"shortcuts": "Keyboard shortcuts",
|
||||||
"textFinish": "Finish editing (text)",
|
"textFinish": "Finish editing (text editor)",
|
||||||
"textNewLine": "Add new line (text)",
|
"textNewLine": "Add new line (text editor)",
|
||||||
"title": "Help",
|
"title": "Help",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
"zoomToFit": "Zoom to fit all elements",
|
"zoomToFit": "Zoom to fit all elements",
|
||||||
|
|||||||
+18
-13
@@ -42,8 +42,8 @@
|
|||||||
"fontSize": "Tamaño de la fuente",
|
"fontSize": "Tamaño de la fuente",
|
||||||
"fontFamily": "Tipo de fuente",
|
"fontFamily": "Tipo de fuente",
|
||||||
"onlySelected": "Sólo seleccionados",
|
"onlySelected": "Sólo seleccionados",
|
||||||
"withBackground": "",
|
"withBackground": "Fondo",
|
||||||
"exportEmbedScene": "",
|
"exportEmbedScene": "Embeber escena",
|
||||||
"exportEmbedScene_details": "Los datos de escena se guardarán en el archivo PNG/SVG exportado, así la escena puede ser restaurada de la misma.\nEsto aumentará el tamaño del archivo exportado.",
|
"exportEmbedScene_details": "Los datos de escena se guardarán en el archivo PNG/SVG exportado, así la escena puede ser restaurada de la misma.\nEsto aumentará el tamaño del archivo exportado.",
|
||||||
"addWatermark": "Agregar \"Hecho con Excalidraw\"",
|
"addWatermark": "Agregar \"Hecho con Excalidraw\"",
|
||||||
"handDrawn": "Dibujado a mano",
|
"handDrawn": "Dibujado a mano",
|
||||||
@@ -101,19 +101,21 @@
|
|||||||
"viewMode": "Modo presentación",
|
"viewMode": "Modo presentación",
|
||||||
"toggleExportColorScheme": "Cambiar el esquema de colores de exportación",
|
"toggleExportColorScheme": "Cambiar el esquema de colores de exportación",
|
||||||
"share": "Compartir",
|
"share": "Compartir",
|
||||||
|
"showStroke": "Mostrar el selector de color del trazo",
|
||||||
|
"showBackground": "Mostrar el selector de color de fondo",
|
||||||
"toggleTheme": "Alternar tema"
|
"toggleTheme": "Alternar tema"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"clearReset": "Limpiar lienzo y reiniciar el color de fondo",
|
"clearReset": "Limpiar lienzo y reiniciar el color de fondo",
|
||||||
"exportJSON": "",
|
"exportJSON": "Exportar como archivo",
|
||||||
"exportImage": "",
|
"exportImage": "Guardar como imagen",
|
||||||
"export": "Exportar",
|
"export": "Exportar",
|
||||||
"exportToPng": "Exportar a PNG",
|
"exportToPng": "Exportar a PNG",
|
||||||
"exportToSvg": "Exportar a SVG",
|
"exportToSvg": "Exportar a SVG",
|
||||||
"copyToClipboard": "Copiar al portapapeles",
|
"copyToClipboard": "Copiar al portapapeles",
|
||||||
"copyPngToClipboard": "Copiar PNG al portapapeles",
|
"copyPngToClipboard": "Copiar PNG al portapapeles",
|
||||||
"scale": "Escalar",
|
"scale": "Escalar",
|
||||||
"save": "",
|
"save": "Guardal al archivo actual",
|
||||||
"saveAs": "Guardar como",
|
"saveAs": "Guardar como",
|
||||||
"load": "Cargar",
|
"load": "Cargar",
|
||||||
"getShareableLink": "Obtener enlace para compartir",
|
"getShareableLink": "Obtener enlace para compartir",
|
||||||
@@ -122,7 +124,7 @@
|
|||||||
"scrollBackToContent": "Volver al contenido",
|
"scrollBackToContent": "Volver al contenido",
|
||||||
"zoomIn": "Acercarse",
|
"zoomIn": "Acercarse",
|
||||||
"zoomOut": "Alejarse",
|
"zoomOut": "Alejarse",
|
||||||
"resetZoom": "Restablecer acercamiento",
|
"resetZoom": "Restablecer zoom",
|
||||||
"menu": "Menú",
|
"menu": "Menú",
|
||||||
"done": "Hecho",
|
"done": "Hecho",
|
||||||
"edit": "Editar",
|
"edit": "Editar",
|
||||||
@@ -218,12 +220,15 @@
|
|||||||
"title": "Error"
|
"title": "Error"
|
||||||
},
|
},
|
||||||
"exportDialog": {
|
"exportDialog": {
|
||||||
"disk_title": "",
|
"disk_title": "Guardar en el disco",
|
||||||
"disk_details": "",
|
"disk_details": "Exportar los datos de la escena a un archivo desde el cual se puede importar más tarde.",
|
||||||
"disk_button": "",
|
"disk_button": "Guardar en el archivo",
|
||||||
"link_title": "",
|
"link_title": "Enlace para compartir",
|
||||||
"link_details": "",
|
"link_details": "Exportar como enlace de sólo lectura.",
|
||||||
"link_button": ""
|
"link_button": "Exportar al link",
|
||||||
|
"excalidrawplus_description": "Guarda la escena en tu espacio de trabajo de Excalidraw+.",
|
||||||
|
"excalidrawplus_button": "Exportar",
|
||||||
|
"excalidrawplus_exportError": "No se pudo exportar a Excalidraw+ en este momento..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Lee nuestro blog",
|
"blog": "Lee nuestro blog",
|
||||||
@@ -248,7 +253,7 @@
|
|||||||
},
|
},
|
||||||
"encrypted": {
|
"encrypted": {
|
||||||
"tooltip": "Tus dibujos están cifrados de punto a punto, por lo que los servidores de Excalidraw nunca los verán.",
|
"tooltip": "Tus dibujos están cifrados de punto a punto, por lo que los servidores de Excalidraw nunca los verán.",
|
||||||
"link": ""
|
"link": "Entrada en el blog sobre cifrado de extremo a extremo"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"angle": "Ángulo",
|
"angle": "Ángulo",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "",
|
"viewMode": "",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "بلاگ ما را بخوانید",
|
"blog": "بلاگ ما را بخوانید",
|
||||||
|
|||||||
+16
-11
@@ -42,8 +42,8 @@
|
|||||||
"fontSize": "Kirjasinkoko",
|
"fontSize": "Kirjasinkoko",
|
||||||
"fontFamily": "Kirjasintyyppi",
|
"fontFamily": "Kirjasintyyppi",
|
||||||
"onlySelected": "Vain valitut",
|
"onlySelected": "Vain valitut",
|
||||||
"withBackground": "",
|
"withBackground": "Taustalla",
|
||||||
"exportEmbedScene": "",
|
"exportEmbedScene": "Upota työ",
|
||||||
"exportEmbedScene_details": "Teoksen tiedot tallennetaan PNG/SVG-tiedostoon, jolloin teoksen voi palauttaa siitä. Kasvattaa tallennetun tiedoston kokoa.",
|
"exportEmbedScene_details": "Teoksen tiedot tallennetaan PNG/SVG-tiedostoon, jolloin teoksen voi palauttaa siitä. Kasvattaa tallennetun tiedoston kokoa.",
|
||||||
"addWatermark": "Lisää \"Tehty Excalidrawilla\"",
|
"addWatermark": "Lisää \"Tehty Excalidrawilla\"",
|
||||||
"handDrawn": "Käsinkirjoitettu",
|
"handDrawn": "Käsinkirjoitettu",
|
||||||
@@ -101,19 +101,21 @@
|
|||||||
"viewMode": "Katselutila",
|
"viewMode": "Katselutila",
|
||||||
"toggleExportColorScheme": "Vaihda viennin väriteema",
|
"toggleExportColorScheme": "Vaihda viennin väriteema",
|
||||||
"share": "Jaa",
|
"share": "Jaa",
|
||||||
|
"showStroke": "Näytä viivan värin valitsin",
|
||||||
|
"showBackground": "Näytä taustavärin valitsin",
|
||||||
"toggleTheme": "Vaihda teema"
|
"toggleTheme": "Vaihda teema"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"clearReset": "Tyhjennä piirtoalue",
|
"clearReset": "Tyhjennä piirtoalue",
|
||||||
"exportJSON": "",
|
"exportJSON": "Vie tiedostoon",
|
||||||
"exportImage": "",
|
"exportImage": "Tallenna kuvana",
|
||||||
"export": "Vie",
|
"export": "Vie",
|
||||||
"exportToPng": "Vie PNG-tiedostona",
|
"exportToPng": "Vie PNG-tiedostona",
|
||||||
"exportToSvg": "Vie SVG-tiedostona",
|
"exportToSvg": "Vie SVG-tiedostona",
|
||||||
"copyToClipboard": "Kopioi leikepöydälle",
|
"copyToClipboard": "Kopioi leikepöydälle",
|
||||||
"copyPngToClipboard": "Kopioi PNG-tiedosto leikepöydälle",
|
"copyPngToClipboard": "Kopioi PNG-tiedosto leikepöydälle",
|
||||||
"scale": "Koko",
|
"scale": "Koko",
|
||||||
"save": "",
|
"save": "Tallenna nykyiseen tiedostoon",
|
||||||
"saveAs": "Tallenna nimellä",
|
"saveAs": "Tallenna nimellä",
|
||||||
"load": "Avaa",
|
"load": "Avaa",
|
||||||
"getShareableLink": "Hae jaettava linkki",
|
"getShareableLink": "Hae jaettava linkki",
|
||||||
@@ -218,12 +220,15 @@
|
|||||||
"title": "Virhe"
|
"title": "Virhe"
|
||||||
},
|
},
|
||||||
"exportDialog": {
|
"exportDialog": {
|
||||||
"disk_title": "",
|
"disk_title": "Tallenna levylle",
|
||||||
"disk_details": "",
|
"disk_details": "Vie työn tiedot tiedostoon, josta sen voi tuoda myöhemmin.",
|
||||||
"disk_button": "",
|
"disk_button": "Tallenna tiedostoon",
|
||||||
"link_title": "",
|
"link_title": "Jaettava linkki",
|
||||||
"link_details": "",
|
"link_details": "Vie vain luku -linkkinä.",
|
||||||
"link_button": ""
|
"link_button": "Vie linkkinä",
|
||||||
|
"excalidrawplus_description": "Tallenna teos Excalidraw+ tilaan.",
|
||||||
|
"excalidrawplus_button": "Vie",
|
||||||
|
"excalidrawplus_exportError": "Ei voitu viedä Excalidraw+-palveluun tällä hetkellä..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Lue blogiamme",
|
"blog": "Lue blogiamme",
|
||||||
|
|||||||
+19
-14
@@ -16,7 +16,7 @@
|
|||||||
"delete": "Supprimer",
|
"delete": "Supprimer",
|
||||||
"copyStyles": "Copier les styles",
|
"copyStyles": "Copier les styles",
|
||||||
"pasteStyles": "Coller les styles",
|
"pasteStyles": "Coller les styles",
|
||||||
"stroke": "Contour",
|
"stroke": "Trait",
|
||||||
"background": "Arrière-plan",
|
"background": "Arrière-plan",
|
||||||
"fill": "Remplissage",
|
"fill": "Remplissage",
|
||||||
"strokeWidth": "Largeur du trait",
|
"strokeWidth": "Largeur du trait",
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
"fontFamily": "Police",
|
"fontFamily": "Police",
|
||||||
"onlySelected": "Uniquement la sélection",
|
"onlySelected": "Uniquement la sélection",
|
||||||
"withBackground": "Arrière-plan",
|
"withBackground": "Arrière-plan",
|
||||||
"exportEmbedScene": "Scène intégrée",
|
"exportEmbedScene": "Intégrer la scène",
|
||||||
"exportEmbedScene_details": "Les données de scène seront enregistrées dans le fichier PNG/SVG exporté, afin que la scène puisse être restaurée à partir de celui-ci.\nCela augmentera la taille du fichier exporté.",
|
"exportEmbedScene_details": "Les données de scène seront enregistrées dans le fichier PNG/SVG exporté, afin que la scène puisse être restaurée à partir de celui-ci.\nCela augmentera la taille du fichier exporté.",
|
||||||
"addWatermark": "Ajouter \"Fait avec Excalidraw\"",
|
"addWatermark": "Ajouter \"Fait avec Excalidraw\"",
|
||||||
"handDrawn": "À main levée",
|
"handDrawn": "À main levée",
|
||||||
@@ -101,19 +101,21 @@
|
|||||||
"viewMode": "Mode présentation",
|
"viewMode": "Mode présentation",
|
||||||
"toggleExportColorScheme": "Activer/Désactiver l'export du thème de couleur",
|
"toggleExportColorScheme": "Activer/Désactiver l'export du thème de couleur",
|
||||||
"share": "Partager",
|
"share": "Partager",
|
||||||
|
"showStroke": "Afficher le sélecteur de couleur de trait",
|
||||||
|
"showBackground": "Afficher le sélecteur de couleur d'arrière-plan",
|
||||||
"toggleTheme": "Changer le thème"
|
"toggleTheme": "Changer le thème"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"clearReset": "Réinitialiser le canevas",
|
"clearReset": "Réinitialiser le canevas",
|
||||||
"exportJSON": "Exporter dans un fichier",
|
"exportJSON": "Exporter comme fichier",
|
||||||
"exportImage": "Enregistrer comme image",
|
"exportImage": "Enregistrer comme image",
|
||||||
"export": "Exporter",
|
"export": "Exporter",
|
||||||
"exportToPng": "Exporter en PNG",
|
"exportToPng": "Enregistrer en PNG",
|
||||||
"exportToSvg": "Exporter en SVG",
|
"exportToSvg": "Enregistrer en SVG",
|
||||||
"copyToClipboard": "Copier dans le presse-papier",
|
"copyToClipboard": "Copier dans le presse-papier",
|
||||||
"copyPngToClipboard": "Copier le PNG vers le presse-papier",
|
"copyPngToClipboard": "Copier le PNG dans le presse-papier",
|
||||||
"scale": "Échelle",
|
"scale": "Échelle",
|
||||||
"save": "Sauvegarder dans le fichier actuel",
|
"save": "Enregistrer dans le fichier actuel",
|
||||||
"saveAs": "Enregistrer sous",
|
"saveAs": "Enregistrer sous",
|
||||||
"load": "Ouvrir",
|
"load": "Ouvrir",
|
||||||
"getShareableLink": "Obtenir un lien de partage",
|
"getShareableLink": "Obtenir un lien de partage",
|
||||||
@@ -218,12 +220,15 @@
|
|||||||
"title": "Erreur"
|
"title": "Erreur"
|
||||||
},
|
},
|
||||||
"exportDialog": {
|
"exportDialog": {
|
||||||
"disk_title": "Sauvegarder sur le disque",
|
"disk_title": "Enregistrer sur le disque",
|
||||||
"disk_details": "Exportez les données de la scène dans un fichier que vous pourrez importer ultérieurement.",
|
"disk_details": "Exporter les données de la scène comme un fichier que vous pourrez importer ultérieurement.",
|
||||||
"disk_button": "Sauvegarder dans un fichier",
|
"disk_button": "Enregistrer comme fichier",
|
||||||
"link_title": "Lien à partager",
|
"link_title": "Lien partageable",
|
||||||
"link_details": "Exporter comme un lien en lecture seule.",
|
"link_details": "Exporter comme un lien en lecture seule.",
|
||||||
"link_button": "Exporter vers un lien"
|
"link_button": "Exporter comme lien",
|
||||||
|
"excalidrawplus_description": "Enregistrer la scène dans votre espace de travail Excalidraw+.",
|
||||||
|
"excalidrawplus_button": "Exporter",
|
||||||
|
"excalidrawplus_exportError": "Impossible d'exporter vers Excalidraw+ pour le moment..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Lire notre blog",
|
"blog": "Lire notre blog",
|
||||||
@@ -267,8 +272,8 @@
|
|||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
"copyStyles": "Styles copiés.",
|
"copyStyles": "Styles copiés.",
|
||||||
"copyToClipboard": "Copié vers le presse-papiers.",
|
"copyToClipboard": "Copié dans le presse-papier.",
|
||||||
"copyToClipboardAsPng": "{{exportSelection}} copié dans le presse-papiers en PNG\n({{exportColorScheme}})",
|
"copyToClipboardAsPng": "{{exportSelection}} copié dans le presse-papier en PNG\n({{exportColorScheme}})",
|
||||||
"fileSaved": "Fichier enregistré.",
|
"fileSaved": "Fichier enregistré.",
|
||||||
"fileSavedToFilename": "Enregistré sous {filename}",
|
"fileSavedToFilename": "Enregistré sous {filename}",
|
||||||
"canvas": "canevas",
|
"canvas": "canevas",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "מצב תצוגה",
|
"viewMode": "מצב תצוגה",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "קרא את הבלוג שלנו",
|
"blog": "קרא את הבלוג שלנו",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "",
|
"viewMode": "",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "हमारा ब्लॉग पढे",
|
"blog": "हमारा ब्लॉग पढे",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "",
|
"viewMode": "",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "",
|
"blog": "",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Mode tampilan",
|
"viewMode": "Mode tampilan",
|
||||||
"toggleExportColorScheme": "Ubah skema warna ekspor",
|
"toggleExportColorScheme": "Ubah skema warna ekspor",
|
||||||
"share": "Bagikan",
|
"share": "Bagikan",
|
||||||
|
"showStroke": "Tampilkan garis pengambil warna",
|
||||||
|
"showBackground": "Tampilkan latar pengambil warna",
|
||||||
"toggleTheme": "Ubah tema"
|
"toggleTheme": "Ubah tema"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Simpan ke file",
|
"disk_button": "Simpan ke file",
|
||||||
"link_title": "Tautan",
|
"link_title": "Tautan",
|
||||||
"link_details": "Ekspor sebagai tautan yang hanya dibaca.",
|
"link_details": "Ekspor sebagai tautan yang hanya dibaca.",
|
||||||
"link_button": "Ekspor ke tautan"
|
"link_button": "Ekspor ke tautan",
|
||||||
|
"excalidrawplus_description": "Simpan pemandangan ke ruang kerja Excalidraw+ Anda.",
|
||||||
|
"excalidrawplus_button": "Ekspor",
|
||||||
|
"excalidrawplus_exportError": "Tidak dapat ekspor ke Excalidraw+ saat ini..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Baca blog kami",
|
"blog": "Baca blog kami",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Modalità visualizzazione",
|
"viewMode": "Modalità visualizzazione",
|
||||||
"toggleExportColorScheme": "Cambia lo schema di colori in esportazione",
|
"toggleExportColorScheme": "Cambia lo schema di colori in esportazione",
|
||||||
"share": "Condividi",
|
"share": "Condividi",
|
||||||
|
"showStroke": "Mostra selettore colore del tratto",
|
||||||
|
"showBackground": "Mostra selettore colore di sfondo",
|
||||||
"toggleTheme": "Cambia tema"
|
"toggleTheme": "Cambia tema"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Salva su file",
|
"disk_button": "Salva su file",
|
||||||
"link_title": "Link condivisibile",
|
"link_title": "Link condivisibile",
|
||||||
"link_details": "Esporta come link di sola lettura.",
|
"link_details": "Esporta come link di sola lettura.",
|
||||||
"link_button": "Esporta come Link"
|
"link_button": "Esporta come Link",
|
||||||
|
"excalidrawplus_description": "Salva la scena nel tuo spazio di lavoro Excalidraw+.",
|
||||||
|
"excalidrawplus_button": "Esporta",
|
||||||
|
"excalidrawplus_exportError": "Non è stato possibile esportare su Excalidraw+ al questo momento..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Leggi il nostro blog",
|
"blog": "Leggi il nostro blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "閲覧モード",
|
"viewMode": "閲覧モード",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "共有",
|
"share": "共有",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": "テーマの切り替え"
|
"toggleTheme": "テーマの切り替え"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "ファイルへ保存",
|
"disk_button": "ファイルへ保存",
|
||||||
"link_title": "共有可能なリンク",
|
"link_title": "共有可能なリンク",
|
||||||
"link_details": "読み取り専用リンクとしてエクスポート",
|
"link_details": "読み取り専用リンクとしてエクスポート",
|
||||||
"link_button": "リンクとしてエクスポート"
|
"link_button": "リンクとしてエクスポート",
|
||||||
|
"excalidrawplus_description": "Excalidraw+ ワークスペースにシーンを保存します。",
|
||||||
|
"excalidrawplus_button": "エクスポート",
|
||||||
|
"excalidrawplus_exportError": "Excalidraw+ にエクスポートできませんでした..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "公式ブログを読む",
|
"blog": "公式ブログを読む",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
"background": "Agilal",
|
"background": "Agilal",
|
||||||
"fill": "Taččart",
|
"fill": "Taččart",
|
||||||
"strokeWidth": "Tehri n yizirig",
|
"strokeWidth": "Tehri n yizirig",
|
||||||
"strokeShape": "",
|
"strokeShape": "Talɣa n yizirig",
|
||||||
"strokeShape_gel": "",
|
"strokeShape_gel": "",
|
||||||
"strokeShape_fountain": "",
|
"strokeShape_fountain": "",
|
||||||
"strokeShape_brush": "Amfezzu",
|
"strokeShape_brush": "Amfezzu",
|
||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Askar n tmuɣli",
|
"viewMode": "Askar n tmuɣli",
|
||||||
"toggleExportColorScheme": "Sermed/sens asifeḍ usentel n yini",
|
"toggleExportColorScheme": "Sermed/sens asifeḍ usentel n yini",
|
||||||
"share": "Bḍu",
|
"share": "Bḍu",
|
||||||
|
"showStroke": "Beqqeḍ amelqaḍ n yini n yizirig",
|
||||||
|
"showBackground": "Beqqeḍ amelqaḍ n yini n ugilal",
|
||||||
"toggleTheme": "Snifel asentel"
|
"toggleTheme": "Snifel asentel"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Sekles deg ufaylu",
|
"disk_button": "Sekles deg ufaylu",
|
||||||
"link_title": "Aseɣwen n beṭṭu",
|
"link_title": "Aseɣwen n beṭṭu",
|
||||||
"link_details": "Sifeḍ am useɣwen n tɣuri kan.",
|
"link_details": "Sifeḍ am useɣwen n tɣuri kan.",
|
||||||
"link_button": "Sifeḍ deg useɣwen"
|
"link_button": "Sifeḍ deg useɣwen",
|
||||||
|
"excalidrawplus_description": "Sekles asayes-inek•inem di tallunt n umahil Excalidraw+.",
|
||||||
|
"excalidrawplus_button": "Sifeḍ",
|
||||||
|
"excalidrawplus_exportError": "Ulamek asifeḍ ɣer Excalidraw+ akka tura..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Ɣeṛ ablug-nneɣ",
|
"blog": "Ɣeṛ ablug-nneɣ",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "보기 모드",
|
"viewMode": "보기 모드",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "블로그 읽어보기",
|
"blog": "블로그 읽어보기",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "",
|
"viewMode": "",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "",
|
"blog": "",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "",
|
"viewMode": "",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "",
|
"blog": "",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Visningsmodus",
|
"viewMode": "Visningsmodus",
|
||||||
"toggleExportColorScheme": "Veksle eksport av fargepalett",
|
"toggleExportColorScheme": "Veksle eksport av fargepalett",
|
||||||
"share": "Del",
|
"share": "Del",
|
||||||
|
"showStroke": "Vis fargevelger for kantfarge",
|
||||||
|
"showBackground": "Vis fargevelger for bakgrunnsfarge",
|
||||||
"toggleTheme": "Veksle tema"
|
"toggleTheme": "Veksle tema"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Lagre til fil",
|
"disk_button": "Lagre til fil",
|
||||||
"link_title": "Delbar lenke",
|
"link_title": "Delbar lenke",
|
||||||
"link_details": "Eksporter som en skrivebeskyttet lenke.",
|
"link_details": "Eksporter som en skrivebeskyttet lenke.",
|
||||||
"link_button": "Eksporter til lenke"
|
"link_button": "Eksporter til lenke",
|
||||||
|
"excalidrawplus_description": "Lagre scenen til ditt Excalidraw+ arbeidsområde.",
|
||||||
|
"excalidrawplus_button": "Eksporter",
|
||||||
|
"excalidrawplus_exportError": "Kunne ikke eksportere til Excalidraw+ for øyeblikket..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Les bloggen vår",
|
"blog": "Les bloggen vår",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Weergavemodus",
|
"viewMode": "Weergavemodus",
|
||||||
"toggleExportColorScheme": "Kleurenschema exporteren aan/uit",
|
"toggleExportColorScheme": "Kleurenschema exporteren aan/uit",
|
||||||
"share": "Deel",
|
"share": "Deel",
|
||||||
|
"showStroke": "Toon lijn kleur kiezer",
|
||||||
|
"showBackground": "Toon achtergrondkleur kiezer",
|
||||||
"toggleTheme": "Thema aan/uit"
|
"toggleTheme": "Thema aan/uit"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Opslaan naar bestand",
|
"disk_button": "Opslaan naar bestand",
|
||||||
"link_title": "Deelbare link",
|
"link_title": "Deelbare link",
|
||||||
"link_details": "Exporteren als een alleen-lezen link.",
|
"link_details": "Exporteren als een alleen-lezen link.",
|
||||||
"link_button": "Exporteer naar link"
|
"link_button": "Exporteer naar link",
|
||||||
|
"excalidrawplus_description": "Sla de scène op in je Excalidraw+ werkruimte.",
|
||||||
|
"excalidrawplus_button": "Exporteren",
|
||||||
|
"excalidrawplus_exportError": "Kan op dit moment niet exporteren naar Excalidraw+..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Lees onze blog",
|
"blog": "Lees onze blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Visningsmodus",
|
"viewMode": "Visningsmodus",
|
||||||
"toggleExportColorScheme": "Veksle eksport av fargepalett",
|
"toggleExportColorScheme": "Veksle eksport av fargepalett",
|
||||||
"share": "Del",
|
"share": "Del",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Les bloggen vår",
|
"blog": "Les bloggen vår",
|
||||||
|
|||||||
+16
-11
@@ -42,8 +42,8 @@
|
|||||||
"fontSize": "Talha poliça",
|
"fontSize": "Talha poliça",
|
||||||
"fontFamily": "Familha de poliça",
|
"fontFamily": "Familha de poliça",
|
||||||
"onlySelected": "Seleccion sonque",
|
"onlySelected": "Seleccion sonque",
|
||||||
"withBackground": "",
|
"withBackground": "Rèireplan",
|
||||||
"exportEmbedScene": "",
|
"exportEmbedScene": "Scèna embarcada",
|
||||||
"exportEmbedScene_details": "Las donadas de scèna seràn enregistradas dins lo fichièr PNG/SVG exportat, per que la scèna pòsca èsser restaurada a partir d’aqueste fichièr.\nAumentarà la talha del fichièr exportat.",
|
"exportEmbedScene_details": "Las donadas de scèna seràn enregistradas dins lo fichièr PNG/SVG exportat, per que la scèna pòsca èsser restaurada a partir d’aqueste fichièr.\nAumentarà la talha del fichièr exportat.",
|
||||||
"addWatermark": "Apondre « Fabricat amb Excalidraw »",
|
"addWatermark": "Apondre « Fabricat amb Excalidraw »",
|
||||||
"handDrawn": "A la man levada",
|
"handDrawn": "A la man levada",
|
||||||
@@ -101,19 +101,21 @@
|
|||||||
"viewMode": "Mòde de vista",
|
"viewMode": "Mòde de vista",
|
||||||
"toggleExportColorScheme": "Alternar l’esquèma de color d’expòrt",
|
"toggleExportColorScheme": "Alternar l’esquèma de color d’expòrt",
|
||||||
"share": "Partejar",
|
"share": "Partejar",
|
||||||
|
"showStroke": "Mostrar lo selector de color de contorn",
|
||||||
|
"showBackground": "Mostrar lo selector de color de fons",
|
||||||
"toggleTheme": "Alternar tèma"
|
"toggleTheme": "Alternar tèma"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"clearReset": "Reïnicializar lo canabàs",
|
"clearReset": "Reïnicializar lo canabàs",
|
||||||
"exportJSON": "",
|
"exportJSON": "Exportar en fichièr",
|
||||||
"exportImage": "",
|
"exportImage": "Salvar coma imatge",
|
||||||
"export": "Exportar",
|
"export": "Exportar",
|
||||||
"exportToPng": "Exportar en PNG",
|
"exportToPng": "Exportar en PNG",
|
||||||
"exportToSvg": "Exportar en SVG",
|
"exportToSvg": "Exportar en SVG",
|
||||||
"copyToClipboard": "Copiar al quichapapièrs",
|
"copyToClipboard": "Copiar al quichapapièrs",
|
||||||
"copyPngToClipboard": "Copiar PNG al quichapapièrs",
|
"copyPngToClipboard": "Copiar PNG al quichapapièrs",
|
||||||
"scale": "Escala",
|
"scale": "Escala",
|
||||||
"save": "",
|
"save": "Salvar al fichièr actual",
|
||||||
"saveAs": "Enregistrar jos",
|
"saveAs": "Enregistrar jos",
|
||||||
"load": "Cargar",
|
"load": "Cargar",
|
||||||
"getShareableLink": "Obténer lo ligam de partatge",
|
"getShareableLink": "Obténer lo ligam de partatge",
|
||||||
@@ -218,12 +220,15 @@
|
|||||||
"title": "Error"
|
"title": "Error"
|
||||||
},
|
},
|
||||||
"exportDialog": {
|
"exportDialog": {
|
||||||
"disk_title": "",
|
"disk_title": "Salvar al disc",
|
||||||
"disk_details": "",
|
"disk_details": "Exportar las donadas de la scèna cap a un fichièr que podètz importar mai tard.",
|
||||||
"disk_button": "",
|
"disk_button": "Salvar al fichièr",
|
||||||
"link_title": "",
|
"link_title": "Ligam de partejar",
|
||||||
"link_details": "",
|
"link_details": "Exportar coma un ligam de lectura sola.",
|
||||||
"link_button": ""
|
"link_button": "Exportar en ligam",
|
||||||
|
"excalidrawplus_description": "Enregistrar la scèna dins vòstre espaci de trabalh Excalidraw+.",
|
||||||
|
"excalidrawplus_button": "Exportar",
|
||||||
|
"excalidrawplus_exportError": "Export impossibla cap a Excalidraw+ pel moment..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Legir nòstre blog",
|
"blog": "Legir nòstre blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "ਦੇਖੋ ਮੋਡ",
|
"viewMode": "ਦੇਖੋ ਮੋਡ",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "ਸਾਂਝਾ ਕਰੋ",
|
"share": "ਸਾਂਝਾ ਕਰੋ",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": "ਥੀਮ ਬਦਲੋ"
|
"toggleTheme": "ਥੀਮ ਬਦਲੋ"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "ਸਾਡਾ ਬਲੌਗ ਪੜ੍ਹੋ",
|
"blog": "ਸਾਡਾ ਬਲੌਗ ਪੜ੍ਹੋ",
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
{
|
{
|
||||||
"ar-SA": 94,
|
"ar-SA": 92,
|
||||||
"bg-BG": 85,
|
"bg-BG": 83,
|
||||||
"ca-ES": 92,
|
"ca-ES": 94,
|
||||||
"cs-CZ": 36,
|
"cs-CZ": 36,
|
||||||
"de-DE": 100,
|
"de-DE": 100,
|
||||||
"el-GR": 90,
|
"el-GR": 88,
|
||||||
"en": 100,
|
"en": 100,
|
||||||
"es-ES": 93,
|
"es-ES": 98,
|
||||||
"fa-IR": 81,
|
"fa-IR": 79,
|
||||||
"fi-FI": 94,
|
"fi-FI": 99,
|
||||||
"fr-FR": 100,
|
"fr-FR": 100,
|
||||||
"he-IL": 82,
|
"he-IL": 80,
|
||||||
"hi-IN": 84,
|
"hi-IN": 82,
|
||||||
"hu-HU": 74,
|
"hu-HU": 73,
|
||||||
"id-ID": 100,
|
"id-ID": 100,
|
||||||
"it-IT": 99,
|
"it-IT": 99,
|
||||||
"ja-JP": 99,
|
"ja-JP": 98,
|
||||||
"kab-KAB": 97,
|
"kab-KAB": 98,
|
||||||
"ko-KR": 85,
|
"ko-KR": 83,
|
||||||
"lv-LV": 17,
|
"lv-LV": 17,
|
||||||
"my-MM": 69,
|
"my-MM": 68,
|
||||||
"nb-NO": 100,
|
"nb-NO": 100,
|
||||||
"nl-NL": 100,
|
"nl-NL": 100,
|
||||||
"nn-NO": 92,
|
"nn-NO": 90,
|
||||||
"oc-FR": 95,
|
"oc-FR": 100,
|
||||||
"pa-IN": 91,
|
"pa-IN": 89,
|
||||||
"pl-PL": 87,
|
"pl-PL": 85,
|
||||||
"pt-BR": 92,
|
"pt-BR": 90,
|
||||||
"pt-PT": 94,
|
"pt-PT": 92,
|
||||||
"ro-RO": 100,
|
"ro-RO": 100,
|
||||||
"ru-RU": 95,
|
"ru-RU": 97,
|
||||||
"sk-SK": 95,
|
"sk-SK": 100,
|
||||||
"sv-SE": 100,
|
"sv-SE": 100,
|
||||||
"tr-TR": 93,
|
"tr-TR": 91,
|
||||||
"uk-UA": 100,
|
"uk-UA": 97,
|
||||||
"zh-CN": 94,
|
"zh-CN": 98,
|
||||||
"zh-TW": 99
|
"zh-TW": 99
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Tryb widoku",
|
"viewMode": "Tryb widoku",
|
||||||
"toggleExportColorScheme": "",
|
"toggleExportColorScheme": "",
|
||||||
"share": "",
|
"share": "",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Przeczytaj na naszym blogu",
|
"blog": "Przeczytaj na naszym blogu",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Modo de visualização",
|
"viewMode": "Modo de visualização",
|
||||||
"toggleExportColorScheme": "Alternar esquema de cores de exportação",
|
"toggleExportColorScheme": "Alternar esquema de cores de exportação",
|
||||||
"share": "Compartilhar",
|
"share": "Compartilhar",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Leia o nosso blog",
|
"blog": "Leia o nosso blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Modo de visualização",
|
"viewMode": "Modo de visualização",
|
||||||
"toggleExportColorScheme": "Alternar esquema de cores de exportação",
|
"toggleExportColorScheme": "Alternar esquema de cores de exportação",
|
||||||
"share": "Partilhar",
|
"share": "Partilhar",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": "Alternar tema"
|
"toggleTheme": "Alternar tema"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Leia o nosso blog",
|
"blog": "Leia o nosso blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Mod de vizualizare",
|
"viewMode": "Mod de vizualizare",
|
||||||
"toggleExportColorScheme": "Comutare schemă de culori de export",
|
"toggleExportColorScheme": "Comutare schemă de culori de export",
|
||||||
"share": "Distribuie",
|
"share": "Distribuie",
|
||||||
|
"showStroke": "Afișare selector culoare contur",
|
||||||
|
"showBackground": "Afișare selector culoare fundal",
|
||||||
"toggleTheme": "Comutare temă"
|
"toggleTheme": "Comutare temă"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Salvare în fișier",
|
"disk_button": "Salvare în fișier",
|
||||||
"link_title": "URL partajabil",
|
"link_title": "URL partajabil",
|
||||||
"link_details": "Exportă ca URL doar în citire.",
|
"link_details": "Exportă ca URL doar în citire.",
|
||||||
"link_button": "Exportare în URL"
|
"link_button": "Exportare în URL",
|
||||||
|
"excalidrawplus_description": "Salvează scena în spațiul de lucru Excalidraw+.",
|
||||||
|
"excalidrawplus_button": "Exportare",
|
||||||
|
"excalidrawplus_exportError": "Excalidraw+ nu a putut fi exportat în acest moment..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Citește blogul nostru",
|
"blog": "Citește blogul nostru",
|
||||||
|
|||||||
+13
-8
@@ -20,10 +20,10 @@
|
|||||||
"background": "Фон",
|
"background": "Фон",
|
||||||
"fill": "Заливка",
|
"fill": "Заливка",
|
||||||
"strokeWidth": "Толщина штриха",
|
"strokeWidth": "Толщина штриха",
|
||||||
"strokeShape": "",
|
"strokeShape": "Стиль обводки",
|
||||||
"strokeShape_gel": "",
|
"strokeShape_gel": "Гелевая ручка",
|
||||||
"strokeShape_fountain": "",
|
"strokeShape_fountain": "Фонтанная ручка",
|
||||||
"strokeShape_brush": "",
|
"strokeShape_brush": "Кисть",
|
||||||
"strokeStyle": "Стиль обводки",
|
"strokeStyle": "Стиль обводки",
|
||||||
"strokeStyle_solid": "Сплошная",
|
"strokeStyle_solid": "Сплошная",
|
||||||
"strokeStyle_dashed": "Пунктирная",
|
"strokeStyle_dashed": "Пунктирная",
|
||||||
@@ -96,11 +96,13 @@
|
|||||||
"centerHorizontally": "Центрировать по горизонтали",
|
"centerHorizontally": "Центрировать по горизонтали",
|
||||||
"distributeHorizontally": "Распределить по горизонтали",
|
"distributeHorizontally": "Распределить по горизонтали",
|
||||||
"distributeVertically": "Распределить по вертикали",
|
"distributeVertically": "Распределить по вертикали",
|
||||||
"flipHorizontal": "",
|
"flipHorizontal": "Переворот по горизонтали",
|
||||||
"flipVertical": "",
|
"flipVertical": "Переворот по вертикали",
|
||||||
"viewMode": "Вид",
|
"viewMode": "Вид",
|
||||||
"toggleExportColorScheme": "Экспортировать цветовую схему",
|
"toggleExportColorScheme": "Экспортировать цветовую схему",
|
||||||
"share": "Поделиться",
|
"share": "Поделиться",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": ""
|
"toggleTheme": ""
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Сохранить в файл",
|
"disk_button": "Сохранить в файл",
|
||||||
"link_title": "Поделитесь ссылкой",
|
"link_title": "Поделитесь ссылкой",
|
||||||
"link_details": "Экспорт ссылки только для чтения.",
|
"link_details": "Экспорт ссылки только для чтения.",
|
||||||
"link_button": "Экспорт в ссылку"
|
"link_button": "Экспорт в ссылку",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "Экспорт",
|
||||||
|
"excalidrawplus_exportError": "Не удалось экспортировать в Excalidraw+ на данный момент..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Прочитайте наш блог",
|
"blog": "Прочитайте наш блог",
|
||||||
@@ -248,7 +253,7 @@
|
|||||||
},
|
},
|
||||||
"encrypted": {
|
"encrypted": {
|
||||||
"tooltip": "Ваши данные защищены сквозным (End-to-end) шифрованием. Серверы Excalidraw никогда не получат доступ к ним.",
|
"tooltip": "Ваши данные защищены сквозным (End-to-end) шифрованием. Серверы Excalidraw никогда не получат доступ к ним.",
|
||||||
"link": ""
|
"link": "Запись блога о сквозном шифровании в Excalidraw"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"angle": "Угол",
|
"angle": "Угол",
|
||||||
|
|||||||
+16
-11
@@ -42,8 +42,8 @@
|
|||||||
"fontSize": "Veľkosť písma",
|
"fontSize": "Veľkosť písma",
|
||||||
"fontFamily": "Písmo",
|
"fontFamily": "Písmo",
|
||||||
"onlySelected": "Iba vybrané",
|
"onlySelected": "Iba vybrané",
|
||||||
"withBackground": "",
|
"withBackground": "Pozadie",
|
||||||
"exportEmbedScene": "",
|
"exportEmbedScene": "Zahrnúť scénu",
|
||||||
"exportEmbedScene_details": "Údaje scény budú uložené do exportovaného PNG/SVG súboru, takže scéna z neho môže byť opäť obnovená.\nBude to mať za následok zvýšenie veľkosti súboru.",
|
"exportEmbedScene_details": "Údaje scény budú uložené do exportovaného PNG/SVG súboru, takže scéna z neho môže byť opäť obnovená.\nBude to mať za následok zvýšenie veľkosti súboru.",
|
||||||
"addWatermark": "Pridať \"Vytvorené s Excalidraw\"",
|
"addWatermark": "Pridať \"Vytvorené s Excalidraw\"",
|
||||||
"handDrawn": "Ručne písané",
|
"handDrawn": "Ručne písané",
|
||||||
@@ -101,19 +101,21 @@
|
|||||||
"viewMode": "Režim zobrazenia",
|
"viewMode": "Režim zobrazenia",
|
||||||
"toggleExportColorScheme": "Prepnúť exportovanie farebnej schémy",
|
"toggleExportColorScheme": "Prepnúť exportovanie farebnej schémy",
|
||||||
"share": "Zdieľať",
|
"share": "Zdieľať",
|
||||||
|
"showStroke": "Zobraziť výber farby pre obrys",
|
||||||
|
"showBackground": "Zobraziť výber farby pre pozadie",
|
||||||
"toggleTheme": "Prepnúť tému"
|
"toggleTheme": "Prepnúť tému"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"clearReset": "Obnoviť plátno",
|
"clearReset": "Obnoviť plátno",
|
||||||
"exportJSON": "",
|
"exportJSON": "Exportovať do súboru",
|
||||||
"exportImage": "",
|
"exportImage": "Uložiť ako obrázok",
|
||||||
"export": "Exportovať",
|
"export": "Exportovať",
|
||||||
"exportToPng": "Exportovať do PNG",
|
"exportToPng": "Exportovať do PNG",
|
||||||
"exportToSvg": "Exportovať do SVG",
|
"exportToSvg": "Exportovať do SVG",
|
||||||
"copyToClipboard": "Kopírovať do schránky",
|
"copyToClipboard": "Kopírovať do schránky",
|
||||||
"copyPngToClipboard": "Kopírovať PNG do schránky",
|
"copyPngToClipboard": "Kopírovať PNG do schránky",
|
||||||
"scale": "Mierka",
|
"scale": "Mierka",
|
||||||
"save": "",
|
"save": "Uložiť do aktuálneho súboru",
|
||||||
"saveAs": "Uložiť ako",
|
"saveAs": "Uložiť ako",
|
||||||
"load": "Nahrať",
|
"load": "Nahrať",
|
||||||
"getShareableLink": "Získať odkaz na zdieľanie",
|
"getShareableLink": "Získať odkaz na zdieľanie",
|
||||||
@@ -218,12 +220,15 @@
|
|||||||
"title": "Chyba"
|
"title": "Chyba"
|
||||||
},
|
},
|
||||||
"exportDialog": {
|
"exportDialog": {
|
||||||
"disk_title": "",
|
"disk_title": "Uložiť na disk",
|
||||||
"disk_details": "",
|
"disk_details": "Exportovať údaje scény do súboru, z ktorého môžu byť neskôr importované.",
|
||||||
"disk_button": "",
|
"disk_button": "Uložiť do súboru",
|
||||||
"link_title": "",
|
"link_title": "Odkaz na zdieľanie",
|
||||||
"link_details": "",
|
"link_details": "Exportovať ako odkaz iba na čítanie.",
|
||||||
"link_button": ""
|
"link_button": "Exportovať ako odkaz",
|
||||||
|
"excalidrawplus_description": "Uložiť scénu do vášho Excalidraw+ pracovného priestoru.",
|
||||||
|
"excalidrawplus_button": "Exportovať",
|
||||||
|
"excalidrawplus_exportError": "Nepodarilo sa vykonať export do Excalidraw+..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Prečítajte si náš blog",
|
"blog": "Prečítajte si náš blog",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Visningsläge",
|
"viewMode": "Visningsläge",
|
||||||
"toggleExportColorScheme": "Växla färgschema för export",
|
"toggleExportColorScheme": "Växla färgschema för export",
|
||||||
"share": "Dela",
|
"share": "Dela",
|
||||||
|
"showStroke": "Visa färgväljare för linjefärg",
|
||||||
|
"showBackground": "Visa färgväljare för bakgrundsfärg",
|
||||||
"toggleTheme": "Växla tema"
|
"toggleTheme": "Växla tema"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Spara till fil",
|
"disk_button": "Spara till fil",
|
||||||
"link_title": "Delbar länk",
|
"link_title": "Delbar länk",
|
||||||
"link_details": "Exportera som en skrivskyddad länk.",
|
"link_details": "Exportera som en skrivskyddad länk.",
|
||||||
"link_button": "Exportera till länk"
|
"link_button": "Exportera till länk",
|
||||||
|
"excalidrawplus_description": "Spara skissen till din Excalidraw+ arbetsyta.",
|
||||||
|
"excalidrawplus_button": "Exportera",
|
||||||
|
"excalidrawplus_exportError": "Det gick inte att exportera till Excalidraw+ just nu..."
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Läs vår blogg",
|
"blog": "Läs vår blogg",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Görünüm modu",
|
"viewMode": "Görünüm modu",
|
||||||
"toggleExportColorScheme": "Renk şemasını dışa aktar/aktarma",
|
"toggleExportColorScheme": "Renk şemasını dışa aktar/aktarma",
|
||||||
"share": "Paylaş",
|
"share": "Paylaş",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": "Temayı etkinleştir/devre dışı bırak"
|
"toggleTheme": "Temayı etkinleştir/devre dışı bırak"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "",
|
"disk_button": "",
|
||||||
"link_title": "",
|
"link_title": "",
|
||||||
"link_details": "",
|
"link_details": "",
|
||||||
"link_button": ""
|
"link_button": "",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Blog'umuzu okuyun",
|
"blog": "Blog'umuzu okuyun",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "Режим перегляду",
|
"viewMode": "Режим перегляду",
|
||||||
"toggleExportColorScheme": "Переключити колірну схему експорту",
|
"toggleExportColorScheme": "Переключити колірну схему експорту",
|
||||||
"share": "Поділитися",
|
"share": "Поділитися",
|
||||||
|
"showStroke": "",
|
||||||
|
"showBackground": "",
|
||||||
"toggleTheme": "Перемкнути тему"
|
"toggleTheme": "Перемкнути тему"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "Зберегти до файлу",
|
"disk_button": "Зберегти до файлу",
|
||||||
"link_title": "Доступ за посиланням",
|
"link_title": "Доступ за посиланням",
|
||||||
"link_details": "Експортувати як посилання тільки для читання.",
|
"link_details": "Експортувати як посилання тільки для читання.",
|
||||||
"link_button": "Експортувати у посилання"
|
"link_button": "Експортувати у посилання",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "Наш блог",
|
"blog": "Наш блог",
|
||||||
|
|||||||
+18
-13
@@ -20,7 +20,7 @@
|
|||||||
"background": "背景",
|
"background": "背景",
|
||||||
"fill": "填充",
|
"fill": "填充",
|
||||||
"strokeWidth": "描边宽度",
|
"strokeWidth": "描边宽度",
|
||||||
"strokeShape": "",
|
"strokeShape": "描边形状",
|
||||||
"strokeShape_gel": "中性笔",
|
"strokeShape_gel": "中性笔",
|
||||||
"strokeShape_fountain": "钢笔",
|
"strokeShape_fountain": "钢笔",
|
||||||
"strokeShape_brush": "墨笔",
|
"strokeShape_brush": "墨笔",
|
||||||
@@ -42,8 +42,8 @@
|
|||||||
"fontSize": "字体大小",
|
"fontSize": "字体大小",
|
||||||
"fontFamily": "字体",
|
"fontFamily": "字体",
|
||||||
"onlySelected": "仅被选中",
|
"onlySelected": "仅被选中",
|
||||||
"withBackground": "",
|
"withBackground": "背景",
|
||||||
"exportEmbedScene": "",
|
"exportEmbedScene": "包含画布数据",
|
||||||
"exportEmbedScene_details": "画布数据将被保存到导出的 PNG/SVG 文件,以便恢复。\n将会增加导出的文件大小。",
|
"exportEmbedScene_details": "画布数据将被保存到导出的 PNG/SVG 文件,以便恢复。\n将会增加导出的文件大小。",
|
||||||
"addWatermark": "添加 “使用 Excalidraw 创建” 水印",
|
"addWatermark": "添加 “使用 Excalidraw 创建” 水印",
|
||||||
"handDrawn": "手写",
|
"handDrawn": "手写",
|
||||||
@@ -101,19 +101,21 @@
|
|||||||
"viewMode": "查看模式",
|
"viewMode": "查看模式",
|
||||||
"toggleExportColorScheme": "切换导出配色方案",
|
"toggleExportColorScheme": "切换导出配色方案",
|
||||||
"share": "分享",
|
"share": "分享",
|
||||||
|
"showStroke": "显示描边颜色选择器",
|
||||||
|
"showBackground": "显示背景颜色选择器",
|
||||||
"toggleTheme": "切换主题"
|
"toggleTheme": "切换主题"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"clearReset": "重置画布",
|
"clearReset": "重置画布",
|
||||||
"exportJSON": "",
|
"exportJSON": "导出为文件",
|
||||||
"exportImage": "",
|
"exportImage": "保存为图像",
|
||||||
"export": "导出",
|
"export": "导出",
|
||||||
"exportToPng": "导出为 PNG",
|
"exportToPng": "导出为 PNG",
|
||||||
"exportToSvg": "导出为 SVG",
|
"exportToSvg": "导出为 SVG",
|
||||||
"copyToClipboard": "复制到剪贴板",
|
"copyToClipboard": "复制到剪贴板",
|
||||||
"copyPngToClipboard": "复制 PNG 到剪切板",
|
"copyPngToClipboard": "复制 PNG 到剪切板",
|
||||||
"scale": "缩放",
|
"scale": "缩放",
|
||||||
"save": "",
|
"save": "保存至当前文件",
|
||||||
"saveAs": "保存为",
|
"saveAs": "保存为",
|
||||||
"load": "载入文件",
|
"load": "载入文件",
|
||||||
"getShareableLink": "获取共享链接",
|
"getShareableLink": "获取共享链接",
|
||||||
@@ -164,7 +166,7 @@
|
|||||||
"ellipse": "椭圆",
|
"ellipse": "椭圆",
|
||||||
"arrow": "箭头",
|
"arrow": "箭头",
|
||||||
"line": "线条",
|
"line": "线条",
|
||||||
"freedraw": "",
|
"freedraw": "自由书写",
|
||||||
"text": "文字",
|
"text": "文字",
|
||||||
"library": "库",
|
"library": "库",
|
||||||
"lock": "绘制后保持所选的工具栏状态"
|
"lock": "绘制后保持所选的工具栏状态"
|
||||||
@@ -218,12 +220,15 @@
|
|||||||
"title": "错误"
|
"title": "错误"
|
||||||
},
|
},
|
||||||
"exportDialog": {
|
"exportDialog": {
|
||||||
"disk_title": "",
|
"disk_title": "保存到本地",
|
||||||
"disk_details": "",
|
"disk_details": "将画布数据导出为文件,以便以后导入",
|
||||||
"disk_button": "",
|
"disk_button": "保存为文件",
|
||||||
"link_title": "",
|
"link_title": "分享链接",
|
||||||
"link_details": "",
|
"link_details": "导出为只读链接。",
|
||||||
"link_button": ""
|
"link_button": "导出链接",
|
||||||
|
"excalidrawplus_description": "",
|
||||||
|
"excalidrawplus_button": "",
|
||||||
|
"excalidrawplus_exportError": ""
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "浏览我们的博客",
|
"blog": "浏览我们的博客",
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
"viewMode": "檢視模式",
|
"viewMode": "檢視模式",
|
||||||
"toggleExportColorScheme": "切換輸出配色",
|
"toggleExportColorScheme": "切換輸出配色",
|
||||||
"share": "共享",
|
"share": "共享",
|
||||||
|
"showStroke": "顯示線條檢色器",
|
||||||
|
"showBackground": "顯示背景檢色器",
|
||||||
"toggleTheme": "切換主題"
|
"toggleTheme": "切換主題"
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
@@ -223,7 +225,10 @@
|
|||||||
"disk_button": "儲存至檔案",
|
"disk_button": "儲存至檔案",
|
||||||
"link_title": "可共享連結",
|
"link_title": "可共享連結",
|
||||||
"link_details": "匯出為唯讀連結",
|
"link_details": "匯出為唯讀連結",
|
||||||
"link_button": "匯出為連結"
|
"link_button": "匯出為連結",
|
||||||
|
"excalidrawplus_description": "將此場景儲存至你的 Excalidraw+ 工作區",
|
||||||
|
"excalidrawplus_button": "輸出",
|
||||||
|
"excalidrawplus_exportError": "目前無法輸出至 Excalidraw+"
|
||||||
},
|
},
|
||||||
"helpDialog": {
|
"helpDialog": {
|
||||||
"blog": "閱讀部落格",
|
"blog": "閱讀部落格",
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ Please add the latest change on the top under the correct section.
|
|||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
- Expose [`FONT_FAMILY`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#FONT_FAMILY) so that consumer can use when passing `initialData.appState.currentItemFontFamily`.
|
||||||
|
|
||||||
|
- Added prop [`autoFocus`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#autoFocus) to focus the excalidraw component on page load when enabled, defaults to false [#3691](https://github.com/excalidraw/excalidraw/pull/3691).
|
||||||
|
|
||||||
|
Note: Earlier Excalidraw component was focussed by default on page load, you need to enable `autoFocus` prop to retain the same behaviour.
|
||||||
|
|
||||||
- Added prop `UIOptions.canvasActions.export.renderCustomUI` to support Custom UI rendering inside export dialog [#3666](https://github.com/excalidraw/excalidraw/pull/3666).
|
- Added prop `UIOptions.canvasActions.export.renderCustomUI` to support Custom UI rendering inside export dialog [#3666](https://github.com/excalidraw/excalidraw/pull/3666).
|
||||||
- Added prop `UIOptions.canvasActions.saveAsImage` to show/hide the **Save as image** button in the canvas actions. Defauls to `true` hence the **Save as Image** button is rendered [#3662](https://github.com/excalidraw/excalidraw/pull/3662).
|
- Added prop `UIOptions.canvasActions.saveAsImage` to show/hide the **Save as image** button in the canvas actions. Defauls to `true` hence the **Save as Image** button is rendered [#3662](https://github.com/excalidraw/excalidraw/pull/3662).
|
||||||
|
|
||||||
@@ -31,6 +37,10 @@ Please add the latest change on the top under the correct section.
|
|||||||
- `UIOptions.canvasActions.saveAsScene` is now renamed to `UiOptions.canvasActions.export.saveFileToDisk`. Defaults to `true` hence the **save file to disk** button is rendered inside the export dialog.
|
- `UIOptions.canvasActions.saveAsScene` is now renamed to `UiOptions.canvasActions.export.saveFileToDisk`. Defaults to `true` hence the **save file to disk** button is rendered inside the export dialog.
|
||||||
- `exportToBackend` is now renamed to `UIOptions.canvasActions.export.exportToBackend`. If this prop is not passed, the **shareable-link** button will not be rendered, same as before.
|
- `exportToBackend` is now renamed to `UIOptions.canvasActions.export.exportToBackend`. If this prop is not passed, the **shareable-link** button will not be rendered, same as before.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- Use excalidraw Id in elements so every element has unique id [#3696](https://github.com/excalidraw/excalidraw/pull/3696).
|
||||||
|
|
||||||
### Refactor
|
### Refactor
|
||||||
|
|
||||||
- #### BREAKING CHANGE
|
- #### BREAKING CHANGE
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ To view the full example visit :point_down:
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Since Excalidraw doesn't support server side rendering yet so you will have to make sure the component is rendered once host is mounted.
|
Since Excalidraw doesn't support server side rendering yet, you should render the component once the host is mounted.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
@@ -161,7 +161,7 @@ export default function IndexPage() {
|
|||||||
const [Comp, setComp] = useState(null);
|
const [Comp, setComp] = useState(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
import("@excalidraw/excalidraw").then((comp) => setComp(comp.default));
|
import("@excalidraw/excalidraw").then((comp) => setComp(comp.default));
|
||||||
});
|
}, []);
|
||||||
return <>{Comp && <Comp />}</>;
|
return <>{Comp && <Comp />}</>;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ To view the full example visit :point_down:
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Since Excalidraw doesn't support server side rendering yet so you will have to make sure the component is rendered once host is mounted.
|
Since Excalidraw doesn't support server side rendering yet, you should render the component once the host is mounted.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
@@ -167,7 +167,7 @@ export default function IndexPage() {
|
|||||||
const [Comp, setComp] = useState(null);
|
const [Comp, setComp] = useState(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
import("@excalidraw/excalidraw-next").then((comp) => setComp(comp.default));
|
import("@excalidraw/excalidraw-next").then((comp) => setComp(comp.default));
|
||||||
});
|
}, []);
|
||||||
return <>{Comp && <Comp />}</>;
|
return <>{Comp && <Comp />}</>;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -378,6 +378,7 @@ To view the full example visit :point_down:
|
|||||||
| [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. |
|
| [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. |
|
||||||
| [`handleKeyboardGlobally`](#handleKeyboardGlobally) | boolean | false | Indicates whether to bind the keyboard events to document. |
|
| [`handleKeyboardGlobally`](#handleKeyboardGlobally) | boolean | false | Indicates whether to bind the keyboard events to document. |
|
||||||
| [`onLibraryChange`](#onLibraryChange) | <pre>(items: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems</a>) => void | Promise<any> </pre> | | The callback if supplied is triggered when the library is updated and receives the library items. |
|
| [`onLibraryChange`](#onLibraryChange) | <pre>(items: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L200">LibraryItems</a>) => void | Promise<any> </pre> | | The callback if supplied is triggered when the library is updated and receives the library items. |
|
||||||
|
| [`autoFocus`](#autoFocus) | boolean | false | Implies whether to focus the Excalidraw component on page load |
|
||||||
|
|
||||||
### Dimensions of Excalidraw
|
### Dimensions of Excalidraw
|
||||||
|
|
||||||
@@ -644,6 +645,10 @@ It is invoked with empty items when user clears the library. You can use this ca
|
|||||||
|
|
||||||
The unique id of the excalidraw component. This can be used to identify the excalidraw component, for example importing the library items to the excalidraw component from where it was initiated when you have multiple excalidraw components rendered on the same page as shown in [multiple excalidraw demo](https://codesandbox.io/s/multiple-excalidraw-k1xx5).
|
The unique id of the excalidraw component. This can be used to identify the excalidraw component, for example importing the library items to the excalidraw component from where it was initiated when you have multiple excalidraw components rendered on the same page as shown in [multiple excalidraw demo](https://codesandbox.io/s/multiple-excalidraw-k1xx5).
|
||||||
|
|
||||||
|
### autoFocus
|
||||||
|
|
||||||
|
This prop implies whether to focus the Excalidraw component on page load. Defaults to false.
|
||||||
|
|
||||||
### Extra API's
|
### Extra API's
|
||||||
|
|
||||||
#### `getSceneVersion`
|
#### `getSceneVersion`
|
||||||
@@ -835,3 +840,21 @@ This function returns a svg with the exported elements.
|
|||||||
| exportBackground | boolean | true | Indicates whether background should be exported |
|
| exportBackground | boolean | true | Indicates whether background should be exported |
|
||||||
| viewBackgroundColor | string | #fff | The default background color |
|
| viewBackgroundColor | string | #fff | The default background color |
|
||||||
| exportWithDarkMode | boolean | false | Indicates whether to export with dark mode |
|
| exportWithDarkMode | boolean | false | Indicates whether to export with dark mode |
|
||||||
|
|
||||||
|
### FONT_FAMILY
|
||||||
|
|
||||||
|
**_Signature_**
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { FONT_FAMILY } from "./constants";
|
||||||
|
```
|
||||||
|
|
||||||
|
`FONT_FAMILY` contains all the font families used in `Excalidraw` as explained below
|
||||||
|
|
||||||
|
| Font Family | Description |
|
||||||
|
| ----------- | -------------------- |
|
||||||
|
| Virgil | The handwritten font |
|
||||||
|
| Helvetica | The Normal Font |
|
||||||
|
| Cacadia | The Code Font |
|
||||||
|
|
||||||
|
Defaults to `FONT_FAMILY.Virgil` unless passed in `initialData.appState.currentItemFontFamily`.
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
|
|||||||
detectScroll = true,
|
detectScroll = true,
|
||||||
handleKeyboardGlobally = false,
|
handleKeyboardGlobally = false,
|
||||||
onLibraryChange,
|
onLibraryChange,
|
||||||
|
autoFocus = false,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const canvasActions = props.UIOptions?.canvasActions;
|
const canvasActions = props.UIOptions?.canvasActions;
|
||||||
@@ -92,6 +93,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
|
|||||||
detectScroll={detectScroll}
|
detectScroll={detectScroll}
|
||||||
handleKeyboardGlobally={handleKeyboardGlobally}
|
handleKeyboardGlobally={handleKeyboardGlobally}
|
||||||
onLibraryChange={onLibraryChange}
|
onLibraryChange={onLibraryChange}
|
||||||
|
autoFocus={autoFocus}
|
||||||
/>
|
/>
|
||||||
</InitializeApp>
|
</InitializeApp>
|
||||||
);
|
);
|
||||||
@@ -178,3 +180,4 @@ export {
|
|||||||
exportToSvg,
|
exportToSvg,
|
||||||
} from "../../packages/utils";
|
} from "../../packages/utils";
|
||||||
export { serializeAsJSON } from "../../data/json";
|
export { serializeAsJSON } from "../../data/json";
|
||||||
|
export { FONT_FAMILY } from "../../constants";
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
"@babel/preset-env": "7.14.2",
|
"@babel/preset-env": "7.14.2",
|
||||||
"@babel/preset-react": "7.13.13",
|
"@babel/preset-react": "7.13.13",
|
||||||
"@babel/preset-typescript": "7.13.0",
|
"@babel/preset-typescript": "7.13.0",
|
||||||
"autoprefixer": "10.2.5",
|
"autoprefixer": "10.2.6",
|
||||||
"babel-loader": "8.2.2",
|
"babel-loader": "8.2.2",
|
||||||
"babel-plugin-transform-class-properties": "6.24.1",
|
"babel-plugin-transform-class-properties": "6.24.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
@@ -66,9 +66,9 @@
|
|||||||
"postcss-loader": "5.3.0",
|
"postcss-loader": "5.3.0",
|
||||||
"sass-loader": "11.1.1",
|
"sass-loader": "11.1.1",
|
||||||
"terser-webpack-plugin": "5.1.2",
|
"terser-webpack-plugin": "5.1.2",
|
||||||
"ts-loader": "8.1.0",
|
"ts-loader": "9.2.3",
|
||||||
"typescript": "4.2.4",
|
"typescript": "4.3.2",
|
||||||
"webpack": "5.37.1",
|
"webpack": "5.38.1",
|
||||||
"webpack-bundle-analyzer": "4.4.1",
|
"webpack-bundle-analyzer": "4.4.1",
|
||||||
"webpack-cli": "4.7.0"
|
"webpack-cli": "4.7.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1240,15 +1240,15 @@ ansi-styles@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^2.0.1"
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
autoprefixer@10.2.5:
|
autoprefixer@10.2.6:
|
||||||
version "10.2.5"
|
version "10.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.5.tgz#096a0337dbc96c0873526d7fef5de4428d05382d"
|
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.6.tgz#aadd9ec34e1c98d403e01950038049f0eb252949"
|
||||||
integrity sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA==
|
integrity sha512-8lChSmdU6dCNMCQopIf4Pe5kipkAGj/fvTMslCsih0uHpOrXOPUEVOmYMMqmw3cekQkSD7EhIeuYl5y0BLdKqg==
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist "^4.16.3"
|
browserslist "^4.16.6"
|
||||||
caniuse-lite "^1.0.30001196"
|
caniuse-lite "^1.0.30001230"
|
||||||
colorette "^1.2.2"
|
colorette "^1.2.2"
|
||||||
fraction.js "^4.0.13"
|
fraction.js "^4.1.1"
|
||||||
normalize-range "^0.1.2"
|
normalize-range "^0.1.2"
|
||||||
postcss-value-parser "^4.1.0"
|
postcss-value-parser "^4.1.0"
|
||||||
|
|
||||||
@@ -1404,7 +1404,7 @@ braces@^3.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
fill-range "^7.0.1"
|
fill-range "^7.0.1"
|
||||||
|
|
||||||
browserslist@^4.14.5, browserslist@^4.16.3:
|
browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.16.6:
|
||||||
version "4.16.6"
|
version "4.16.6"
|
||||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
|
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
|
||||||
integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
|
integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
|
||||||
@@ -1433,7 +1433,7 @@ callsites@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||||
|
|
||||||
caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001219:
|
caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001230:
|
||||||
version "1.0.30001230"
|
version "1.0.30001230"
|
||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71"
|
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71"
|
||||||
integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==
|
integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==
|
||||||
@@ -1551,11 +1551,6 @@ core-js@^2.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||||
|
|
||||||
core-util-is@~1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
|
||||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
|
||||||
|
|
||||||
cosmiconfig@^7.0.0:
|
cosmiconfig@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3"
|
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3"
|
||||||
@@ -1640,19 +1635,10 @@ emojis-list@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
|
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
|
||||||
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
|
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
|
||||||
|
|
||||||
enhanced-resolve@^4.0.0:
|
enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.0:
|
||||||
version "4.5.0"
|
version "5.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec"
|
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b"
|
||||||
integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==
|
integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==
|
||||||
dependencies:
|
|
||||||
graceful-fs "^4.1.2"
|
|
||||||
memory-fs "^0.5.0"
|
|
||||||
tapable "^1.0.0"
|
|
||||||
|
|
||||||
enhanced-resolve@^5.8.0:
|
|
||||||
version "5.8.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz#d9deae58f9d3773b6a111a5a46831da5be5c9ac0"
|
|
||||||
integrity sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
graceful-fs "^4.2.4"
|
graceful-fs "^4.2.4"
|
||||||
tapable "^2.2.0"
|
tapable "^2.2.0"
|
||||||
@@ -1662,13 +1648,6 @@ envinfo@^7.7.3:
|
|||||||
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.4.tgz#c6311cdd38a0e86808c1c9343f667e4267c4a320"
|
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.4.tgz#c6311cdd38a0e86808c1c9343f667e4267c4a320"
|
||||||
integrity sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==
|
integrity sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==
|
||||||
|
|
||||||
errno@^0.1.3:
|
|
||||||
version "0.1.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
|
|
||||||
integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
|
|
||||||
dependencies:
|
|
||||||
prr "~1.0.1"
|
|
||||||
|
|
||||||
error-ex@^1.3.1:
|
error-ex@^1.3.1:
|
||||||
version "1.3.2"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||||
@@ -1691,7 +1670,7 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
|||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||||
|
|
||||||
eslint-scope@^5.1.1:
|
eslint-scope@5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||||
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
|
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
|
||||||
@@ -1788,10 +1767,10 @@ find-up@^4.0.0:
|
|||||||
locate-path "^5.0.0"
|
locate-path "^5.0.0"
|
||||||
path-exists "^4.0.0"
|
path-exists "^4.0.0"
|
||||||
|
|
||||||
fraction.js@^4.0.13:
|
fraction.js@^4.1.1:
|
||||||
version "4.0.13"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe"
|
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.1.tgz#ac4e520473dae67012d618aab91eda09bcb400ff"
|
||||||
integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==
|
integrity sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg==
|
||||||
|
|
||||||
function-bind@^1.1.1:
|
function-bind@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
@@ -1904,11 +1883,6 @@ indexes-of@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
|
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
|
||||||
integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
|
integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
|
||||||
|
|
||||||
inherits@~2.0.3:
|
|
||||||
version "2.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
|
||||||
|
|
||||||
interpret@^2.2.0:
|
interpret@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
|
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
|
||||||
@@ -1950,11 +1924,6 @@ is-stream@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
|
||||||
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
|
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
|
||||||
|
|
||||||
isarray@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
|
||||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
|
||||||
|
|
||||||
isexe@^2.0.0:
|
isexe@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||||
@@ -2099,14 +2068,6 @@ make-dir@^3.0.2, make-dir@^3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
semver "^6.0.0"
|
semver "^6.0.0"
|
||||||
|
|
||||||
memory-fs@^0.5.0:
|
|
||||||
version "0.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c"
|
|
||||||
integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==
|
|
||||||
dependencies:
|
|
||||||
errno "^0.1.3"
|
|
||||||
readable-stream "^2.0.1"
|
|
||||||
|
|
||||||
merge-stream@^2.0.0:
|
merge-stream@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||||
@@ -2356,16 +2317,6 @@ postcss@^8.2.15:
|
|||||||
nanoid "^3.1.23"
|
nanoid "^3.1.23"
|
||||||
source-map-js "^0.6.2"
|
source-map-js "^0.6.2"
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
|
||||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
|
||||||
|
|
||||||
prr@~1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
|
|
||||||
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
|
|
||||||
|
|
||||||
punycode@^2.1.0:
|
punycode@^2.1.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
@@ -2378,19 +2329,6 @@ randombytes@^2.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.1.0"
|
safe-buffer "^5.1.0"
|
||||||
|
|
||||||
readable-stream@^2.0.1:
|
|
||||||
version "2.3.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
|
||||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
|
||||||
dependencies:
|
|
||||||
core-util-is "~1.0.0"
|
|
||||||
inherits "~2.0.3"
|
|
||||||
isarray "~1.0.0"
|
|
||||||
process-nextick-args "~2.0.0"
|
|
||||||
safe-buffer "~5.1.1"
|
|
||||||
string_decoder "~1.1.1"
|
|
||||||
util-deprecate "~1.0.1"
|
|
||||||
|
|
||||||
rechoir@^0.7.0:
|
rechoir@^0.7.0:
|
||||||
version "0.7.0"
|
version "0.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca"
|
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca"
|
||||||
@@ -2481,7 +2419,7 @@ safe-buffer@^5.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||||
|
|
||||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
safe-buffer@~5.1.1:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||||
@@ -2602,13 +2540,6 @@ source-map@~0.7.2:
|
|||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
||||||
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
||||||
|
|
||||||
string_decoder@~1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
|
||||||
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "~5.1.0"
|
|
||||||
|
|
||||||
strip-ansi@^3.0.0:
|
strip-ansi@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||||
@@ -2640,11 +2571,6 @@ supports-color@^7.0.0, supports-color@^7.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^4.0.0"
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
tapable@^1.0.0:
|
|
||||||
version "1.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
|
||||||
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
|
||||||
|
|
||||||
tapable@^2.1.1, tapable@^2.2.0:
|
tapable@^2.1.1, tapable@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
|
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
|
||||||
@@ -2693,14 +2619,13 @@ totalist@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"
|
resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"
|
||||||
integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==
|
integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==
|
||||||
|
|
||||||
ts-loader@8.1.0:
|
ts-loader@9.2.3:
|
||||||
version "8.1.0"
|
version "9.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.1.0.tgz#d6292487df279c7cc79b6d3b70bb9d31682b693e"
|
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.3.tgz#dc3b6362a4d4382493cd4f138d345f419656de68"
|
||||||
integrity sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==
|
integrity sha512-sEyWiU3JMHBL55CIeC4iqJQadI0U70A5af0kvgbNLHVNz2ACztQg0j/9x10bjjIht8WfFYLKfn4L6tkZ+pu+8Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk "^4.1.0"
|
chalk "^4.1.0"
|
||||||
enhanced-resolve "^4.0.0"
|
enhanced-resolve "^5.0.0"
|
||||||
loader-utils "^2.0.0"
|
|
||||||
micromatch "^4.0.0"
|
micromatch "^4.0.0"
|
||||||
semver "^7.3.4"
|
semver "^7.3.4"
|
||||||
|
|
||||||
@@ -2709,10 +2634,10 @@ tslib@^1.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
typescript@4.2.4:
|
typescript@4.3.2:
|
||||||
version "4.2.4"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805"
|
||||||
integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==
|
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==
|
||||||
|
|
||||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
@@ -2749,7 +2674,7 @@ uri-js@^4.2.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.0"
|
punycode "^2.1.0"
|
||||||
|
|
||||||
util-deprecate@^1.0.2, util-deprecate@~1.0.1:
|
util-deprecate@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||||
@@ -2759,10 +2684,10 @@ v8-compile-cache@^2.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132"
|
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132"
|
||||||
integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==
|
integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==
|
||||||
|
|
||||||
watchpack@^2.0.0:
|
watchpack@^2.2.0:
|
||||||
version "2.1.1"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7"
|
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce"
|
||||||
integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==
|
integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==
|
||||||
dependencies:
|
dependencies:
|
||||||
glob-to-regexp "^0.4.1"
|
glob-to-regexp "^0.4.1"
|
||||||
graceful-fs "^4.1.2"
|
graceful-fs "^4.1.2"
|
||||||
@@ -2817,18 +2742,18 @@ webpack-sources@^1.1.0:
|
|||||||
source-list-map "^2.0.0"
|
source-list-map "^2.0.0"
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
webpack-sources@^2.1.1:
|
webpack-sources@^2.3.0:
|
||||||
version "2.2.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac"
|
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.0.tgz#9ed2de69b25143a4c18847586ad9eccb19278cfa"
|
||||||
integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==
|
integrity sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
source-list-map "^2.0.1"
|
source-list-map "^2.0.1"
|
||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
|
|
||||||
webpack@5.37.1:
|
webpack@5.38.1:
|
||||||
version "5.37.1"
|
version "5.38.1"
|
||||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.37.1.tgz#2deb5acd350583c1ab9338471f323381b0b0c14b"
|
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.38.1.tgz#5224c7f24c18e729268d3e3bc97240d6e880258e"
|
||||||
integrity sha512-btZjGy/hSjCAAVHw+cKG+L0M+rstlyxbO2C+BOTaQ5/XAnxkDrP5sVbqWhXgo4pL3X2dcOib6rqCP20Zr9PLow==
|
integrity sha512-OqRmYD1OJbHZph6RUMD93GcCZy4Z4wC0ele4FXyYF0J6AxO1vOSuIlU1hkS/lDlR9CDYBz64MZRmdbdnFFoT2g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/eslint-scope" "^3.7.0"
|
"@types/eslint-scope" "^3.7.0"
|
||||||
"@types/estree" "^0.0.47"
|
"@types/estree" "^0.0.47"
|
||||||
@@ -2840,7 +2765,7 @@ webpack@5.37.1:
|
|||||||
chrome-trace-event "^1.0.2"
|
chrome-trace-event "^1.0.2"
|
||||||
enhanced-resolve "^5.8.0"
|
enhanced-resolve "^5.8.0"
|
||||||
es-module-lexer "^0.4.0"
|
es-module-lexer "^0.4.0"
|
||||||
eslint-scope "^5.1.1"
|
eslint-scope "5.1.1"
|
||||||
events "^3.2.0"
|
events "^3.2.0"
|
||||||
glob-to-regexp "^0.4.1"
|
glob-to-regexp "^0.4.1"
|
||||||
graceful-fs "^4.2.4"
|
graceful-fs "^4.2.4"
|
||||||
@@ -2851,8 +2776,8 @@ webpack@5.37.1:
|
|||||||
schema-utils "^3.0.0"
|
schema-utils "^3.0.0"
|
||||||
tapable "^2.1.1"
|
tapable "^2.1.1"
|
||||||
terser-webpack-plugin "^5.1.1"
|
terser-webpack-plugin "^5.1.1"
|
||||||
watchpack "^2.0.0"
|
watchpack "^2.2.0"
|
||||||
webpack-sources "^2.1.1"
|
webpack-sources "^2.3.0"
|
||||||
|
|
||||||
which@^2.0.1:
|
which@^2.0.1:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
@@ -2867,9 +2792,9 @@ wildcard@^2.0.0:
|
|||||||
integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
|
integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==
|
||||||
|
|
||||||
ws@^7.3.1:
|
ws@^7.3.1:
|
||||||
version "7.4.3"
|
version "7.4.6"
|
||||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.3.tgz#1f9643de34a543b8edb124bdcbc457ae55a6e5cd"
|
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
|
||||||
integrity sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==
|
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
|
||||||
|
|
||||||
yallist@^4.0.0:
|
yallist@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
|
|||||||
@@ -36,10 +36,10 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.14.3",
|
"@babel/core": "7.14.3",
|
||||||
"@babel/plugin-transform-arrow-functions": "7.13.0",
|
"@babel/plugin-transform-arrow-functions": "7.13.0",
|
||||||
"@babel/plugin-transform-async-to-generator": "7.13.0",
|
"@babel/plugin-transform-async-to-generator": "7.14.5",
|
||||||
"@babel/plugin-transform-runtime": "^7.12.10",
|
"@babel/plugin-transform-runtime": "^7.12.10",
|
||||||
"@babel/plugin-transform-typescript": "7.14.3",
|
"@babel/plugin-transform-typescript": "7.14.5",
|
||||||
"@babel/preset-env": "7.14.1",
|
"@babel/preset-env": "7.14.5",
|
||||||
"@babel/preset-typescript": "7.13.0",
|
"@babel/preset-typescript": "7.13.0",
|
||||||
"babel-loader": "8.2.2",
|
"babel-loader": "8.2.2",
|
||||||
"babel-plugin-transform-class-properties": "6.24.1",
|
"babel-plugin-transform-class-properties": "6.24.1",
|
||||||
@@ -47,8 +47,8 @@
|
|||||||
"css-loader": "5.2.6",
|
"css-loader": "5.2.6",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"sass-loader": "11.1.1",
|
"sass-loader": "11.1.1",
|
||||||
"ts-loader": "8.1.0",
|
"ts-loader": "9.2.3",
|
||||||
"webpack": "5.37.1",
|
"webpack": "5.38.1",
|
||||||
"webpack-bundle-analyzer": "4.4.2",
|
"webpack-bundle-analyzer": "4.4.2",
|
||||||
"webpack-cli": "4.7.0"
|
"webpack-cli": "4.7.0"
|
||||||
},
|
},
|
||||||
|
|||||||
+632
-626
File diff suppressed because it is too large
Load Diff
+16
-21
@@ -4,7 +4,7 @@ import { getCommonBounds } from "../element/bounds";
|
|||||||
import { renderScene, renderSceneToSvg } from "../renderer/renderScene";
|
import { renderScene, renderSceneToSvg } from "../renderer/renderScene";
|
||||||
import { distance, SVG_NS } from "../utils";
|
import { distance, SVG_NS } from "../utils";
|
||||||
import { AppState } from "../types";
|
import { AppState } from "../types";
|
||||||
import { THEME_FILTER } from "../constants";
|
import { DEFAULT_EXPORT_PADDING, THEME_FILTER } from "../constants";
|
||||||
import { getDefaultAppState } from "../appState";
|
import { getDefaultAppState } from "../appState";
|
||||||
|
|
||||||
export const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;
|
export const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;
|
||||||
@@ -14,39 +14,34 @@ export const exportToCanvas = (
|
|||||||
appState: AppState,
|
appState: AppState,
|
||||||
{
|
{
|
||||||
exportBackground,
|
exportBackground,
|
||||||
exportPadding = 10,
|
exportPadding = DEFAULT_EXPORT_PADDING,
|
||||||
viewBackgroundColor,
|
viewBackgroundColor,
|
||||||
scale = 1,
|
|
||||||
}: {
|
}: {
|
||||||
exportBackground: boolean;
|
exportBackground: boolean;
|
||||||
exportPadding?: number;
|
exportPadding?: number;
|
||||||
scale?: number;
|
|
||||||
viewBackgroundColor: string;
|
viewBackgroundColor: string;
|
||||||
},
|
},
|
||||||
createCanvas: (
|
createCanvas: (
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
) => { canvas: HTMLCanvasElement; scale: number } = (width, height) => {
|
) => { canvas: HTMLCanvasElement; scale: number } = (width, height) => {
|
||||||
const tempCanvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
tempCanvas.width = width * scale;
|
canvas.width = width * appState.exportScale;
|
||||||
tempCanvas.height = height * scale;
|
canvas.height = height * appState.exportScale;
|
||||||
return { canvas: tempCanvas, scale };
|
return { canvas, scale: appState.exportScale };
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);
|
const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);
|
||||||
|
|
||||||
const { canvas: tempCanvas, scale: newScale = scale } = createCanvas(
|
const { canvas, scale = 1 } = createCanvas(width, height);
|
||||||
width,
|
|
||||||
height,
|
|
||||||
);
|
|
||||||
|
|
||||||
renderScene(
|
renderScene(
|
||||||
elements,
|
elements,
|
||||||
appState,
|
appState,
|
||||||
null,
|
null,
|
||||||
newScale,
|
scale,
|
||||||
rough.canvas(tempCanvas),
|
rough.canvas(canvas),
|
||||||
tempCanvas,
|
canvas,
|
||||||
{
|
{
|
||||||
viewBackgroundColor: exportBackground ? viewBackgroundColor : null,
|
viewBackgroundColor: exportBackground ? viewBackgroundColor : null,
|
||||||
exportWithDarkMode: appState.exportWithDarkMode,
|
exportWithDarkMode: appState.exportWithDarkMode,
|
||||||
@@ -67,22 +62,22 @@ export const exportToCanvas = (
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return tempCanvas;
|
return canvas;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const exportToSvg = (
|
export const exportToSvg = (
|
||||||
elements: readonly NonDeletedExcalidrawElement[],
|
elements: readonly NonDeletedExcalidrawElement[],
|
||||||
{
|
{
|
||||||
exportBackground,
|
exportBackground,
|
||||||
exportPadding = 10,
|
exportPadding = DEFAULT_EXPORT_PADDING,
|
||||||
viewBackgroundColor,
|
viewBackgroundColor,
|
||||||
exportWithDarkMode,
|
exportWithDarkMode,
|
||||||
scale = 1,
|
exportScale = 1,
|
||||||
metadata = "",
|
metadata = "",
|
||||||
}: {
|
}: {
|
||||||
exportBackground: boolean;
|
exportBackground: boolean;
|
||||||
exportPadding?: number;
|
exportPadding?: number;
|
||||||
scale?: number;
|
exportScale?: number;
|
||||||
viewBackgroundColor: string;
|
viewBackgroundColor: string;
|
||||||
exportWithDarkMode?: boolean;
|
exportWithDarkMode?: boolean;
|
||||||
metadata?: string;
|
metadata?: string;
|
||||||
@@ -95,8 +90,8 @@ export const exportToSvg = (
|
|||||||
svgRoot.setAttribute("version", "1.1");
|
svgRoot.setAttribute("version", "1.1");
|
||||||
svgRoot.setAttribute("xmlns", SVG_NS);
|
svgRoot.setAttribute("xmlns", SVG_NS);
|
||||||
svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
||||||
svgRoot.setAttribute("width", `${width * scale}`);
|
svgRoot.setAttribute("width", `${width * exportScale}`);
|
||||||
svgRoot.setAttribute("height", `${height * scale}`);
|
svgRoot.setAttribute("height", `${height * exportScale}`);
|
||||||
if (exportWithDarkMode) {
|
if (exportWithDarkMode) {
|
||||||
svgRoot.setAttribute("filter", THEME_FILTER);
|
svgRoot.setAttribute("filter", THEME_FILTER);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import "@testing-library/jest-dom";
|
import "@testing-library/jest-dom";
|
||||||
import "jest-canvas-mock";
|
import "jest-canvas-mock";
|
||||||
|
|
||||||
|
jest.mock("nanoid", () => {
|
||||||
|
return {
|
||||||
|
nanoid: jest.fn(() => "test-id"),
|
||||||
|
};
|
||||||
|
});
|
||||||
// ReactDOM is located inside index.tsx file
|
// ReactDOM is located inside index.tsx file
|
||||||
// as a result, we need a place for it to render into
|
// as a result, we need a place for it to render into
|
||||||
const element = document.createElement("div");
|
const element = document.createElement("div");
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -43,6 +44,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -193,6 +195,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -208,6 +211,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -504,6 +508,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -519,6 +524,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -815,6 +821,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -830,6 +837,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -980,6 +988,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -995,6 +1004,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -1178,6 +1188,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -1193,6 +1204,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -1429,6 +1441,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -1444,6 +1457,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -1758,6 +1772,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -1772,7 +1787,8 @@ Object {
|
|||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": "backgroundColorPicker",
|
"openMenu": null,
|
||||||
|
"openPopup": "backgroundColorPicker",
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -2489,6 +2505,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -2504,6 +2521,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -2800,6 +2818,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -2815,6 +2834,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -3111,6 +3131,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -3126,6 +3147,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -3496,6 +3518,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -3511,6 +3534,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -3753,6 +3777,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -3768,6 +3793,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -4085,6 +4111,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -4100,6 +4127,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -4185,6 +4213,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -4200,6 +4229,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -4263,6 +4293,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -4278,6 +4309,7 @@ Object {
|
|||||||
"offsetLeft": 20,
|
"offsetLeft": 20,
|
||||||
"offsetTop": 10,
|
"offsetTop": 10,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -43,6 +44,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -495,6 +497,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -510,6 +513,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -968,6 +972,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -983,6 +988,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -1756,6 +1762,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -1771,6 +1778,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -1962,6 +1970,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -1977,6 +1986,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -2426,6 +2436,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -2441,6 +2452,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -2681,6 +2693,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -2696,6 +2709,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -2846,6 +2860,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -2861,6 +2876,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -3293,6 +3309,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -3307,7 +3324,8 @@ Object {
|
|||||||
"name": "Untitled-201933152653",
|
"name": "Untitled-201933152653",
|
||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": "strokeColorPicker",
|
"openMenu": null,
|
||||||
|
"openPopup": "strokeColorPicker",
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -3532,6 +3550,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -3547,6 +3566,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -3738,6 +3758,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -3753,6 +3774,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -3985,6 +4007,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -4000,6 +4023,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -4239,6 +4263,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -4254,6 +4279,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -4625,6 +4651,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -4640,6 +4667,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -4922,6 +4950,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -4937,6 +4966,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -5197,6 +5227,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -5212,6 +5243,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -5406,6 +5438,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -5421,6 +5454,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -5571,6 +5605,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -5586,6 +5621,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -6030,6 +6066,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -6045,6 +6082,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -6351,6 +6389,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -6366,6 +6405,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -8407,6 +8447,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -8422,6 +8463,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -8772,6 +8814,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -8787,6 +8830,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -9027,6 +9071,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -9042,6 +9087,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -9246,6 +9292,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -9261,6 +9308,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -9528,6 +9576,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -9543,6 +9592,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -9693,6 +9743,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -9708,6 +9759,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -9858,6 +9910,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -9873,6 +9926,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -10023,6 +10077,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -10038,6 +10093,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -10218,6 +10274,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -10233,6 +10290,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -10413,6 +10471,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -10428,6 +10487,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -10620,6 +10680,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -10635,6 +10696,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -10815,6 +10877,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -10830,6 +10893,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -10980,6 +11044,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -10995,6 +11060,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -11145,6 +11211,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -11160,6 +11227,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -11340,6 +11408,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -11355,6 +11424,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -11505,6 +11575,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -11520,6 +11591,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -11712,6 +11784,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -11727,6 +11800,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -12437,6 +12511,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -12452,6 +12527,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -12692,6 +12768,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -12707,6 +12784,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -12794,6 +12872,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -12809,6 +12888,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -12894,6 +12974,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -12909,6 +12990,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -13062,6 +13144,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -13077,6 +13160,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -13386,6 +13470,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -13401,6 +13486,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -13588,6 +13674,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -13603,6 +13690,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -14422,6 +14510,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -14437,6 +14526,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -14522,6 +14612,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -14537,6 +14628,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -15289,6 +15381,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -15304,6 +15397,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -15697,6 +15791,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -15712,6 +15807,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -15972,6 +16068,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -15987,6 +16084,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -16074,6 +16172,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -16089,6 +16188,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -16576,6 +16676,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -16591,6 +16692,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
@@ -16676,6 +16778,7 @@ Object {
|
|||||||
"errorMessage": null,
|
"errorMessage": null,
|
||||||
"exportBackground": true,
|
"exportBackground": true,
|
||||||
"exportEmbedScene": false,
|
"exportEmbedScene": false,
|
||||||
|
"exportScale": 1,
|
||||||
"exportWithDarkMode": false,
|
"exportWithDarkMode": false,
|
||||||
"fileHandle": null,
|
"fileHandle": null,
|
||||||
"gridSize": null,
|
"gridSize": null,
|
||||||
@@ -16691,6 +16794,7 @@ Object {
|
|||||||
"offsetLeft": 0,
|
"offsetLeft": 0,
|
||||||
"offsetTop": 0,
|
"offsetTop": 0,
|
||||||
"openMenu": null,
|
"openMenu": null,
|
||||||
|
"openPopup": null,
|
||||||
"pasteDialog": Object {
|
"pasteDialog": Object {
|
||||||
"data": null,
|
"data": null,
|
||||||
"shown": false,
|
"shown": false,
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`restoreElements should restore arrow element correctly 1`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"endArrowhead": null,
|
||||||
|
"endBinding": null,
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 0,
|
||||||
|
"id": "id-arrow01",
|
||||||
|
"isDeleted": false,
|
||||||
|
"lastCommittedPoint": null,
|
||||||
|
"opacity": 100,
|
||||||
|
"points": Array [
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"startArrowhead": null,
|
||||||
|
"startBinding": null,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"type": "arrow",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"width": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore correctly with rectangle, ellipse and diamond elements 1`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "blue",
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"fillStyle": "cross-hatch",
|
||||||
|
"groupIds": Array [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
],
|
||||||
|
"height": 200,
|
||||||
|
"id": "1",
|
||||||
|
"isDeleted": false,
|
||||||
|
"opacity": 10,
|
||||||
|
"roughness": 2,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"strokeColor": "red",
|
||||||
|
"strokeSharpness": "round",
|
||||||
|
"strokeStyle": "dashed",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"type": "rectangle",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"width": 100,
|
||||||
|
"x": 10,
|
||||||
|
"y": 20,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore correctly with rectangle, ellipse and diamond elements 2`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "blue",
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"fillStyle": "cross-hatch",
|
||||||
|
"groupIds": Array [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
],
|
||||||
|
"height": 200,
|
||||||
|
"id": "2",
|
||||||
|
"isDeleted": false,
|
||||||
|
"opacity": 10,
|
||||||
|
"roughness": 2,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"strokeColor": "red",
|
||||||
|
"strokeSharpness": "round",
|
||||||
|
"strokeStyle": "dashed",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"type": "ellipse",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"width": 100,
|
||||||
|
"x": 10,
|
||||||
|
"y": 20,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore correctly with rectangle, ellipse and diamond elements 3`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "blue",
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"fillStyle": "cross-hatch",
|
||||||
|
"groupIds": Array [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
],
|
||||||
|
"height": 200,
|
||||||
|
"id": "3",
|
||||||
|
"isDeleted": false,
|
||||||
|
"opacity": 10,
|
||||||
|
"roughness": 2,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"strokeColor": "red",
|
||||||
|
"strokeSharpness": "round",
|
||||||
|
"strokeStyle": "dashed",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"type": "diamond",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"width": 100,
|
||||||
|
"x": 10,
|
||||||
|
"y": 20,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore freedraw element correctly 1`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 0,
|
||||||
|
"id": "id-freedraw01",
|
||||||
|
"isDeleted": false,
|
||||||
|
"lastCommittedPoint": null,
|
||||||
|
"opacity": 100,
|
||||||
|
"points": Array [],
|
||||||
|
"pressures": Array [],
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"simulatePressure": true,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"type": "freedraw",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"width": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore line and draw elements correctly 1`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"endArrowhead": null,
|
||||||
|
"endBinding": null,
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 0,
|
||||||
|
"id": "id-line01",
|
||||||
|
"isDeleted": false,
|
||||||
|
"lastCommittedPoint": null,
|
||||||
|
"opacity": 100,
|
||||||
|
"points": Array [
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"startArrowhead": null,
|
||||||
|
"startBinding": null,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"type": "line",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"width": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore line and draw elements correctly 2`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"endArrowhead": null,
|
||||||
|
"endBinding": null,
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 0,
|
||||||
|
"id": "id-draw01",
|
||||||
|
"isDeleted": false,
|
||||||
|
"lastCommittedPoint": null,
|
||||||
|
"opacity": 100,
|
||||||
|
"points": Array [
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
Array [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"startArrowhead": null,
|
||||||
|
"startBinding": null,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"type": "line",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"width": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore text element correctly passing value for each attribute 1`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"baseline": 0,
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"fontFamily": 1,
|
||||||
|
"fontSize": 14,
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 0,
|
||||||
|
"id": "id-text01",
|
||||||
|
"isDeleted": false,
|
||||||
|
"opacity": 100,
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"text": "text",
|
||||||
|
"textAlign": "center",
|
||||||
|
"type": "text",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"verticalAlign": "middle",
|
||||||
|
"width": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`restoreElements should restore text element correctly with unknown font family, null text and undefined alignment 1`] = `
|
||||||
|
Object {
|
||||||
|
"angle": 0,
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"baseline": 0,
|
||||||
|
"boundElementIds": Array [],
|
||||||
|
"fillStyle": "hachure",
|
||||||
|
"fontFamily": 1,
|
||||||
|
"fontSize": 10,
|
||||||
|
"groupIds": Array [],
|
||||||
|
"height": 0,
|
||||||
|
"id": "id-text01",
|
||||||
|
"isDeleted": false,
|
||||||
|
"opacity": 100,
|
||||||
|
"roughness": 1,
|
||||||
|
"seed": Any<Number>,
|
||||||
|
"strokeColor": "#000000",
|
||||||
|
"strokeSharpness": "sharp",
|
||||||
|
"strokeStyle": "solid",
|
||||||
|
"strokeWidth": 1,
|
||||||
|
"text": "",
|
||||||
|
"textAlign": "left",
|
||||||
|
"type": "text",
|
||||||
|
"version": 1,
|
||||||
|
"versionNonce": 0,
|
||||||
|
"verticalAlign": "top",
|
||||||
|
"width": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user