Compare commits

..

1 Commits

Author SHA1 Message Date
c96b0404ba feat: close mobile canvas menu on canvas pointerdown 2021-05-25 22:51:31 +02:00
90 changed files with 1161 additions and 2474 deletions

View File

@ -117,7 +117,6 @@
width: 100%;
height: 100%;
overflow: hidden;
}
.visually-hidden {

View File

@ -38,7 +38,6 @@ const crowdinMap = {
"zh-CN": "en-zhcn",
"zh-TW": "en-zhtw",
"lv-LV": "en-lv",
"cs-CZ": "cs-cz",
};
const flags = {
@ -77,7 +76,6 @@ const flags = {
"zh-CN": "🇨🇳",
"zh-TW": "🇹🇼",
"lv-LV": "🇱🇻",
"cs-CZ": "🇨🇿",
};
const languages = {
@ -116,7 +114,6 @@ const languages = {
"zh-CN": "简体中文",
"zh-TW": "繁體中文",
"lv-LV": "Latviešu",
"cs-CZ": "Česky",
};
const percentages = fs.readFileSync(

View File

@ -22,8 +22,8 @@ export const actionChangeViewBackgroundColor = register({
name: "changeViewBackgroundColor",
perform: (_, appState, value) => {
return {
appState: { ...appState, ...value },
commitToHistory: !!value.viewBackgroundColor,
appState: { ...appState, viewBackgroundColor: value },
commitToHistory: true,
};
},
PanelComponent: ({ appState, updateData }) => {
@ -33,11 +33,7 @@ export const actionChangeViewBackgroundColor = register({
label={t("labels.canvasBackground")}
type="canvasBackground"
color={appState.viewBackgroundColor}
onChange={(color) => updateData({ viewBackgroundColor: color })}
isActive={appState.openMenu === "canvasColorPicker"}
setActive={(active) =>
updateData({ openMenu: active ? "canvasColorPicker" : null })
}
onChange={(color) => updateData(color)}
data-testid="canvas-background-picker"
/>
</div>
@ -59,6 +55,7 @@ export const actionClearCanvas = register({
exportBackground: appState.exportBackground,
exportEmbedScene: appState.exportEmbedScene,
gridSize: appState.gridSize,
shouldAddWatermark: appState.shouldAddWatermark,
showStats: appState.showStats,
pasteDialog: appState.pasteDialog,
},

View File

@ -71,8 +71,26 @@ export const actionChangeExportEmbedScene = register({
),
});
export const actionSaveToActiveFile = register({
name: "saveToActiveFile",
export const actionChangeShouldAddWatermark = register({
name: "changeShouldAddWatermark",
perform: (_elements, appState, value) => {
return {
appState: { ...appState, shouldAddWatermark: value },
commitToHistory: false,
};
},
PanelComponent: ({ appState, updateData }) => (
<CheckboxItem
checked={appState.shouldAddWatermark}
onChange={(checked) => updateData(checked)}
>
{t("labels.addWatermark")}
</CheckboxItem>
),
});
export const actionSaveScene = register({
name: "saveScene",
perform: async (elements, appState, value) => {
const fileHandleExists = !!appState.fileHandle;
try {
@ -113,8 +131,8 @@ export const actionSaveToActiveFile = register({
),
});
export const actionSaveFileToDisk = register({
name: "saveFileToDisk",
export const actionSaveAsScene = register({
name: "saveAsScene",
perform: async (elements, appState, value) => {
try {
const { fileHandle } = await saveAsJSON(elements, {

View File

@ -99,18 +99,13 @@ export const actionChangeStrokeColor = register({
name: "changeStrokeColor",
perform: (elements, appState, value) => {
return {
...(value.currentItemStrokeColor && {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
strokeColor: value.currentItemStrokeColor,
}),
),
}),
appState: {
...appState,
...value,
},
commitToHistory: !!value.currentItemStrokeColor,
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
strokeColor: value,
}),
),
appState: { ...appState, currentItemStrokeColor: value },
commitToHistory: true,
};
},
PanelComponent: ({ elements, appState, updateData }) => (
@ -125,11 +120,7 @@ export const actionChangeStrokeColor = register({
(element) => element.strokeColor,
appState.currentItemStrokeColor,
)}
onChange={(color) => updateData({ currentItemStrokeColor: color })}
isActive={appState.openMenu === "strokeColorPicker"}
setActive={(active) =>
updateData({ openMenu: active ? "strokeColorPicker" : null })
}
onChange={updateData}
/>
</>
),
@ -139,18 +130,13 @@ export const actionChangeBackgroundColor = register({
name: "changeBackgroundColor",
perform: (elements, appState, value) => {
return {
...(value.currentItemBackgroundColor && {
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
backgroundColor: value.currentItemBackgroundColor,
}),
),
}),
appState: {
...appState,
...value,
},
commitToHistory: !!value.currentItemBackgroundColor,
elements: changeProperty(elements, appState, (el) =>
newElementWith(el, {
backgroundColor: value,
}),
),
appState: { ...appState, currentItemBackgroundColor: value },
commitToHistory: true,
};
},
PanelComponent: ({ elements, appState, updateData }) => (
@ -165,11 +151,7 @@ export const actionChangeBackgroundColor = register({
(element) => element.backgroundColor,
appState.currentItemBackgroundColor,
)}
onChange={(color) => updateData({ currentItemBackgroundColor: color })}
isActive={appState.openMenu === "backgroundColorPicker"}
setActive={(active) =>
updateData({ openMenu: active ? "backgroundColorPicker" : null })
}
onChange={updateData}
/>
</>
),

View File

@ -34,8 +34,8 @@ export { actionFinalize } from "./actionFinalize";
export {
actionChangeProjectName,
actionChangeExportBackground,
actionSaveToActiveFile,
actionSaveFileToDisk,
actionSaveScene,
actionSaveAsScene,
actionLoadScene,
} from "./actionExport";

View File

@ -66,8 +66,9 @@ export type ActionName =
| "changeProjectName"
| "changeExportBackground"
| "changeExportEmbedScene"
| "saveToActiveFile"
| "saveFileToDisk"
| "changeShouldAddWatermark"
| "saveScene"
| "saveAsScene"
| "loadScene"
| "duplicateSelection"
| "deleteSelectedElements"

View File

@ -61,6 +61,7 @@ export const getDefaultAppState = (): Omit<
selectedElementIds: {},
selectedGroupIds: {},
selectionElement: null,
shouldAddWatermark: false,
shouldCacheIgnoreZoom: false,
showHelpDialog: false,
showStats: false,
@ -140,6 +141,7 @@ const APP_STATE_STORAGE_CONF = (<
selectedElementIds: { browser: true, export: false },
selectedGroupIds: { browser: true, export: false },
selectionElement: { browser: false, export: false },
shouldAddWatermark: { browser: true, export: false },
shouldCacheIgnoreZoom: { browser: true, export: false },
showHelpDialog: { browser: false, export: false },
showStats: { browser: true, export: false },

View File

@ -452,6 +452,7 @@ class App extends React.Component<AppProps, AppState> {
const {
onCollabButtonClick,
onExportToBackend,
renderTopRightUI,
renderFooter,
renderCustomStats,
@ -492,6 +493,7 @@ class App extends React.Component<AppProps, AppState> {
toggleZenMode={this.toggleZenMode}
langCode={getLanguage().code}
isCollaborating={this.props.isCollaborating || false}
onExportToBackend={onExportToBackend}
renderTopRightUI={renderTopRightUI}
renderCustomFooter={renderFooter}
viewModeEnabled={viewModeEnabled}
@ -1643,21 +1645,6 @@ class App extends React.Component<AppProps, AppState> {
isHoldingSpace = true;
setCursor(this.canvas, CURSOR_TYPE.GRABBING);
}
if (event.key === KEYS.G || event.key === KEYS.S) {
const selectedElements = getSelectedElements(
this.scene.getElements(),
this.state,
);
if (selectedElements.length) {
if (event.key === KEYS.G) {
this.setState({ openMenu: "backgroundColorPicker" });
}
if (event.key === KEYS.S) {
this.setState({ openMenu: "strokeColorPicker" });
}
}
}
},
);
@ -1858,29 +1845,9 @@ class App extends React.Component<AppProps, AppState> {
private getElementAtPosition(
x: number,
y: number,
opts?: {
/** if true, returns the first selected element (with highest z-index)
of all hit elements */
preferSelected?: boolean;
cycleElementsUnderCursor?: boolean;
},
): NonDeleted<ExcalidrawElement> | null {
const allHitElements = this.getElementsAtPosition(x, y);
if (allHitElements.length > 1) {
if (opts?.preferSelected) {
for (let index = allHitElements.length - 1; index > -1; index--) {
if (this.state.selectedElementIds[allHitElements[index].id]) {
return allHitElements[index];
}
}
} else if (opts?.cycleElementsUnderCursor) {
const selectedIdx = allHitElements.findIndex(
(element) => this.state.selectedElementIds[element.id],
);
return selectedIdx > 0
? allHitElements[selectedIdx - 1]
: allHitElements[allHitElements.length - 1];
}
const elementWithHighestZIndex =
allHitElements[allHitElements.length - 1];
// If we're hitting element with highest z-index only on its bounding box
@ -2313,115 +2280,119 @@ class App extends React.Component<AppProps, AppState> {
invalidateContextMenu = true;
};
private handleCanvasPointerDown = (
event: React.PointerEvent<HTMLCanvasElement>,
) => {
event.persist();
private handleCanvasPointerDown = withBatchedUpdates(
(event: React.PointerEvent<HTMLCanvasElement>) => {
event.persist();
// remove any active selection when we start to interact with canvas
// (mainly, we care about removing selection outside the component which
// would prevent our copy handling otherwise)
const selection = document.getSelection();
if (selection?.anchorNode) {
selection.removeAllRanges();
}
if (this.state.openMenu === "canvas") {
this.setState({ openMenu: null });
}
this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);
this.maybeCleanupAfterMissingPointerUp(event);
// remove any active selection when we start to interact with canvas
// (mainly, we care about removing selection outside the component which
// would prevent our copy handling otherwise)
const selection = document.getSelection();
if (selection?.anchorNode) {
selection.removeAllRanges();
}
if (isPanning) {
return;
}
this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);
this.maybeCleanupAfterMissingPointerUp(event);
this.setState({
lastPointerDownWith: event.pointerType,
cursorButton: "down",
});
this.savePointer(event.clientX, event.clientY, "down");
if (isPanning) {
return;
}
if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {
return;
}
this.setState({
lastPointerDownWith: event.pointerType,
cursorButton: "down",
});
this.savePointer(event.clientX, event.clientY, "down");
// only handle left mouse button or touch
if (
event.button !== POINTER_BUTTON.MAIN &&
event.button !== POINTER_BUTTON.TOUCH
) {
return;
}
if (this.handleCanvasPanUsingWheelOrSpaceDrag(event)) {
return;
}
this.updateGestureOnPointerDown(event);
// only handle left mouse button or touch
if (
event.button !== POINTER_BUTTON.MAIN &&
event.button !== POINTER_BUTTON.TOUCH
) {
return;
}
// don't select while panning
if (gesture.pointers.size > 1) {
return;
}
this.updateGestureOnPointerDown(event);
// State for the duration of a pointer interaction, which starts with a
// pointerDown event, ends with a pointerUp event (or another pointerDown)
const pointerDownState = this.initialPointerDownState(event);
// don't select while panning
if (gesture.pointers.size > 1) {
return;
}
if (this.handleDraggingScrollBar(event, pointerDownState)) {
return;
}
// State for the duration of a pointer interaction, which starts with a
// pointerDown event, ends with a pointerUp event (or another pointerDown)
const pointerDownState = this.initialPointerDownState(event);
this.clearSelectionIfNotUsingSelection();
this.updateBindingEnabledOnPointerMove(event);
if (this.handleDraggingScrollBar(event, pointerDownState)) {
return;
}
if (this.handleSelectionOnPointerDown(event, pointerDownState)) {
return;
}
this.clearSelectionIfNotUsingSelection();
this.updateBindingEnabledOnPointerMove(event);
if (this.state.elementType === "text") {
this.handleTextOnPointerDown(event, pointerDownState);
return;
} else if (
this.state.elementType === "arrow" ||
this.state.elementType === "line"
) {
this.handleLinearElementOnPointerDown(
event,
this.state.elementType,
if (this.handleSelectionOnPointerDown(event, pointerDownState)) {
return;
}
if (this.state.elementType === "text") {
this.handleTextOnPointerDown(event, pointerDownState);
return;
} else if (
this.state.elementType === "arrow" ||
this.state.elementType === "line"
) {
this.handleLinearElementOnPointerDown(
event,
this.state.elementType,
pointerDownState,
);
} else if (this.state.elementType === "freedraw") {
this.handleFreeDrawElementOnPointerDown(
event,
this.state.elementType,
pointerDownState,
);
} else {
this.createGenericElementOnPointerDown(
this.state.elementType,
pointerDownState,
);
}
const onPointerMove = this.onPointerMoveFromPointerDownHandler(
pointerDownState,
);
} else if (this.state.elementType === "freedraw") {
this.handleFreeDrawElementOnPointerDown(
event,
this.state.elementType,
const onPointerUp = this.onPointerUpFromPointerDownHandler(
pointerDownState,
);
} else {
this.createGenericElementOnPointerDown(
this.state.elementType,
pointerDownState,
);
}
const onPointerMove = this.onPointerMoveFromPointerDownHandler(
pointerDownState,
);
const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);
const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);
const onPointerUp = this.onPointerUpFromPointerDownHandler(
pointerDownState,
);
lastPointerUp = onPointerUp;
const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);
const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);
lastPointerUp = onPointerUp;
if (!this.state.viewModeEnabled) {
window.addEventListener(EVENT.POINTER_MOVE, onPointerMove);
window.addEventListener(EVENT.POINTER_UP, onPointerUp);
window.addEventListener(EVENT.KEYDOWN, onKeyDown);
window.addEventListener(EVENT.KEYUP, onKeyUp);
pointerDownState.eventListeners.onMove = onPointerMove;
pointerDownState.eventListeners.onUp = onPointerUp;
pointerDownState.eventListeners.onKeyUp = onKeyUp;
pointerDownState.eventListeners.onKeyDown = onKeyDown;
}
};
if (!this.state.viewModeEnabled) {
window.addEventListener(EVENT.POINTER_MOVE, onPointerMove);
window.addEventListener(EVENT.POINTER_UP, onPointerUp);
window.addEventListener(EVENT.KEYDOWN, onKeyDown);
window.addEventListener(EVENT.KEYUP, onKeyUp);
pointerDownState.eventListeners.onMove = onPointerMove;
pointerDownState.eventListeners.onUp = onPointerUp;
pointerDownState.eventListeners.onKeyUp = onKeyUp;
pointerDownState.eventListeners.onKeyDown = onKeyDown;
}
},
);
private maybeOpenContextMenuAfterPointerDownOnTouchDevices = (
event: React.PointerEvent<HTMLCanvasElement>,
@ -2754,13 +2725,10 @@ class App extends React.Component<AppProps, AppState> {
// hitElement may already be set above, so check first
pointerDownState.hit.element =
(!event[KEYS.CTRL_OR_CMD] ? pointerDownState.hit.element : null) ??
pointerDownState.hit.element ??
this.getElementAtPosition(
pointerDownState.origin.x,
pointerDownState.origin.y,
{
cycleElementsUnderCursor: event[KEYS.CTRL_OR_CMD],
},
);
// For overlapped elements one position may hit
@ -3958,7 +3926,7 @@ class App extends React.Component<AppProps, AppState> {
event.preventDefault();
const { x, y } = viewportCoordsToSceneCoords(event, this.state);
const element = this.getElementAtPosition(x, y, { preferSelected: true });
const element = this.getElementAtPosition(x, y);
const type = element ? "element" : "canvas";

View File

@ -18,7 +18,7 @@ export const BackgroundPickerAndDarkModeToggle = ({
{showThemeBtn && actionManager.renderAction("toggleTheme")}
{appState.fileHandle && (
<div style={{ marginInlineStart: "0.25rem" }}>
{actionManager.renderAction("saveToActiveFile")}
{actionManager.renderAction("saveScene")}
</div>
)}
</div>

View File

@ -2,20 +2,16 @@
.excalidraw {
.Checkbox {
margin: 4px 0.3em;
margin: 3px 0.3em;
display: flex;
align-items: center;
cursor: pointer;
user-select: none;
-webkit-tap-highlight-color: transparent;
&:hover:not(.is-checked) .Checkbox-box:not(:focus) {
&:hover:not(.is-checked) .Checkbox-box {
box-shadow: 0 0 0 2px #{$oc-blue-4};
}
&:hover:not(.is-checked) .Checkbox-box:not(:focus) {
svg {
display: block;
opacity: 0.3;

View File

@ -238,16 +238,13 @@ export const ColorPicker = ({
color,
onChange,
label,
isActive,
setActive,
}: {
type: "canvasBackground" | "elementBackground" | "elementStroke";
color: string | null;
onChange: (color: string) => void;
label: string;
isActive: boolean;
setActive: (active: boolean) => void;
}) => {
const [isActive, setActive] = React.useState(false);
const pickerButton = React.useRef<HTMLButtonElement>(null);
return (

View File

@ -108,7 +108,7 @@
}
&:active {
background-color: var(--button-color-darkest);
box-shadow: none;
box-shadow: 0 3px 5px -1px rgb(0 0 0 / 20%), 0 6px 10px 0 rgb(0 0 0 / 14%);
}
svg {

View File

@ -365,14 +365,6 @@ export const HelpDialog = ({ onClose }: { onClose?: () => void }) => {
label={t("labels.flipVertical")}
shortcuts={[getShortcutKey("Shift+V")]}
/>
<Shortcut
label={t("labels.showStroke")}
shortcuts={[getShortcutKey("S")]}
/>
<Shortcut
label={t("labels.showBackground")}
shortcuts={[getShortcutKey("G")]}
/>
</ShortcutIsland>
</Column>
</Columns>

View File

@ -101,7 +101,11 @@ const ImageExportModal = ({
const [scale, setScale] = useState(defaultScale);
const [exportSelected, setExportSelected] = useState(someElementIsSelected);
const previewRef = useRef<HTMLDivElement>(null);
const { exportBackground, viewBackgroundColor } = appState;
const {
exportBackground,
viewBackgroundColor,
shouldAddWatermark,
} = appState;
const exportedElements = exportSelected
? getSelectedElements(elements, appState)
@ -122,6 +126,7 @@ const ImageExportModal = ({
viewBackgroundColor,
exportPadding,
scale,
shouldAddWatermark,
});
// if converting to blob fails, there's some problem that will
@ -145,6 +150,7 @@ const ImageExportModal = ({
exportPadding,
viewBackgroundColor,
scale,
shouldAddWatermark,
]);
return (
@ -180,6 +186,7 @@ const ImageExportModal = ({
const [width, height] = getExportSize(
exportedElements,
exportPadding,
shouldAddWatermark,
_scale,
);

View File

@ -3,11 +3,11 @@ import { ActionsManagerInterface } from "../actions/types";
import { NonDeletedExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import { useIsMobile } from "./App";
import { AppState, ExportOpts } from "../types";
import { AppState } from "../types";
import { Dialog } from "./Dialog";
import { exportFile, exportToFileIcon, link } from "./icons";
import { ToolButton } from "./ToolButton";
import { actionSaveFileToDisk } from "../actions/actionExport";
import { actionSaveAsScene } from "../actions/actionExport";
import { Card } from "./Card";
import "./ExportDialog.scss";
@ -22,40 +22,35 @@ const JSONExportModal = ({
elements,
appState,
actionManager,
exportOpts,
canvas,
onExportToBackend,
}: {
appState: AppState;
elements: readonly NonDeletedExcalidrawElement[];
actionManager: ActionsManagerInterface;
onExportToBackend?: ExportCB;
onCloseRequest: () => void;
exportOpts: ExportOpts;
canvas: HTMLCanvasElement | null;
}) => {
const { onExportToBackend } = exportOpts;
return (
<div className="ExportDialog ExportDialog--json">
<div className="ExportDialog-cards">
{exportOpts.saveFileToDisk && (
<Card color="lime">
<div className="Card-icon">{exportToFileIcon}</div>
<h2>{t("exportDialog.disk_title")}</h2>
<div className="Card-details">
{t("exportDialog.disk_details")}
{!fsSupported && actionManager.renderAction("changeProjectName")}
</div>
<ToolButton
className="Card-button"
type="button"
title={t("exportDialog.disk_button")}
aria-label={t("exportDialog.disk_button")}
showAriaLabel={true}
onClick={() => {
actionManager.executeAction(actionSaveFileToDisk);
}}
/>
</Card>
)}
<Card color="lime">
<div className="Card-icon">{exportToFileIcon}</div>
<h2>{t("exportDialog.disk_title")}</h2>
<div className="Card-details">
{t("exportDialog.disk_details")}
{!fsSupported && actionManager.renderAction("changeProjectName")}
</div>
<ToolButton
className="Card-button"
type="button"
title={t("exportDialog.disk_button")}
aria-label={t("exportDialog.disk_button")}
showAriaLabel={true}
onClick={() => {
actionManager.executeAction(actionSaveAsScene);
}}
/>
</Card>
{onExportToBackend && (
<Card color="pink">
<div className="Card-icon">{link}</div>
@ -67,12 +62,10 @@ const JSONExportModal = ({
title={t("exportDialog.link_button")}
aria-label={t("exportDialog.link_button")}
showAriaLabel={true}
onClick={() => onExportToBackend(elements, appState, canvas)}
onClick={() => onExportToBackend(elements)}
/>
</Card>
)}
{exportOpts.renderCustomUI &&
exportOpts.renderCustomUI(elements, appState, canvas)}
</div>
</div>
);
@ -82,14 +75,12 @@ export const JSONExportDialog = ({
elements,
appState,
actionManager,
exportOpts,
canvas,
onExportToBackend,
}: {
appState: AppState;
elements: readonly NonDeletedExcalidrawElement[];
actionManager: ActionsManagerInterface;
exportOpts: ExportOpts;
canvas: HTMLCanvasElement | null;
onExportToBackend?: ExportCB;
}) => {
const [modalIsShown, setModalIsShown] = useState(false);
@ -116,9 +107,8 @@ export const JSONExportDialog = ({
elements={elements}
appState={appState}
actionManager={actionManager}
onExportToBackend={onExportToBackend}
onCloseRequest={handleClose}
exportOpts={exportOpts}
canvas={canvas}
/>
</Dialog>
)}

View File

@ -63,6 +63,11 @@ interface LayerUIProps {
toggleZenMode: () => void;
langCode: Language["code"];
isCollaborating: boolean;
onExportToBackend?: (
exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
canvas: HTMLCanvasElement | null,
) => void;
renderTopRightUI?: (isMobile: boolean, appState: AppState) => JSX.Element;
renderCustomFooter?: (isMobile: boolean, appState: AppState) => JSX.Element;
viewModeEnabled: boolean;
@ -366,6 +371,7 @@ const LayerUI = ({
showThemeBtn,
toggleZenMode,
isCollaborating,
onExportToBackend,
renderTopRightUI,
renderCustomFooter,
viewModeEnabled,
@ -387,14 +393,20 @@ const LayerUI = ({
elements={elements}
appState={appState}
actionManager={actionManager}
exportOpts={UIOptions.canvasActions.export}
canvas={canvas}
onExportToBackend={
onExportToBackend
? (elements) => {
onExportToBackend &&
onExportToBackend(elements, appState, canvas);
}
: undefined
}
/>
);
};
const renderImageExportDialog = () => {
if (!UIOptions.canvasActions.saveAsImage) {
if (!UIOptions.canvasActions.export) {
return null;
}
@ -407,6 +419,7 @@ const LayerUI = ({
name: appState.name,
viewBackgroundColor: appState.viewBackgroundColor,
scale,
shouldAddWatermark: appState.shouldAddWatermark,
})
.catch(muteFSAbortError)
.catch((error) => {

View File

@ -39,6 +39,7 @@ export const LibraryUnit = ({
const svg = exportToSvg(elementsToRender, {
exportBackground: false,
viewBackgroundColor: oc.white,
shouldAddWatermark: false,
});
for (const child of ref.current!.children) {
if (child.tagName !== "svg") {

View File

@ -38,6 +38,7 @@ const ChartPreviewBtn = (props: {
const svg = exportToSvg(elements, {
exportBackground: false,
viewBackgroundColor: oc.white,
shouldAddWatermark: false,
});
const previewNode = previewRef.current!;

View File

@ -90,8 +90,14 @@ export const exportFile = createIcon(
export const exportImage = createIcon(
<>
<path d="M571 308l-95.7-96.4c-10.1-10.1-27.4-3-27.4 11.3V288h-64v64h64v65.2c0 14.3 17.3 21.4 27.4 11.3L571 332c6.6-6.6 6.6-17.4 0-24zm-187 44v-64 64z" />
<path d="M384 121.941V128H256V0h6.059c6.362 0 12.471 2.53 16.97 7.029l97.941 97.941a24.01 24.01 0 017.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z" />
<path
d="M571 308l-95.7-96.4c-10.1-10.1-27.4-3-27.4 11.3V288h-64v64h64v65.2c0 14.3 17.3 21.4 27.4 11.3L571 332c6.6-6.6 6.6-17.4 0-24zm-187 44v-64 64z"
fill-rule="nonzero"
/>
<path
d="M384 121.941V128H256V0h6.059c6.362 0 12.471 2.53 16.97 7.029l97.941 97.941a24.01 24.01 0 017.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z"
fill-rule="nonzero"
/>
</>,
{ width: 576, height: 512, mirror: true },
);

View File

@ -131,11 +131,11 @@ export const DEFAULT_UI_OPTIONS: AppProps["UIOptions"] = {
canvasActions: {
changeViewBackgroundColor: true,
clearCanvas: true,
export: { saveFileToDisk: true },
export: true,
loadScene: true,
saveToActiveFile: true,
saveAsScene: true,
saveScene: true,
theme: true,
saveAsImage: true,
},
};

View File

@ -24,12 +24,14 @@ export const exportCanvas = async (
viewBackgroundColor,
name,
scale = 1,
shouldAddWatermark,
}: {
exportBackground: boolean;
exportPadding?: number;
viewBackgroundColor: string;
name: string;
scale?: number;
shouldAddWatermark: boolean;
},
) => {
if (elements.length === 0) {
@ -42,6 +44,7 @@ export const exportCanvas = async (
viewBackgroundColor,
exportPadding,
scale,
shouldAddWatermark,
metadata:
appState.exportEmbedScene && type === "svg"
? await (
@ -68,6 +71,7 @@ export const exportCanvas = async (
viewBackgroundColor,
exportPadding,
scale,
shouldAddWatermark,
});
tempCanvas.style.display = "none";
document.body.appendChild(tempCanvas);

View File

@ -307,19 +307,7 @@ export const duplicateElement = <TElement extends Mutable<ExcalidrawElement>>(
overrides?: Partial<TElement>,
): TElement => {
let copy: TElement = deepCopyElement(element);
if (process.env.NODE_ENV === "test") {
copy.id = `${copy.id}_copy`;
// `window.h` may not be defined in some unit tests
if (
window.h?.app
?.getSceneElementsIncludingDeleted()
.find((el) => el.id === copy.id)
) {
copy.id += "_copy";
}
} else {
copy.id = randomId();
}
copy.id = process.env.NODE_ENV === "test" ? `${copy.id}_copy` : randomId();
copy.seed = randomInteger();
copy.groupIds = getNewGroupIdsForDuplication(
copy.groupIds,

View File

@ -424,13 +424,7 @@ const ExcalidrawWrapper = () => {
onCollabButtonClick={collabAPI?.onCollabButtonClick}
isCollaborating={collabAPI?.isCollaborating()}
onPointerUpdate={collabAPI?.onPointerUpdate}
UIOptions={{
canvasActions: {
export: {
onExportToBackend,
},
},
}}
onExportToBackend={onExportToBackend}
renderTopRightUI={renderTopRightUI}
renderFooter={renderFooter}
langCode={langCode}

View File

@ -21,7 +21,6 @@ interface DehydratedHistoryEntry {
const clearAppStatePropertiesForHistory = (appState: AppState) => {
return {
selectedElementIds: appState.selectedElementIds,
selectedGroupIds: appState.selectedGroupIds,
viewBackgroundColor: appState.viewBackgroundColor,
editingLinearElement: appState.editingLinearElement,
editingGroupId: appState.editingGroupId,
@ -170,7 +169,7 @@ class History {
continue;
}
}
if (key === "selectedElementIds" || key === "selectedGroupIds") {
if (key === "selectedElementIds") {
continue;
}
if (nextEntry.appState[key] !== lastEntry.appState[key]) {

View File

@ -48,7 +48,6 @@ const allLanguages: Language[] = [
{ code: "zh-CN", label: "简体中文" },
{ code: "zh-TW", label: "繁體中文" },
{ code: "lv-LV", label: "Latviešu" },
{ code: "cs-CZ", label: "Česky" },
].concat([defaultLang]);
export const languages: Language[] = allLanguages

View File

@ -69,6 +69,7 @@ const canvas = exportToCanvas(
{
exportBackground: true,
viewBackgroundColor: "#ffffff",
shouldAddWatermark: false,
scale: 1,
},
createCanvas,

View File

@ -44,7 +44,6 @@ export const KEYS = {
A: "a",
D: "d",
E: "e",
G: "g",
L: "l",
O: "o",
P: "p",

View File

@ -20,10 +20,6 @@
"background": "الخلفية",
"fill": "التعبئة",
"strokeWidth": "حجم الحدود",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "نمط الحدود",
"strokeStyle_solid": "صلبة",
"strokeStyle_dashed": "متقطع",
@ -42,8 +38,8 @@
"fontSize": "حجم الخط",
"fontFamily": "نوع الخط",
"onlySelected": "المحدد فقط",
"withBackground": "الخلفية",
"exportEmbedScene": "",
"withBackground": "مع الخلفية",
"exportEmbedScene": "تضمين المشهد في ملف التصدير",
"exportEmbedScene_details": "سيتم حفظ بيانات المشهد في ملف PNG/SVG المصدّر بحيث يمكن استعادة المشهد منه.\nسيزيد حجم الملف المصدر.",
"addWatermark": "إضافة \"مصنوعة بواسطة Excalidraw\"",
"handDrawn": "رسم باليد",
@ -65,7 +61,7 @@
"architect": "معماري",
"artist": "رسام",
"cartoonist": "كرتوني",
"fileTitle": "إسم الملف",
"fileTitle": "",
"colorPicker": "اختيار الألوان",
"canvasBackground": "خلفية اللوحة",
"drawingCanvas": "لوحة الرسم",
@ -96,24 +92,21 @@
"centerHorizontally": "توسيط أفقي",
"distributeHorizontally": "التوزيع الأفقي",
"distributeVertically": "التوزيع عمودياً",
"flipHorizontal": "قلب عامودي",
"flipVertical": "قلب أفقي",
"flipHorizontal": "",
"flipVertical": "",
"viewMode": "نمط العرض",
"toggleExportColorScheme": "",
"share": "مشاركة",
"toggleTheme": "غير النمط"
"share": "مشاركة"
},
"buttons": {
"clearReset": "إعادة تعيين اللوحة",
"exportJSON": "صدر الملف",
"exportImage": "إحفظ كصورة",
"export": "تصدير",
"exportToPng": "تصدير بصيغة PNG",
"exportToSvg": "تصدير بصيغة SVG",
"copyToClipboard": "نسخ إلى الحافظة",
"copyPngToClipboard": "نسخ الـ PNG إلى الحافظة",
"scale": "مقاس",
"save": "احفظ للملف الحالي",
"save": "حفظ",
"saveAs": "حفظ كـ",
"load": "تحميل",
"getShareableLink": "احصل على رابط المشاركة",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "تحديد",
"freedraw": "الكتابة الحرة",
"rectangle": "مستطيل",
"diamond": "مضلع",
"ellipse": "دائرة",
"arrow": "سهم",
"line": "خط",
"freedraw": "",
"text": "نص",
"library": "مكتبة",
"lock": "الحفاظ على أداة التحديد نشطة بعد الرسم"
@ -217,38 +210,30 @@
"errorDialog": {
"title": "خطأ"
},
"exportDialog": {
"disk_title": "حفظ الملف للجهاز",
"disk_details": "",
"disk_button": "إحفظ لملف",
"link_title": "رابط قابل للمشاركة",
"link_details": "صدر الملف للمشاهدة فقط.",
"link_button": "التصدير كرابط"
},
"helpDialog": {
"blog": "اقرأ مدونتنا",
"click": "انقر",
"curvedArrow": "سهم مائل",
"curvedLine": "خط مائل",
"documentation": "دليل الاستخدام",
"blog": "",
"click": "",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "اسحب",
"editor": "المحرر",
"github": "عثرت على مشكلة؟ إرسال",
"howto": "اتبع التعليمات",
"or": "أو",
"preventBinding": "منع ارتبط السهم",
"shapes": "أشكال",
"shortcuts": "اختصارات لوحة المفاتيح",
"textFinish": "الانتهاء من التحرير (نص)",
"textNewLine": "اضف سطر جديد (نص)",
"title": "المساعدة",
"view": "عرض",
"zoomToFit": "تكبير للملائمة",
"zoomToSelection": "تكبير للعنصر المحدد"
"howto": "",
"or": "",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "رسوماتك مشفرة من النهاية إلى النهاية حتى أن خوادم Excalidraw لن تراها أبدا.",
"link": "مشاركة المدونة في التشفير من النهاية إلى النهاية في Excalidraw"
"link": ""
},
"stats": {
"angle": "الزاوية",
@ -260,18 +245,18 @@
"storage": "التخزين",
"title": "إحصائيات للمهووسين",
"total": "المجموع",
"version": "الإصدار",
"versionCopy": "انقر للنسخ",
"versionNotAvailable": "الإصدار غير متوفر",
"version": "",
"versionCopy": "",
"versionNotAvailable": "",
"width": "العرض"
},
"toast": {
"copyStyles": "نسخ النمط.",
"copyToClipboard": "نسخ إلى الحافظة.",
"copyToClipboardAsPng": "تم نسخ {{exportSelection}} إلى الحافظة بصيغةPNG\n({{exportColorScheme}})",
"fileSaved": "تم حفظ الملف.",
"fileSavedToFilename": "حفظ باسم {filename}",
"canvas": "لوحة الرسم",
"selection": "العنصر المحدد"
"copyStyles": "",
"copyToClipboard": "",
"copyToClipboardAsPng": "",
"fileSaved": "",
"fileSavedToFilename": "",
"canvas": "",
"selection": ""
}
}

View File

@ -20,10 +20,6 @@
"background": "Фон",
"fill": "Наситеност",
"strokeWidth": "Ширина на щриха",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Стил на линия",
"strokeStyle_solid": "Плътен",
"strokeStyle_dashed": "Пунктир",
@ -42,8 +38,8 @@
"fontSize": "Размер на шрифта",
"fontFamily": "Семейство шрифтове",
"onlySelected": "Само избраното",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "С фон",
"exportEmbedScene": "Вгради сцената във файл",
"exportEmbedScene_details": "Данните от сцената ще бъдат екпортирани в PNG/SVG файл, за да може сцената да бъде възстановена от него.\nТова ще увеличи размера на файла.",
"addWatermark": "Добави \"Направено с Excalidraw\"",
"handDrawn": "Нарисувано на ръка",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "Изглед",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "Нулиране на платно",
"exportJSON": "",
"exportImage": "",
"export": "Експортиране",
"exportToPng": "Изнасяне в PNG",
"exportToSvg": "Изнасяне в SVG",
"copyToClipboard": "Копиране в клипборда",
"copyPngToClipboard": "Копирай PNG в клипборда",
"scale": "Мащаб",
"save": "",
"save": "Запази",
"saveAs": "Запиши като",
"load": "Зареждане",
"getShareableLink": "Получаване на връзка за споделяне",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Селекция",
"freedraw": "Рисуване",
"rectangle": "Правоъгълник",
"diamond": "Диамант",
"ellipse": "Елипс",
"arrow": "Стрелка",
"line": "Линия",
"freedraw": "",
"text": "Текст",
"library": "Библиотека",
"lock": "Поддържайте избрания инструмент активен след рисуване"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Грешка"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Прочетете нашия блог",
"click": "клик",

View File

@ -20,10 +20,6 @@
"background": "Color del fons",
"fill": "Estil del fons",
"strokeWidth": "Amplada del traç",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Estil del traç",
"strokeStyle_solid": "Sòlid",
"strokeStyle_dashed": "Guions",
@ -42,8 +38,8 @@
"fontSize": "Mida de lletra",
"fontFamily": "Tipus de lletra",
"onlySelected": "Només seleccionats",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Amb fons",
"exportEmbedScene": "Incrustar escena al fitxer exportat",
"exportEmbedScene_details": "Les dades de lescena es desaran al fitxer PNG/SVG de manera que es pugui restaurar lescena.\nAugmentarà la mida del fitxer exportat.",
"addWatermark": "Afegir \"Fet amb Excalidraw\"",
"handDrawn": "Dibuixat a mà",
@ -100,20 +96,17 @@
"flipVertical": "Capgira verticalment",
"viewMode": "Mode de visualització",
"toggleExportColorScheme": "Canvia l'esquema de colors de l'exportació",
"share": "Compartir",
"toggleTheme": ""
"share": "Compartir"
},
"buttons": {
"clearReset": "Netejar el llenç",
"exportJSON": "",
"exportImage": "",
"export": "Exportar",
"exportToPng": "Exportar a PNG",
"exportToSvg": "Exportar a SNG",
"copyToClipboard": "Copiar al porta-retalls",
"copyPngToClipboard": "Copiar PNG al porta-retalls",
"scale": "Escala",
"save": "",
"save": "Desar",
"saveAs": "Desar com",
"load": "Carregar",
"getShareableLink": "Obtenir enllaç per compartir",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Selecció",
"freedraw": "Dibuix lliure",
"rectangle": "Rectangle",
"diamond": "Rombe",
"ellipse": "El·lipse",
"arrow": "Fletxa",
"line": "Línia",
"freedraw": "Dibuix",
"text": "Text",
"library": "Biblioteca",
"lock": "Mantenir activa l'eina seleccionada desprès de dibuixar"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Error"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Llegiu el nostre blog",
"click": "clic",

View File

@ -1,277 +0,0 @@
{
"labels": {
"paste": "Vložit",
"pasteCharts": "Vložit grafy",
"selectAll": "Vybrat vše",
"multiSelect": "Přidat prvek do výběru",
"moveCanvas": "Posunout plátno",
"cut": "Vyjmout",
"copy": "Kopírovat",
"copyAsPng": "Zkopírovat do schránky jako PNG",
"copyAsSvg": "Zkopírovat do schránky jako SVG",
"bringForward": "Přenést blíž",
"sendToBack": "Přenést do pozadí",
"bringToFront": "Přenést do popředí",
"sendBackward": "Přenést dál",
"delete": "Smazat",
"copyStyles": "Kopírovat styly",
"pasteStyles": "Vložit styly",
"stroke": "Obrys",
"background": "Pozadí",
"fill": "Výplň",
"strokeWidth": "Šířka obrysu",
"strokeShape": "Tvar tahu",
"strokeShape_gel": "Gelové pero",
"strokeShape_fountain": "Plnicí pero",
"strokeShape_brush": "Fixa",
"strokeStyle": "Styl tahu",
"strokeStyle_solid": "Plný",
"strokeStyle_dashed": "Čárkovaný",
"strokeStyle_dotted": "Tečkovaný",
"sloppiness": "Stylizace",
"opacity": "Průhlednost",
"textAlign": "Zarovnání textu",
"edges": "Hrany",
"sharp": "Ostré",
"round": "Zaoblené",
"arrowheads": "Styl šipky",
"arrowhead_none": "Žádný",
"arrowhead_arrow": "Šipka",
"arrowhead_bar": "Kóta",
"arrowhead_dot": "Tečka",
"fontSize": "Velikost písma",
"fontFamily": "Písmo",
"onlySelected": "Pouze vybrané",
"withBackground": "",
"exportEmbedScene": "",
"exportEmbedScene_details": "",
"addWatermark": "",
"handDrawn": "Od ruky",
"normal": "Normální",
"code": "Kód",
"small": "Malé",
"medium": "Střední",
"large": "Velké",
"veryLarge": "Velmi velké",
"solid": "",
"hachure": "",
"crossHatch": "",
"thin": "",
"bold": "",
"left": "",
"center": "",
"right": "",
"extraBold": "",
"architect": "",
"artist": "",
"cartoonist": "",
"fileTitle": "",
"colorPicker": "",
"canvasBackground": "Pozadí plátna",
"drawingCanvas": "",
"layers": "",
"actions": "",
"language": "",
"liveCollaboration": "",
"duplicateSelection": "",
"untitled": "",
"name": "",
"yourName": "",
"madeWithExcalidraw": "",
"group": "",
"ungroup": "",
"collaborators": "",
"showGrid": "",
"addToLibrary": "",
"removeFromLibrary": "",
"libraryLoadingMessage": "",
"libraries": "",
"loadingScene": "",
"align": "",
"alignTop": "",
"alignBottom": "",
"alignLeft": "",
"alignRight": "",
"centerVertically": "",
"centerHorizontally": "",
"distributeHorizontally": "",
"distributeVertically": "",
"flipHorizontal": "",
"flipVertical": "",
"viewMode": "Náhled",
"toggleExportColorScheme": "",
"share": "Sdílet",
"toggleTheme": "Přepnout tmavý řežim"
},
"buttons": {
"clearReset": "",
"exportJSON": "",
"exportImage": "",
"export": "Exportovat",
"exportToPng": "Exportovat do PNG",
"exportToSvg": "Exportovat do SVG",
"copyToClipboard": "Kopírovat do schránky",
"copyPngToClipboard": "Kopírovat PNG do schránky",
"scale": "Měřítko",
"save": "",
"saveAs": "Uložit jako",
"load": "Nahrát",
"getShareableLink": "Získat odkaz pro sdílení",
"close": "Zavřít",
"selectLanguage": "Zvolit jazyk",
"scrollBackToContent": "",
"zoomIn": "Přiblížit",
"zoomOut": "Oddálit",
"resetZoom": "Resetovat přiblížení",
"menu": "Menu",
"done": "Hotovo",
"edit": "Upravit",
"undo": "Zpět",
"redo": "Znovu",
"resetLibrary": "",
"createNewRoom": "Vytvořit novou místnost",
"fullScreen": "Celá obrazovka",
"darkMode": "Tmavý režim",
"lightMode": "Světlý režim",
"zenMode": "Zen mód",
"exitZenMode": "Opustit zen mód"
},
"alerts": {
"clearReset": "",
"couldNotCreateShareableLink": "",
"couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "",
"importBackendFailed": "",
"cannotExportEmptyCanvas": "",
"couldNotCopyToClipboard": "",
"decryptFailed": "",
"uploadedSecurly": "",
"loadSceneOverridePrompt": "",
"collabStopOverridePrompt": "",
"errorLoadingLibrary": "",
"errorAddingToLibrary": "",
"errorRemovingFromLibrary": "",
"confirmAddLibrary": "",
"imageDoesNotContainScene": "",
"cannotRestoreFromImage": "",
"invalidSceneUrl": "",
"resetLibrary": ""
},
"toolBar": {
"selection": "Výběr",
"rectangle": "Obdélník",
"diamond": "Diamant",
"ellipse": "Elipsa",
"arrow": "Šipka",
"line": "Čára",
"freedraw": "Kreslení",
"text": "Text",
"library": "",
"lock": ""
},
"headings": {
"canvasActions": "",
"selectedShapeActions": "",
"shapes": "Tvary"
},
"hints": {
"linearElement": "",
"freeDraw": "",
"text": "",
"linearElementMulti": "",
"lockAngle": "",
"resize": "",
"rotate": "",
"lineEditor_info": "",
"lineEditor_pointSelected": "",
"lineEditor_nothingSelected": ""
},
"canvasError": {
"cannotShowPreview": "",
"canvasTooBig": "",
"canvasTooBigTip": ""
},
"errorSplash": {
"headingMain_pre": "",
"headingMain_button": "",
"clearCanvasMessage": "",
"clearCanvasMessage_button": "",
"clearCanvasCaveat": "",
"trackedToSentry_pre": "",
"trackedToSentry_post": "",
"openIssueMessage_pre": "",
"openIssueMessage_button": "",
"openIssueMessage_post": "",
"sceneContent": ""
},
"roomDialog": {
"desc_intro": "",
"desc_privacy": "",
"button_startSession": "",
"button_stopSession": "",
"desc_inProgressIntro": "",
"desc_shareLink": "",
"desc_exitSession": "",
"shareTitle": ""
},
"errorDialog": {
"title": ""
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "",
"click": "kliknutí",
"curvedArrow": "",
"curvedLine": "",
"documentation": "",
"drag": "tažení",
"editor": "",
"github": "",
"howto": "",
"or": "nebo",
"preventBinding": "",
"shapes": "",
"shortcuts": "",
"textFinish": "",
"textNewLine": "",
"title": "",
"view": "",
"zoomToFit": "",
"zoomToSelection": ""
},
"encrypted": {
"tooltip": "",
"link": ""
},
"stats": {
"angle": "",
"element": "",
"elements": "",
"height": "",
"scene": "",
"selected": "",
"storage": "",
"title": "",
"total": "",
"version": "",
"versionCopy": "",
"versionNotAvailable": "",
"width": ""
},
"toast": {
"copyStyles": "",
"copyToClipboard": "",
"copyToClipboardAsPng": "",
"fileSaved": "",
"fileSavedToFilename": "",
"canvas": "plátno",
"selection": "výběr"
}
}

View File

@ -20,10 +20,6 @@
"background": "Hintergrund",
"fill": "Füllung",
"strokeWidth": "Strichstärke",
"strokeShape": "Strichform",
"strokeShape_gel": "Gelschreiber",
"strokeShape_fountain": "Füllfederhalter",
"strokeShape_brush": "Pinselstift",
"strokeStyle": "Konturstil",
"strokeStyle_solid": "Durchgezogen",
"strokeStyle_dashed": "Gestrichelt",
@ -42,8 +38,8 @@
"fontSize": "Schriftgröße",
"fontFamily": "Schriftfamilie",
"onlySelected": "Nur ausgewählte",
"withBackground": "Hintergrund",
"exportEmbedScene": "Szene einbetten",
"withBackground": "Mit Hintergrund",
"exportEmbedScene": "Zeichnung in exportierte Datei einbetten",
"exportEmbedScene_details": "Die Zeichnungsdaten werden in der exportierten PNG/SVG-Datei gespeichert, sodass das Dokument später weiter bearbeitet werden kann. \nDieses wird die exportierte Datei vergrößern.",
"addWatermark": "\"Made with Excalidraw\" hinzufügen",
"handDrawn": "Handgezeichnet",
@ -100,20 +96,17 @@
"flipVertical": "Vertikal spiegeln",
"viewMode": "Ansichtsmodus",
"toggleExportColorScheme": "Exportfarbschema umschalten",
"share": "Teilen",
"toggleTheme": "Design umschalten"
"share": "Teilen"
},
"buttons": {
"clearReset": "Zeichenfläche löschen & Hintergrundfarbe zurücksetzen",
"exportJSON": "In Datei exportieren",
"exportImage": "Als Bild speichern",
"export": "Exportieren",
"exportToPng": "Als PNG exportieren",
"exportToSvg": "Als SVG exportieren",
"copyToClipboard": "In Zwischenablage kopieren",
"copyPngToClipboard": "PNG in die Zwischenablage kopieren",
"scale": "Skalierung",
"save": "In aktueller Datei speichern",
"save": "Speichern",
"saveAs": "Speichern unter",
"load": "Laden",
"getShareableLink": "Teilbaren Link erhalten",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Auswahl",
"freedraw": "Freies Zeichnen",
"rectangle": "Rechteck",
"diamond": "Raute",
"ellipse": "Ellipse",
"arrow": "Pfeil",
"line": "Linie",
"freedraw": "Zeichnen",
"text": "Text",
"library": "Bibliothek",
"lock": "Ausgewähltes Werkzeug nach Zeichnen aktiv lassen"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Fehler"
},
"exportDialog": {
"disk_title": "Auf Festplatte speichern",
"disk_details": "Exportiere die Zeichnungsdaten in eine Datei, die Du später importieren kannst.",
"disk_button": "In Datei speichern",
"link_title": "Teilbarer Link",
"link_details": "Als schreibgeschützten Link exportieren.",
"link_button": "Als Link exportieren"
},
"helpDialog": {
"blog": "Lies unseren Blog",
"click": "klicken",

View File

@ -20,10 +20,6 @@
"background": "Φόντο",
"fill": "Γέμισμα",
"strokeWidth": "Πάχος μολυβιάς",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Στυλ περιγράμματος",
"strokeStyle_solid": "Συμπαγής",
"strokeStyle_dashed": "Διακεκομμένη με παύλες",
@ -42,8 +38,8 @@
"fontSize": "Μέγεθος γραμματοσειράς",
"fontFamily": "Γραμματοσειρά",
"onlySelected": "Μόνο τα Επιλεγμένα",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Με φόντο",
"exportEmbedScene": "Ενσωμάτωση της σκηνής στο αρχείο προς εξαγωγή",
"exportEmbedScene_details": "Τα δεδομένα σκηνής θα αποθηκευτούν στο αρχείο PNG/SVG προς εξαγωγή ώστε η σκηνή να είναι δυνατό να αποκατασταθεί από αυτό.\nΘα αυξήσει το μέγεθος του αρχείου προς εξαγωγή.",
"addWatermark": "Προσθήκη \"Φτιαγμένο με Excalidraw\"",
"handDrawn": "Σχεδιασμένο στο χέρι",
@ -100,20 +96,17 @@
"flipVertical": "Κατακόρυφη αναστροφή",
"viewMode": "Λειτουργία προβολής",
"toggleExportColorScheme": "Εναλλαγή εξαγωγής θέματος χρωμάτων",
"share": "Κοινοποίηση",
"toggleTheme": ""
"share": "Κοινοποίηση"
},
"buttons": {
"clearReset": "Επαναφορά του καμβά",
"exportJSON": "",
"exportImage": "",
"export": "Εξαγωγή",
"exportToPng": "Εξαγωγή σε PNG",
"exportToSvg": "Εξαγωγή σε SVG",
"copyToClipboard": "Αντιγραφή στο πρόχειρο",
"copyPngToClipboard": "Αντιγραφή PNG στο πρόχειρο",
"scale": "Κλίμακα",
"save": "",
"save": "Αποθήκευση",
"saveAs": "Αποθήκευση ως",
"load": "Άνοιγμα",
"getShareableLink": "Δημόσιος σύνδεσμος",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Επιλογή",
"freedraw": "Ελεύθερο σχέδιο",
"rectangle": "Ορθογώνιο",
"diamond": "Ρόμβος",
"ellipse": "Έλλειψη",
"arrow": "Βέλος",
"line": "Γραμμή",
"freedraw": "",
"text": "Κείμενο",
"library": "Βιβλιοθήκη",
"lock": "Κράτησε επιλεγμένο το εργαλείο μετά το σχέδιο"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Σφάλμα"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Διαβάστε το Blog μας",
"click": "κλικ",

View File

@ -101,8 +101,6 @@
"viewMode": "View mode",
"toggleExportColorScheme": "Toggle export color scheme",
"share": "Share",
"showStroke": "Show stroke color picker",
"showBackground": "Show background color picker",
"toggleTheme": "Toggle theme"
},
"buttons": {

View File

@ -20,10 +20,6 @@
"background": "Fondo",
"fill": "Rellenar",
"strokeWidth": "Grosor del trazo",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Estilo del trazo",
"strokeStyle_solid": "Sólido",
"strokeStyle_dashed": "Discontinua",
@ -42,8 +38,8 @@
"fontSize": "Tamaño de la fuente",
"fontFamily": "Tipo de fuente",
"onlySelected": "Sólo seleccionados",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Con fondo",
"exportEmbedScene": "Insertar escena en el 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\"",
"handDrawn": "Dibujado a mano",
@ -100,20 +96,17 @@
"flipVertical": "Girar verticalmente",
"viewMode": "Modo presentación",
"toggleExportColorScheme": "Cambiar el esquema de colores de exportación",
"share": "Compartir",
"toggleTheme": "Alternar tema"
"share": "Compartir"
},
"buttons": {
"clearReset": "Limpiar lienzo y reiniciar el color de fondo",
"exportJSON": "",
"exportImage": "",
"export": "Exportar",
"exportToPng": "Exportar a PNG",
"exportToSvg": "Exportar a SVG",
"copyToClipboard": "Copiar al portapapeles",
"copyPngToClipboard": "Copiar PNG al portapapeles",
"scale": "Escalar",
"save": "",
"save": "Guardar",
"saveAs": "Guardar como",
"load": "Cargar",
"getShareableLink": "Obtener enlace para compartir",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Selección",
"freedraw": "Dibujo libre",
"rectangle": "Rectángulo",
"diamond": "Diamante",
"ellipse": "Elipse",
"arrow": "Flecha",
"line": "Línea",
"freedraw": "Dibujar",
"text": "Texto",
"library": "Biblioteca",
"lock": "Mantener la herramienta seleccionada activa después de dibujar"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Error"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Lee nuestro blog",
"click": "click",

View File

@ -20,10 +20,6 @@
"background": "پس زمینه",
"fill": "رنگ آمیزی",
"strokeWidth": "ضخامت خط",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "استایل خط",
"strokeStyle_solid": "یکدست",
"strokeStyle_dashed": "خط چین",
@ -42,8 +38,8 @@
"fontSize": "اندازه قلم",
"fontFamily": "نوع قلم",
"onlySelected": "فقط انتخاب شده ها",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "با پس زمینه",
"exportEmbedScene": "قرار دادن صحنه در فایل خروجی",
"exportEmbedScene_details": "متحوای صحنه به فایل خروجی SVG/PNG اضافه خواهد شد برای بازیابی صحنه به آن اضافه خواهد شد.\nباعث افزایش حجم فایل خروجی میشود.",
"addWatermark": "\"ساخته شده با Excalidraw\" را اضافه کن",
"handDrawn": "دست نویس",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "پاکسازی بوم نقاشی",
"exportJSON": "",
"exportImage": "",
"export": "تبدیل",
"exportToPng": "تبدیل به PNG",
"exportToSvg": "تبدیل به SVG",
"copyToClipboard": "کپی در حافظه موقت",
"copyPngToClipboard": "کپی PNG در حافظه موقت",
"scale": "مقیاس",
"save": "",
"save": "ذخیره",
"saveAs": "ذخیره با نام",
"load": "بارگذاری",
"getShareableLink": "دریافت لینک قابل اشتراک",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "گزینش",
"freedraw": "طراحی آزاد",
"rectangle": "مستطیل",
"diamond": "لوزی",
"ellipse": "بیضی",
"arrow": "پیکان",
"line": "خط",
"freedraw": "",
"text": "متن",
"library": "کتابخانه",
"lock": "ابزار انتخاب شده را بعد از کشیدن نگه دار"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "خطا"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "بلاگ ما را بخوانید",
"click": "",

View File

@ -20,10 +20,6 @@
"background": "Tausta",
"fill": "Täyttö",
"strokeWidth": "Viivan leveys",
"strokeShape": "Viivan muoto",
"strokeShape_gel": "Geelikynä",
"strokeShape_fountain": "Sulkakynä",
"strokeShape_brush": "Sivellinkynä",
"strokeStyle": "Viivan tyyli",
"strokeStyle_solid": "Yhtenäinen",
"strokeStyle_dashed": "Katkoviiva",
@ -42,8 +38,8 @@
"fontSize": "Kirjasinkoko",
"fontFamily": "Kirjasintyyppi",
"onlySelected": "Vain valitut",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Sisällytä tausta",
"exportEmbedScene": "Upota teos tiedostoon",
"exportEmbedScene_details": "Teoksen tiedot tallennetaan PNG/SVG-tiedostoon, jolloin teoksen voi palauttaa siitä. Kasvattaa tallennetun tiedoston kokoa.",
"addWatermark": "Lisää \"Tehty Excalidrawilla\"",
"handDrawn": "Käsinkirjoitettu",
@ -100,20 +96,17 @@
"flipVertical": "Käännä pystysuunnassa",
"viewMode": "Katselutila",
"toggleExportColorScheme": "Vaihda viennin väriteema",
"share": "Jaa",
"toggleTheme": "Vaihda teema"
"share": "Jaa"
},
"buttons": {
"clearReset": "Tyhjennä piirtoalue",
"exportJSON": "",
"exportImage": "",
"export": "Vie",
"exportToPng": "Vie PNG-tiedostona",
"exportToSvg": "Vie SVG-tiedostona",
"copyToClipboard": "Kopioi leikepöydälle",
"copyPngToClipboard": "Kopioi PNG-tiedosto leikepöydälle",
"scale": "Koko",
"save": "",
"save": "Tallenna",
"saveAs": "Tallenna nimellä",
"load": "Avaa",
"getShareableLink": "Hae jaettava linkki",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Valinta",
"freedraw": "Vapaa piirto",
"rectangle": "Suorakulmio",
"diamond": "Vinoneliö",
"ellipse": "Soikio",
"arrow": "Nuoli",
"line": "Viiva",
"freedraw": "Piirrä",
"text": "Teksti",
"library": "Kirjasto",
"lock": "Pidä valittu työkalu aktiivisena piirron jälkeen"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Virhe"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Lue blogiamme",
"click": "klikkaa",

View File

@ -20,10 +20,6 @@
"background": "Arrière-plan",
"fill": "Remplissage",
"strokeWidth": "Largeur du trait",
"strokeShape": "Forme du trait",
"strokeShape_gel": "Stylo à bille",
"strokeShape_fountain": "Stylo-plume",
"strokeShape_brush": "Pinceau",
"strokeStyle": "Style du trait",
"strokeStyle_solid": "Plein",
"strokeStyle_dashed": "Tirets",
@ -42,8 +38,8 @@
"fontSize": "Taille de la police",
"fontFamily": "Police",
"onlySelected": "Uniquement la sélection",
"withBackground": "Arrière-plan",
"exportEmbedScene": "Scène intégrée",
"withBackground": "Avec arrière-plan",
"exportEmbedScene": "Intégrer la scène au 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\"",
"handDrawn": "À main levée",
@ -100,20 +96,17 @@
"flipVertical": "Retourner verticalement",
"viewMode": "Mode présentation",
"toggleExportColorScheme": "Activer/Désactiver l'export du thème de couleur",
"share": "Partager",
"toggleTheme": "Changer le thème"
"share": "Partager"
},
"buttons": {
"clearReset": "Réinitialiser le canevas",
"exportJSON": "Exporter dans un fichier",
"exportImage": "Enregistrer comme image",
"export": "Exporter",
"exportToPng": "Exporter en PNG",
"exportToSvg": "Exporter en SVG",
"copyToClipboard": "Copier dans le presse-papier",
"copyPngToClipboard": "Copier le PNG vers le presse-papier",
"scale": "Échelle",
"save": "Sauvegarder dans le fichier actuel",
"save": "Sauvegarder",
"saveAs": "Enregistrer sous",
"load": "Ouvrir",
"getShareableLink": "Obtenir un lien de partage",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Sélection",
"freedraw": "Dessin libre",
"rectangle": "Rectangle",
"diamond": "Losange",
"ellipse": "Ellipse",
"arrow": "Flèche",
"line": "Ligne",
"freedraw": "Dessiner",
"text": "Texte",
"library": "Bibliothèque",
"lock": "Garder l'outil sélectionné actif après le dessin"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Erreur"
},
"exportDialog": {
"disk_title": "Sauvegarder sur le disque",
"disk_details": "Exportez les données de la scène dans un fichier que vous pourrez importer ultérieurement.",
"disk_button": "Sauvegarder dans un fichier",
"link_title": "Lien à partager",
"link_details": "Exporter comme un lien en lecture seule.",
"link_button": "Exporter vers un lien"
},
"helpDialog": {
"blog": "Lire notre blog",
"click": "clic",

View File

@ -20,10 +20,6 @@
"background": "רקע",
"fill": "מילוי",
"strokeWidth": "עובי קו מתאר",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "סגנון קו המתאר",
"strokeStyle_solid": "מלא",
"strokeStyle_dashed": "מקווקו",
@ -42,8 +38,8 @@
"fontSize": "גודל גופן",
"fontFamily": "סוג הגופן",
"onlySelected": "רק מה שנבחר",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "עם רקע",
"exportEmbedScene": "שלב את התצוגה בקובץ המיוצא",
"exportEmbedScene_details": "מידע התצוגה יישמר לקובץ המיוצא מסוג PNG/SVG כך שיהיה ניתן לשחזרה ממנו.\nהפעולה תגדיל את גודל הקובץ המיוצא.",
"addWatermark": "הוסף \"נוצר באמצעות Excalidraw\"",
"handDrawn": "כתב יד",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "מצב תצוגה",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "אפס את הלוח",
"exportJSON": "",
"exportImage": "",
"export": "ייצא",
"exportToPng": "יצא ל PNG",
"exportToSvg": "יצא ל SVG",
"copyToClipboard": "העתק ללוח",
"copyPngToClipboard": "העתק PNG ללוח",
"scale": "קנה מידה",
"save": "",
"save": "שמור",
"saveAs": "שמירה בשם",
"load": "טען",
"getShareableLink": "קבל קישור לשיתוף",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "בחירה",
"freedraw": "ציור חופשי",
"rectangle": "מרובע",
"diamond": "מעוין",
"ellipse": "אליפסה",
"arrow": "חץ",
"line": "קו",
"freedraw": "",
"text": "טקסט",
"library": "ספריה",
"lock": "השאר את הכלי הנבחר פעיל גם לאחר סיום הציור"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "שגיאה"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "קרא את הבלוג שלנו",
"click": "קליק",

View File

@ -20,10 +20,6 @@
"background": "पृष्ठभूमि",
"fill": "भरें",
"strokeWidth": "रेखा की चौड़ाई",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "स्ट्रोक का आकार",
"strokeStyle_solid": "ठोस",
"strokeStyle_dashed": "डैश",
@ -42,8 +38,8 @@
"fontSize": "फ़ॉन्ट का आकार",
"fontFamily": "फ़ॉन्ट का परिवार",
"onlySelected": "केवल चयनित",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "बैकग्राउंड के साथ",
"exportEmbedScene": "निर्यात एम्बेड दृश्य",
"exportEmbedScene_details": "निर्यात एम्बेड दृश्य विवरण",
"addWatermark": "ऐड \"मेड विथ एक्सकैलिडराव\"",
"handDrawn": "हाथ से बनाया हुआ",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "कैनवास रीसेट करें",
"exportJSON": "",
"exportImage": "",
"export": "निर्यात",
"exportToPng": "पीएनजी के रूप में निर्यात करे",
"exportToSvg": "Svg के रूप में निर्यात करे",
"copyToClipboard": "क्लिपबोर्ड पर प्रतिलिपि बनाएँ",
"copyPngToClipboard": "क्लिपबोर्ड पर कॉपी करें,पीएनजी के रूप में",
"scale": "पैमाना",
"save": "",
"save": "सहेजें",
"saveAs": "सेव करे इस तरह",
"load": "लोड करें",
"getShareableLink": "साझा करने योग्य लिंक प्राप्त करें",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "चयन",
"freedraw": "मुफ्त ड्रा",
"rectangle": "आयात",
"diamond": "तिर्यग्वर्ग",
"ellipse": "दीर्घवृत्त",
"arrow": "तीर",
"line": "रेखा",
"freedraw": "",
"text": "पाठ",
"library": "लाइब्रेरी",
"lock": "ड्राइंग के बाद चयनित टूल को सक्रिय रखें"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "गलती"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "हमारा ब्लॉग पढे",
"click": "क्लिक करें",

View File

@ -20,10 +20,6 @@
"background": "Háttér",
"fill": "Kitöltés",
"strokeWidth": "Körvonal vastagsága",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Körvonal stílusa",
"strokeStyle_solid": "Kitöltött",
"strokeStyle_dashed": "Szaggatott",
@ -42,8 +38,8 @@
"fontSize": "Betűméret",
"fontFamily": "Betűkészlet család",
"onlySelected": "Csak a kijelölt",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Háttérrel",
"exportEmbedScene": "Jelenet beágyazása az exportált fájlba",
"exportEmbedScene_details": "A jelenetet leíró adatok hozzá lesznek adva a PNG/SVG fájlhoz, így a jelenetet vissza lehet majd tölteni belőle. Ez megnöveli a fájl méretét.",
"addWatermark": "Add hozzá, hogy \"Excalidraw-val készült\"",
"handDrawn": "Kézzel rajzolt",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "Vászon törlése",
"exportJSON": "",
"exportImage": "",
"export": "Exportálás",
"exportToPng": "Exportálás PNG-be",
"exportToSvg": "Exportálás SVG-be",
"copyToClipboard": "Vágólapra másolás",
"copyPngToClipboard": "PNG másolása a vágólapra",
"scale": "Nagyítás",
"save": "",
"save": "Mentés",
"saveAs": "Mentés másként",
"load": "Betöltés",
"getShareableLink": "Megosztható link létrehozása",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Kijelölés",
"freedraw": "Szabadkézi rajz",
"rectangle": "Téglalap",
"diamond": "Rombusz",
"ellipse": "Ellipszis",
"arrow": "Nyíl",
"line": "Vonal",
"freedraw": "",
"text": "Szöveg",
"library": "Könyvtár",
"lock": "Rajzolás után az aktív eszközt tartsa kijelölve"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Hiba"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "",
"click": "",

View File

@ -20,10 +20,6 @@
"background": "Latar",
"fill": "Isian",
"strokeWidth": "Lebar guratan",
"strokeShape": "Bentuk guratan",
"strokeShape_gel": "Pena gel",
"strokeShape_fountain": "Pena gunung",
"strokeShape_brush": "Kuas",
"strokeStyle": "Gaya guratan",
"strokeStyle_solid": "Padat",
"strokeStyle_dashed": "Putus-putus",
@ -42,8 +38,8 @@
"fontSize": "Ukuran font",
"fontFamily": "Jenis font",
"onlySelected": "Hanya yang Dipilih",
"withBackground": "Latar",
"exportEmbedScene": "Sematkan pemandangan",
"withBackground": "Dengan latar",
"exportEmbedScene": "Sematkan pemandangan ke dalam file yang diekspor",
"exportEmbedScene_details": "Data pemandangan akan disimpan dalam file PNG/SVG yang diekspor, sehingga pemandangan itu dapat dipulihkan darinya.\nAkan membesarkan ukuran file yang diekspor.",
"addWatermark": "Tambahkan \"Dibuat dengan Excalidraw\"",
"handDrawn": "Tulisan tangan",
@ -100,20 +96,17 @@
"flipVertical": "Balikkan vertikal",
"viewMode": "Mode tampilan",
"toggleExportColorScheme": "Ubah skema warna ekspor",
"share": "Bagikan",
"toggleTheme": "Ubah tema"
"share": "Bagikan"
},
"buttons": {
"clearReset": "Setel Ulang Kanvas",
"exportJSON": "Ekspor ke file",
"exportImage": "Simpan gambar",
"export": "Ekspor",
"exportToPng": "Ekspor ke PNG",
"exportToSvg": "Ekspor ke SVG",
"copyToClipboard": "Salin ke Papan Klip",
"copyPngToClipboard": "Salin PNG ke papan klip",
"scale": "Skala",
"save": "Simpan ke file sekarang",
"save": "Simpan",
"saveAs": "Simpan sebagai",
"load": "Muat",
"getShareableLink": "Buat Tautan yang Bisa Dibagian",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Pilihan",
"freedraw": "Menggambar bebas",
"rectangle": "Persegi",
"diamond": "Berlian",
"ellipse": "Elips",
"arrow": "Panah",
"line": "Garis",
"freedraw": "Gambar",
"text": "Teks",
"library": "Pustaka",
"lock": "Biarkan alat yang dipilih aktif setelah menggambar"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Kesalahan"
},
"exportDialog": {
"disk_title": "Simpan ke disk",
"disk_details": "Ekspor data pemandangan ke file yang mana Anda dapat impor nanti.",
"disk_button": "Simpan ke file",
"link_title": "Tautan",
"link_details": "Ekspor sebagai tautan yang hanya dibaca.",
"link_button": "Ekspor ke tautan"
},
"helpDialog": {
"blog": "Baca blog kami",
"click": "klik",

View File

@ -20,10 +20,6 @@
"background": "Sfondo",
"fill": "Riempimento",
"strokeWidth": "Spessore del tratto",
"strokeShape": "Forma del tratto",
"strokeShape_gel": "Penna gel",
"strokeShape_fountain": "Penna stilografica",
"strokeShape_brush": "Pennello",
"strokeStyle": "Stile del tratto",
"strokeStyle_solid": "Pieno",
"strokeStyle_dashed": "Tratteggiato",
@ -42,8 +38,8 @@
"fontSize": "Dimensione carattere",
"fontFamily": "Carattere",
"onlySelected": "Solo selezionati",
"withBackground": "Sfondo",
"exportEmbedScene": "Includi scena",
"withBackground": "Con sfondo",
"exportEmbedScene": "Incorpora la scena nel file esportato",
"exportEmbedScene_details": "I dati della scena saranno salvati nel file PNG/SVG esportato in modo che la scena possa essere ripristinata da esso.\nQuesto aumenterà la dimensione del file esportato.",
"addWatermark": "Aggiungi \"Creato con Excalidraw\"",
"handDrawn": "A mano libera",
@ -100,20 +96,17 @@
"flipVertical": "Capovolgi verticalmente",
"viewMode": "Modalità visualizzazione",
"toggleExportColorScheme": "Cambia lo schema di colori in esportazione",
"share": "Condividi",
"toggleTheme": "Cambia tema"
"share": "Condividi"
},
"buttons": {
"clearReset": "Svuota la tela",
"exportJSON": "Esporta su file",
"exportImage": "Salva come immagine",
"export": "Esporta",
"exportToPng": "Esporta come PNG",
"exportToSvg": "Esporta come SVG",
"copyToClipboard": "Copia negli appunti",
"copyPngToClipboard": "Copia PNG negli appunti",
"scale": "Scala",
"save": "Salva sul file corrente",
"save": "Salva",
"saveAs": "Salva con nome",
"load": "Carica",
"getShareableLink": "Ottieni link condivisibile",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Selezione",
"freedraw": "Disegno libero",
"rectangle": "Rettangolo",
"diamond": "Rombo",
"ellipse": "Ellisse",
"arrow": "Freccia",
"line": "Linea",
"freedraw": "",
"text": "Testo",
"library": "Libreria",
"lock": "Mantieni lo strumento selezionato attivo dopo aver disegnato"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Errore"
},
"exportDialog": {
"disk_title": "Salva su disco",
"disk_details": "Esporta i dati della scena su file, dal quale potrai importare in seguito.",
"disk_button": "Salva su file",
"link_title": "Link condivisibile",
"link_details": "Esporta come link di sola lettura.",
"link_button": "Esporta come Link"
},
"helpDialog": {
"blog": "Leggi il nostro blog",
"click": "click",

View File

@ -20,10 +20,6 @@
"background": "背景の色",
"fill": "塗りつぶし",
"strokeWidth": "線の幅",
"strokeShape": "ストロークの形状",
"strokeShape_gel": "ジェルペン",
"strokeShape_fountain": "噴水ペン",
"strokeShape_brush": "ブラシペン",
"strokeStyle": "線の種類",
"strokeStyle_solid": "実線",
"strokeStyle_dashed": "破線",
@ -42,8 +38,8 @@
"fontSize": "フォントの大きさ",
"fontFamily": "フォントの種類",
"onlySelected": "選択中のみ",
"withBackground": "背景",
"exportEmbedScene": "",
"withBackground": "背景を含める",
"exportEmbedScene": "エクスポートされたファイルにシーンを埋め込みます",
"exportEmbedScene_details": "シーンデータはエクスポートされたPNG/SVGファイルに保存され、シーンを復元することができます。\nエクスポートされたファイルのサイズは増加します。",
"addWatermark": "\"Made with Excalidraw\"と表示",
"handDrawn": "手描き風",
@ -100,20 +96,17 @@
"flipVertical": "垂直方向に反転",
"viewMode": "閲覧モード",
"toggleExportColorScheme": "",
"share": "共有",
"toggleTheme": "テーマの切り替え"
"share": ""
},
"buttons": {
"clearReset": "キャンバスのリセット",
"exportJSON": "ファイルへエクスポート",
"exportImage": "画像として保存",
"export": "エクスポート",
"exportToPng": "PNG にエクスポート",
"exportToSvg": "SVG にエクスポート",
"copyToClipboard": "クリップボードにコピー",
"copyPngToClipboard": "クリップボードにPNGをコピー",
"scale": "スケール",
"save": "現在のファイルに保存",
"save": "保存",
"saveAs": "名前を付けて保存",
"load": "読み込み...",
"getShareableLink": "共有URLの取得",
@ -149,22 +142,22 @@
"loadSceneOverridePrompt": "外部図面を読み込むと、既存のコンテンツが置き換わります。続行しますか?",
"collabStopOverridePrompt": "セッションを停止すると、ローカルに保存されている図が上書きされます。 本当によろしいですか?\n\n(ローカルの図を保持したい場合は、セッションを停止せずにブラウザタブを閉じてください。)",
"errorLoadingLibrary": "サードパーティライブラリの読み込み中にエラーが発生しました。",
"errorAddingToLibrary": "アイテムをライブラリに追加できませんでした",
"errorRemovingFromLibrary": "ライブラリからアイテムを削除できませんでした",
"errorAddingToLibrary": "",
"errorRemovingFromLibrary": "",
"confirmAddLibrary": "{{numShapes}} 個の図形をライブラリに追加します。よろしいですか?",
"imageDoesNotContainScene": "現在、画像のインポートはサポートされていません。\n\nシーンをインポートしようとしましたかこの画像にはシーンデータが含まれていないようです。エクスポート中に有効にしていましたか",
"cannotRestoreFromImage": "このイメージファイルからシーンを復元できませんでした",
"invalidSceneUrl": "指定された URL からシーンをインポートできませんでした。不正な形式であるか、有効な Excalidraw JSON データが含まれていません。",
"invalidSceneUrl": "",
"resetLibrary": "ライブラリを消去します。本当によろしいですか?"
},
"toolBar": {
"selection": "選択",
"freedraw": "手書き",
"rectangle": "矩形",
"diamond": "ひし形",
"ellipse": "楕円",
"arrow": "矢印",
"line": "直線",
"freedraw": "描画",
"text": "テキスト",
"library": "ライブラリ",
"lock": "描画後も使用中のツールを選択したままにする"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "エラー"
},
"exportDialog": {
"disk_title": "ディスクに保存",
"disk_details": "シーンデータを後からインポートできるファイルにエクスポートします。",
"disk_button": "ファイルへ保存",
"link_title": "共有可能なリンク",
"link_details": "読み取り専用リンクとしてエクスポート",
"link_button": "リンクとしてエクスポート"
},
"helpDialog": {
"blog": "公式ブログを読む",
"click": "クリック",
@ -268,10 +253,10 @@
"toast": {
"copyStyles": "スタイルをコピー",
"copyToClipboard": "クリップボードにコピー",
"copyToClipboardAsPng": "{{exportSelection}} を PNG 形式でクリップボードにコピーしました\n({{exportColorScheme}})",
"copyToClipboardAsPng": "",
"fileSaved": "ファイルを保存しました",
"fileSavedToFilename": "{filename} に保存しました",
"canvas": "キャンバス",
"selection": "選択"
"selection": ""
}
}

View File

@ -20,10 +20,6 @@
"background": "Agilal",
"fill": "Taččart",
"strokeWidth": "Tehri n yizirig",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "Amfezzu",
"strokeStyle": "Aɣanib n tizirig",
"strokeStyle_solid": "Aččuran",
"strokeStyle_dashed": "S tjerriḍin",
@ -42,8 +38,8 @@
"fontSize": "Tiddi n tsefsit",
"fontFamily": "Tawacult n tsefsiyin",
"onlySelected": "Tafrayt kan",
"withBackground": "Agilal",
"exportEmbedScene": "Sleɣ asayes",
"withBackground": "S ugilal",
"exportEmbedScene": "Seddu asayes deg ufaylu yettwasifḍen",
"exportEmbedScene_details": "Asayes ad yettwasekles deg ufaylu n usifeḍ PNG/SVG akken akken ad yili wamek ara d-yettwarr seg-s usayes. Ayagi ad isimɣur tiddi n ufaylu n usifeḍ.",
"addWatermark": "Seddu \"Yettwaxdem s Excalidraw\"",
"handDrawn": "Asuneɣ s ufus",
@ -100,20 +96,17 @@
"flipVertical": "Tuttya tubdidt",
"viewMode": "Askar n tmuɣli",
"toggleExportColorScheme": "Sermed/sens asifeḍ usentel n yini",
"share": "Bḍu",
"toggleTheme": "Snifel asentel"
"share": "Bḍu"
},
"buttons": {
"clearReset": "Ales awennez n teɣzut n usuneɣ",
"exportJSON": "Sifeḍ afaylu",
"exportImage": "Sekles am tugna",
"export": "Sifeḍ",
"exportToPng": "Sifeḍ ɣer PNG",
"exportToSvg": "Sifeḍ ɣer SVG",
"copyToClipboard": "Nɣel ɣer tecfawit",
"copyPngToClipboard": "Nɣel PNG ɣer tecfawit",
"scale": "Taskala",
"save": "Sekles deg ufaylu amiran",
"save": "Sekles",
"saveAs": "Sekles am",
"load": "Sali-d",
"getShareableLink": "Awi-d aseɣwen n beṭṭu",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Tafrayt",
"freedraw": "Unuɣ ilelli",
"rectangle": "Asrem",
"diamond": "Ameɣṛun",
"ellipse": "Taglayt",
"arrow": "Taneccabt",
"line": "Izirig",
"freedraw": "Suneɣ",
"text": "Aḍris",
"library": "Tamkarḍit",
"lock": "Eǧǧ afecku n tefrayt yermed mbaɛd asuneɣ"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Tuccḍa"
},
"exportDialog": {
"disk_title": "Sekles deg uḍebsi",
"disk_details": "Sekles isefka n usayes deg ufaylu ansi ara tizmireḍ ad d-tketreḍ areḍqal.",
"disk_button": "Sekles deg ufaylu",
"link_title": "Aseɣwen n beṭṭu",
"link_details": "Sifeḍ am useɣwen n tɣuri kan.",
"link_button": "Sifeḍ deg useɣwen"
},
"helpDialog": {
"blog": "Ɣeṛ ablug-nneɣ",
"click": "ssit",

View File

@ -20,10 +20,6 @@
"background": "배경색",
"fill": "채우기",
"strokeWidth": "선 굵기",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "선",
"strokeStyle_solid": "실선",
"strokeStyle_dashed": "파선",
@ -42,8 +38,8 @@
"fontSize": "글자 크기",
"fontFamily": "글꼴",
"onlySelected": "선택한 항목만",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "배경 포함",
"exportEmbedScene": "화면을 내보낸 파일에 담기",
"exportEmbedScene_details": "화면 정보가 내보내는 PNG/SVG 파일에 저장되어 이후에 파일에서 화면을 복구할 수 있습니다. 파일 크기가 증가합니다.",
"addWatermark": "\"Made with Excalidraw\" 추가",
"handDrawn": "손글씨",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "보기 모드",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "캔버스 초기화",
"exportJSON": "",
"exportImage": "",
"export": "내보내기",
"exportToPng": "PNG로 내보내기",
"exportToSvg": "SVG로 내보내기",
"copyToClipboard": "클립보드로 복사",
"copyPngToClipboard": "클립보드로 PNG 이미지 복사",
"scale": "크기",
"save": "",
"save": "저장",
"saveAs": "다른 이름으로 저장",
"load": "불러오기",
"getShareableLink": "공유 가능한 링크 생성",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "선택",
"freedraw": "자유롭게 그리기",
"rectangle": "사각형",
"diamond": "다이아몬드",
"ellipse": "타원",
"arrow": "화살표",
"line": "선",
"freedraw": "",
"text": "텍스트",
"library": "라이브러리",
"lock": "선택된 도구 유지하기"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "오류"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "블로그 읽어보기",
"click": "클릭",

View File

@ -1,47 +1,43 @@
{
"labels": {
"paste": "Ielīmēt",
"pasteCharts": "Ielīmēt grafikus",
"selectAll": "Iezīmēt visu",
"multiSelect": "Pievienot elementu iezīmētajam",
"moveCanvas": "Pārvietot darba laukumu",
"cut": "Izgriezt",
"copy": "Kopēt",
"copyAsPng": "Kopēt starpliktuvē kā PNG",
"copyAsSvg": "Kopēt starpliktuvē kā SVG",
"bringForward": "Pārvietot vienu slāni augstāk",
"sendToBack": "Pārvietot uz zemāko slāni",
"bringToFront": "Pārvietot uz virsējo slāni",
"sendBackward": "Pārvietot par vienu slāni zemāk",
"delete": "Dzēst",
"copyStyles": "Kopēt stilus",
"pasteStyles": "Ielīmēt stilus",
"stroke": "Līnija",
"background": "Fons",
"fill": "Aizpildījums",
"strokeWidth": "Līnijas platums",
"strokeShape": "Līnijas forma",
"strokeShape_gel": "Gēla pildspalva",
"strokeShape_fountain": "Lodīšu pildspalva",
"strokeShape_brush": "Flomāsters - ota",
"strokeStyle": "Līnijas forma",
"strokeStyle_solid": "Vienlaidu",
"strokeStyle_dashed": "Raustīta līnija",
"strokeStyle_dotted": "Punktota līnija",
"sloppiness": "Precizitāte",
"opacity": "Necaurspīdīgums",
"textAlign": "Teksta izkārtojums",
"edges": "Malas",
"sharp": "Asas",
"round": "Apaļas",
"arrowheads": "Bultas",
"arrowhead_none": "Nekādas",
"arrowhead_arrow": "Bulta",
"arrowhead_bar": "Svītra",
"arrowhead_dot": "Punkts",
"fontSize": "Teksta lielums",
"fontFamily": "Fontu saime",
"onlySelected": "Tikai iezīmētais",
"paste": "",
"pasteCharts": "",
"selectAll": "",
"multiSelect": "",
"moveCanvas": "",
"cut": "",
"copy": "",
"copyAsPng": "",
"copyAsSvg": "",
"bringForward": "",
"sendToBack": "",
"bringToFront": "",
"sendBackward": "",
"delete": "",
"copyStyles": "",
"pasteStyles": "",
"stroke": "",
"background": "",
"fill": "",
"strokeWidth": "",
"strokeStyle": "",
"strokeStyle_solid": "",
"strokeStyle_dashed": "",
"strokeStyle_dotted": "",
"sloppiness": "",
"opacity": "",
"textAlign": "",
"edges": "",
"sharp": "",
"round": "",
"arrowheads": "",
"arrowhead_none": "",
"arrowhead_arrow": "",
"arrowhead_bar": "",
"arrowhead_dot": "",
"fontSize": "",
"fontFamily": "",
"onlySelected": "",
"withBackground": "",
"exportEmbedScene": "",
"exportEmbedScene_details": "",
@ -100,13 +96,10 @@
"flipVertical": "",
"viewMode": "",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "",
"exportJSON": "",
"exportImage": "",
"export": "",
"exportToPng": "",
"exportToSvg": "",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "",
"draw": "",
"rectangle": "",
"diamond": "",
"ellipse": "",
"arrow": "",
"line": "",
"freedraw": "",
"text": "",
"library": "",
"lock": ""
@ -217,14 +210,6 @@
"errorDialog": {
"title": ""
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "",
"click": "",

View File

@ -20,10 +20,6 @@
"background": "နောက်ခံ",
"fill": "ဖြည့်",
"strokeWidth": "မျဉ်းအထူ",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "မျဉ်းပုံစံ",
"strokeStyle_solid": "အပြည့်",
"strokeStyle_dashed": "မျဉ်းပြတ်",
@ -43,7 +39,7 @@
"fontFamily": "စာလုံးပုံစံ",
"onlySelected": "ရွေးထားသလောက်",
"withBackground": "",
"exportEmbedScene": "",
"exportEmbedScene": "မြင်ကွင်းပါမြှုပ်နှံ၍ထုတ်ပါ",
"exportEmbedScene_details": "ထုတ်ယူလိုက်သော PNG/SVG ထဲမြင်ကွင်းအချက်အလက်များပါဝင်သဖြင့် ပြန်လည်ရယူနိုင်သော်လည်း ဖိုင်အရွယ်အစားကြီးပါမည်။",
"addWatermark": "\"Excalidraw ဖြင့်ဖန်တီးသည်။\" စာသားထည့်",
"handDrawn": "လက်ရေး",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "ကားချပ်ရှင်းလင်း",
"exportJSON": "",
"exportImage": "",
"export": "ထုတ်",
"exportToPng": "PNG ထုတ်",
"exportToSvg": "SVG ထုတ်",
"copyToClipboard": "ကူးယူ",
"copyPngToClipboard": "PNG ကူးယူ",
"scale": "စကေး",
"save": "",
"save": "သိမ်း",
"saveAs": "ပြောင်းသိမ်း",
"load": "တင်သွင်း",
"getShareableLink": "မျှဝေရန် လင့်ခ်ရယူ",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "ရွေးချယ်",
"freedraw": "အလွတ်ရေးဆွဲ",
"rectangle": "စတုဂံ",
"diamond": "စိန်",
"ellipse": "အဝိုင်း",
"arrow": "မြှား",
"line": "မျဉ်း",
"freedraw": "",
"text": "စာသား",
"library": "မှတ်တမ်း",
"lock": "ရွေးချယ်ထားသောကိရိယာကိုသာဆက်သုံး"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "ချို့ယွင်းချက်"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "",
"click": "",

View File

@ -20,10 +20,6 @@
"background": "Bakgrunn",
"fill": "Fyll",
"strokeWidth": "Strektykkelse",
"strokeShape": "Strekstil",
"strokeShape_gel": "Gelepenn",
"strokeShape_fountain": "Fyllepenn",
"strokeShape_brush": "Pensel",
"strokeStyle": "Strekstil",
"strokeStyle_solid": "Heltrukket",
"strokeStyle_dashed": "Stiplet",
@ -42,8 +38,8 @@
"fontSize": "Skriftstørrelse",
"fontFamily": "Fontfamilie",
"onlySelected": "Kun valgte",
"withBackground": "Bakgrunn",
"exportEmbedScene": "Bygg inn scene",
"withBackground": "Med bakgrunn",
"exportEmbedScene": "Bygg inn scenen i den eksporterte filen",
"exportEmbedScene_details": "Scenedata vil bli lagret i den eksporterte PNG/SVG-filen, slik at scenen kan gjenopprettes fra den.\nDet vil øke den eksporterte filstørrelsen.",
"addWatermark": "Legg til \"Laget med Excalidraw\"",
"handDrawn": "Håndtegnet",
@ -100,20 +96,17 @@
"flipVertical": "Snu vertikalt",
"viewMode": "Visningsmodus",
"toggleExportColorScheme": "Veksle eksport av fargepalett",
"share": "Del",
"toggleTheme": "Veksle tema"
"share": "Del"
},
"buttons": {
"clearReset": "Tøm lerretet og tilbakestill bakgrunnsfargen",
"exportJSON": "Eksporter til fil",
"exportImage": "Lagre som bilde",
"export": "Eksporter",
"exportToPng": "Eksporter til PNG",
"exportToSvg": "Eksporter til SVG",
"copyToClipboard": "Kopier til utklippstavle",
"copyPngToClipboard": "Kopier PNG til utklippstavlen",
"scale": "Skalering",
"save": "Lagre til aktiv fil",
"save": "Lagre",
"saveAs": "Lagre som",
"load": "Åpne",
"getShareableLink": "Få delingslenke",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Velg",
"freedraw": "Frihåndstegning",
"rectangle": "Rektangel",
"diamond": "Diamant",
"ellipse": "Ellipse",
"arrow": "Pil",
"line": "Linje",
"freedraw": "Tegn",
"text": "Tekst",
"library": "Bibliotek",
"lock": "Behold merket verktøy som aktivt"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Feil"
},
"exportDialog": {
"disk_title": "Lagre til disk",
"disk_details": "Eksporter scene-dataene til en fil som du kan importere fra senere.",
"disk_button": "Lagre til fil",
"link_title": "Delbar lenke",
"link_details": "Eksporter som en skrivebeskyttet lenke.",
"link_button": "Eksporter til lenke"
},
"helpDialog": {
"blog": "Les bloggen vår",
"click": "klikk",

View File

@ -20,10 +20,6 @@
"background": "Achtergrond",
"fill": "Invulling",
"strokeWidth": "Lijnbreedte",
"strokeShape": "Lijnstijl",
"strokeShape_gel": "Gel pen",
"strokeShape_fountain": "Vulpen",
"strokeShape_brush": "Penseel",
"strokeStyle": "Lijnstijl",
"strokeStyle_solid": "Ononderbroken",
"strokeStyle_dashed": "Gestreept",
@ -42,8 +38,8 @@
"fontSize": "Tekstgrootte",
"fontFamily": "Lettertype",
"onlySelected": "Enkel geselecteerde",
"withBackground": "Achtergrond",
"exportEmbedScene": "Scène insluiten",
"withBackground": "Met achtergrond",
"exportEmbedScene": "Scène in geëxporteerd bestand invoegen",
"exportEmbedScene_details": "Scènegegevens worden in het geëxporteerde PNG/SVG-bestand opgeslagen zodat de scène kan worden hersteld.\nDe grootte van de geëxporteerde bestanden zal toenemen.",
"addWatermark": "Voeg \"Gemaakt met Excalidraw\" toe",
"handDrawn": "Handgetekend",
@ -100,20 +96,17 @@
"flipVertical": "Verticaal spiegelen",
"viewMode": "Weergavemodus",
"toggleExportColorScheme": "Kleurenschema exporteren aan/uit",
"share": "Deel",
"toggleTheme": "Thema aan/uit"
"share": "Deel"
},
"buttons": {
"clearReset": "Canvas opnieuw instellen",
"exportJSON": "Exporteren naar bestand",
"exportImage": "Als afbeelding opslaan",
"export": "Exporteren",
"exportToPng": "Exporteren naar PNG",
"exportToSvg": "Exporteren naar SVG",
"copyToClipboard": "Kopieer",
"copyPngToClipboard": "Kopieer als PNG",
"scale": "Schaal",
"save": "Opslaan naar huidige bestand",
"save": "Opslaan",
"saveAs": "Opslaan als",
"load": "Open",
"getShareableLink": "Maak een deelbare link",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Selectie",
"freedraw": "Vrij tekenen",
"rectangle": "Rechthoek",
"diamond": "Ruit",
"ellipse": "Ovaal",
"arrow": "Pijl",
"line": "Lijn",
"freedraw": "Tekenen",
"text": "Tekst",
"library": "Bibliotheek",
"lock": "Geselecteerde tool actief houden na tekenen"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Fout"
},
"exportDialog": {
"disk_title": "Opslaan op schijf",
"disk_details": "De scènegegevens exporteren naar een bestand waaruit u later kunt importeren.",
"disk_button": "Opslaan naar bestand",
"link_title": "Deelbare link",
"link_details": "Exporteren als een alleen-lezen link.",
"link_button": "Exporteer naar link"
},
"helpDialog": {
"blog": "Lees onze blog",
"click": "klik",

View File

@ -20,10 +20,6 @@
"background": "Bakgrunn",
"fill": "Fyll",
"strokeWidth": "Strekbreidd",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Strekstil",
"strokeStyle_solid": "Solid",
"strokeStyle_dashed": "Stipla",
@ -42,8 +38,8 @@
"fontSize": "Skriftstorleik",
"fontFamily": "Skrifttype",
"onlySelected": "Kun valde",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Med bakgrunn",
"exportEmbedScene": "Bygg scena inn i eksportert fil",
"exportEmbedScene_details": "Scenedata vert lagra i den eksporterte PNG- eller SVG-fila slik at scena kan bli gjenopprettast frå den. Dette vil auke eksportert filstorleik.",
"addWatermark": "Legg til «Laga med Excalidraw»",
"handDrawn": "Handteikna",
@ -100,20 +96,17 @@
"flipVertical": "Vipp loddrett",
"viewMode": "Visningsmodus",
"toggleExportColorScheme": "Veksle eksport av fargepalett",
"share": "Del",
"toggleTheme": ""
"share": "Del"
},
"buttons": {
"clearReset": "Tilbakestill lerretet",
"exportJSON": "",
"exportImage": "",
"export": "Eksporter",
"exportToPng": "Eksporter til PNG",
"exportToSvg": "Eksporter til SVG",
"copyToClipboard": "Kopier til utklippstavla",
"copyPngToClipboard": "Kopier PNG til utklippstavla",
"scale": "Skaler",
"save": "",
"save": "Lagre",
"saveAs": "Lagre som",
"load": "Opne",
"getShareableLink": "Hent delingslenke",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Vel",
"freedraw": "Frihandsteikning",
"rectangle": "Rektangel",
"diamond": "Diamant",
"ellipse": "Ellipse",
"arrow": "Pil",
"line": "Linje",
"freedraw": "",
"text": "Tekst",
"library": "Bibliotek",
"lock": "Hald fram med valt verktøy"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Feil"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Les bloggen vår",
"click": "klikk",

View File

@ -20,10 +20,6 @@
"background": "Rèireplan",
"fill": "Empliment",
"strokeWidth": "Largor de contorn",
"strokeShape": "Fòrma del trach",
"strokeShape_gel": "Estilo gèl",
"strokeShape_fountain": "Calam",
"strokeShape_brush": "Pincèl",
"strokeStyle": "Estil de contorn",
"strokeStyle_solid": "Solide",
"strokeStyle_dashed": "Tiret",
@ -42,8 +38,8 @@
"fontSize": "Talha poliça",
"fontFamily": "Familha de poliça",
"onlySelected": "Seleccion sonque",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Inclure lo rèireplan",
"exportEmbedScene": "Integrar la scèna al fichièr dexpo",
"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 daqueste fichièr.\nAumentarà la talha del fichièr exportat.",
"addWatermark": "Apondre «Fabricat amb Excalidraw»",
"handDrawn": "A la man levada",
@ -100,20 +96,17 @@
"flipVertical": "Virar verticalament",
"viewMode": "Mòde de vista",
"toggleExportColorScheme": "Alternar lesquèma de color dexpòrt",
"share": "Partejar",
"toggleTheme": "Alternar tèma"
"share": "Partejar"
},
"buttons": {
"clearReset": "Reïnicializar lo canabàs",
"exportJSON": "",
"exportImage": "",
"export": "Exportar",
"exportToPng": "Exportar en PNG",
"exportToSvg": "Exportar en SVG",
"copyToClipboard": "Copiar al quichapapièrs",
"copyPngToClipboard": "Copiar PNG al quichapapièrs",
"scale": "Escala",
"save": "",
"save": "Enregistrar",
"saveAs": "Enregistrar jos",
"load": "Cargar",
"getShareableLink": "Obténer lo ligam de partatge",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Seleccion",
"freedraw": "Dessenh liure",
"rectangle": "Rectangle",
"diamond": "Lausange",
"ellipse": "Ellipsa",
"arrow": "Sageta",
"line": "Linha",
"freedraw": "Dessenhar",
"text": "Tèxt",
"library": "Bibliotèca",
"lock": "Mantenir activa laisina aprèp dessenhar"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Error"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Legir nòstre blog",
"click": "clic",

View File

@ -20,10 +20,6 @@
"background": "ਬੈਕਗਰਾਉਂਡ",
"fill": "ਭਰਨਾ",
"strokeWidth": "ਰੇਖਾ ਦੀ ਚੌੜਾਈ",
"strokeShape": "",
"strokeShape_gel": "ਜੈੱਲ ਪੈੱਨ",
"strokeShape_fountain": "ਫਾਉਨਟੇਨ ਪੈੱਨ",
"strokeShape_brush": "ਬੁਰਸ਼ ਪੈੱਨ",
"strokeStyle": "ਰੇਖਾ ਦਾ ਸਟਾਇਲ",
"strokeStyle_solid": "ਠੋਸ",
"strokeStyle_dashed": "ਡੈਸ਼ ਵਾਲੀ",
@ -42,8 +38,8 @@
"fontSize": "ਫੌਂਟ ਅਕਾਰ",
"fontFamily": "ਫੌਂਟ ਪਰਿਵਾਰ",
"onlySelected": "ਸਿਰਫ ਚੁਣੇ ਹੋਏ ਹੀ",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "ਬੈਕਗਰਾਉਂਂਡ ਨਾਲ",
"exportEmbedScene": "ਦ੍ਰਿਸ਼ ਨੂੰ ਨਿਰਯਾਤ ਕੀਤੀ ਫਾਈਲ ਵਿੱਚ ਮੜ੍ਹੋ",
"exportEmbedScene_details": "ਦ੍ਰਿਸ਼ ਦਾ ਡਾਟਾ ਨਿਰਯਾਤ ਕੀਤੀ PNG/SVG ਫਾਈਲ ਵਿੱਚ ਸਾਂਭ ਦਿੱਤਾ ਜਾਵੇਗਾ ਤਾਂ ਜੋ ਇਸ ਵਿੱਚੋਂ ਦ੍ਰਿਸ਼ ਨੂੰ ਬਹਾਲ ਕੀਤਾ ਜਾ ਸਕੇ। ਇਹ ਨਿਰਯਾਤ ਕੀਤੀ ਜਾਣ ਵਾਲੀ ਫਾਈਲ ਦਾ ਅਕਾਰ ਵਧਾ ਦੇਵੇਗਾ।",
"addWatermark": "\"Excalidraw ਨਾਲ ਬਣਾਇਆ\" ਜੋੜੋ",
"handDrawn": "ਹੱਥਲਿਖਤ",
@ -65,14 +61,14 @@
"architect": "ਭਵਨ ਨਿਰਮਾਣਕਾਰੀ",
"artist": "ਕਲਾਕਾਰ",
"cartoonist": "ਕਾਰਟੂਨਿਸਟ",
"fileTitle": "ਫਾਈਲ ਦਾ ਨਾਂ",
"fileTitle": "",
"colorPicker": "ਰੰਗ ਚੋਣਕਾਰ",
"canvasBackground": "ਕੈਨਵਸ ਦਾ ਬੈਕਗਰਾਉਂਡ",
"drawingCanvas": "ਡਰਾਇੰਗ ਕੈਨਵਸ",
"layers": "ਪਰਤਾਂ",
"actions": "ਕਾਰਵਾਈਆਂ",
"language": "ਭਾਸ਼ਾ",
"liveCollaboration": "ਲਾਇਵ ਸਹਿਯੋਗ",
"liveCollaboration": "",
"duplicateSelection": "ਡੁਪਲੀਕੇਟ ਬਣਾਓ",
"untitled": "ਬੇ-ਸਿਰਨਾਵਾਂ",
"name": "ਨਾਂ",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "ਦੇਖੋ ਮੋਡ",
"toggleExportColorScheme": "",
"share": "ਸਾਂਝਾ ਕਰੋ",
"toggleTheme": "ਥੀਮ ਬਦਲੋ"
"share": ""
},
"buttons": {
"clearReset": "ਕੈਨਵਸ ਰੀਸੈੱਟ ਕਰੋ",
"exportJSON": "",
"exportImage": "",
"export": "ਨਿਰਯਾਤ",
"exportToPng": "PNG ਵਿੱਚ ਨਿਰਯਾਤ ਕਰੋ",
"exportToSvg": "SVG ਵਿੱਚ ਨਿਰਯਾਤ ਕਰੋ",
"copyToClipboard": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰੋ",
"copyPngToClipboard": "PNG ਨੂੰ ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰੋ",
"scale": "ਪੈਮਾਇਸ਼",
"save": "",
"save": "ਸਾਂਭੋ",
"saveAs": "ਇਸ ਵਜੋਂ ਸਾਂਭੋ",
"load": "ਲੋਡ ਕਰੋ",
"getShareableLink": "ਸਾਂਝੀ ਕਰਨ ਵਾਲੀ ਲਿੰਕ ਲਵੋ",
@ -128,7 +121,7 @@
"edit": "ਸੋਧੋ",
"undo": "ਅਣਕੀਤਾ ਕਰੋ",
"redo": "ਮੁੜ-ਕਰੋ",
"resetLibrary": "ਲਾਇਬ੍ਰੇਰੀ ਰੀਸੈੱਟ ਕਰੋ",
"resetLibrary": "",
"createNewRoom": "ਨਵਾਂ ਕਮਰਾ ਬਣਾਓ",
"fullScreen": "ਪੂਰੀ ਸਕਰੀਨ",
"darkMode": "ਡਾਰਕ ਮੋਡ",
@ -149,22 +142,22 @@
"loadSceneOverridePrompt": "ਬਾਹਰੀ ਡਰਾਇੰਗ ਨੂੰ ਲੋਡ ਕਰਨਾ ਤੁਹਾਡੀ ਮੌਜੂਦਾ ਸਮੱਗਰੀ ਦੀ ਥਾਂ ਲੈ ਲਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
"collabStopOverridePrompt": "ਇਜਲਾਸ ਨੂੰ ਰੋਕਣਾ ਪਿਛਲੀ ਲੋਕਲ ਸਾਂਭੀ ਡਰਾਇੰਗ ਦੀ ਥਾਂ ਲੈ ਲਵੇਗਾ। ਪੱਕਾ ਇੰਝ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?\n\n(ਜੇ ਤੁਸੀਂ ਆਪਣੀ ਲੋਕਲ ਡਰਾਇੰਗ ਨੂੰ ਬਰਕਰਾਰ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਇਹ ਕਰਨ ਦੀ ਬਜਾਏ ਬੱਸ ਆਪਣਾ ਟੈਬ ਬੰਦ ਕਰ ਦਿਉ।)",
"errorLoadingLibrary": "ਤੀਜੀ ਧਿਰ ਦੀ ਲਾਇਬ੍ਰੇਰੀ ਨੂੰ ਲੋਡ ਕਰਨ ਵਿੱਚ ਗਲਤੀ ਹੋਈ ਸੀ।",
"errorAddingToLibrary": "ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ ਸਮੱਗਰੀ ਨਹੀਂ ਜੋੜ ਸਕੇ",
"errorRemovingFromLibrary": "ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚੋਂ ਸਮੱਗਰੀ ਨਹੀਂ ਹਟਾ ਸਕੇ",
"errorAddingToLibrary": "",
"errorRemovingFromLibrary": "",
"confirmAddLibrary": "ਇਹ ਤੁਹਾਡੀ ਲਾਇਬ੍ਰੇਰੀ ਵਿੱਚ {{numShapes}} ਆਕ੍ਰਿਤੀ(ਆਂ) ਨੂੰ ਜੋੜ ਦੇਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਪੱਕਾ ਇੰਝ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"imageDoesNotContainScene": "ਫਿਲਹਾਲ ਤਸਵੀਰਾਂ ਨੂੰ ਆਯਾਤ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ।\n\nਕੀ ਤੁਸੀਂ ਦ੍ਰਿਸ਼ ਨੂੰ ਆਯਾਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਸੀ? ਇਸ ਤਸਵੀਰ ਵਿੱਚ ਦ੍ਰਿਸ਼ ਦਾ ਕੋਈ ਵੀ ਡਾਟਾ ਨਜ਼ਰ ਨਹੀਂ ਆ ਰਿਹਾ। ਕੀ ਨਿਰਯਾਤ ਦੌਰਾਨ ਤੁਸੀਂ ਇਹ ਸਮਰੱਥ ਕੀਤਾ ਸੀ?",
"cannotRestoreFromImage": "ਇਸ ਤਸਵੀਰ ਫਾਈਲ ਤੋਂ ਦ੍ਰਿਸ਼ ਬਹਾਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ",
"invalidSceneUrl": "",
"resetLibrary": "ਇਹ ਤੁਹਾਡੀ ਲਾਇਬ੍ਰੇਰੀ ਨੂੰ ਸਾਫ ਕਰ ਦੇਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਪੱਕਾ ਇੰਝ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"
"resetLibrary": ""
},
"toolBar": {
"selection": "ਚੋਣਕਾਰ",
"freedraw": "ਖੁੱਲ੍ਹੀ ਵਾਹੀ",
"rectangle": "ਆਇਤ",
"diamond": "ਹੀਰਾ",
"ellipse": "ਅੰਡਾਕਾਰ",
"arrow": "ਤੀਰ",
"line": "ਲਕੀਰ",
"freedraw": "",
"text": "ਪਾਠ",
"library": "ਲਾਇਬ੍ਰੇਰੀ",
"lock": "ਡਰਾਇੰਗ ਤੋਂ ਬਾਅਦ ਵੀ ਚੁਣੇ ਹੋਏ ਸੰਦ ਨੂੰ ਸਰਗਰਮ ਰੱਖੋ "
@ -217,14 +210,6 @@
"errorDialog": {
"title": "ਗਲਤੀ"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "ਸਾਡਾ ਬਲੌਗ ਪੜ੍ਹੋ",
"click": "ਕਲਿੱਕ",
@ -271,7 +256,7 @@
"copyToClipboardAsPng": "",
"fileSaved": "ਫਾਈਲ ਸਾਂਭੀ ਗਈ।",
"fileSavedToFilename": "{filename} ਵਿੱਚ ਸਾਂਭੀ",
"canvas": "ਕੈਨਵਸ",
"selection": "ਚੋਣ"
"canvas": "",
"selection": ""
}
}

View File

@ -1,39 +1,38 @@
{
"ar-SA": 94,
"bg-BG": 85,
"ca-ES": 92,
"cs-CZ": 36,
"ar-SA": 84,
"bg-BG": 92,
"ca-ES": 99,
"de-DE": 100,
"el-GR": 90,
"el-GR": 97,
"en": 100,
"es-ES": 93,
"fa-IR": 81,
"fi-FI": 94,
"es-ES": 99,
"fa-IR": 87,
"fi-FI": 99,
"fr-FR": 100,
"he-IL": 82,
"hi-IN": 84,
"hu-HU": 74,
"he-IL": 88,
"hi-IN": 91,
"hu-HU": 80,
"id-ID": 100,
"it-IT": 99,
"ja-JP": 99,
"kab-KAB": 97,
"ko-KR": 85,
"lv-LV": 17,
"my-MM": 69,
"it-IT": 100,
"ja-JP": 96,
"kab-KAB": 99,
"ko-KR": 91,
"lv-LV": 0,
"my-MM": 75,
"nb-NO": 100,
"nl-NL": 100,
"nn-NO": 92,
"oc-FR": 95,
"pa-IN": 91,
"pl-PL": 87,
"pt-BR": 92,
"pt-PT": 94,
"nn-NO": 100,
"oc-FR": 100,
"pa-IN": 93,
"pl-PL": 94,
"pt-BR": 100,
"pt-PT": 99,
"ro-RO": 100,
"ru-RU": 95,
"sk-SK": 95,
"ru-RU": 97,
"sk-SK": 100,
"sv-SE": 100,
"tr-TR": 93,
"tr-TR": 100,
"uk-UA": 100,
"zh-CN": 94,
"zh-CN": 100,
"zh-TW": 99
}

View File

@ -20,10 +20,6 @@
"background": "Kolor wypełnienia",
"fill": "Wypełnienie",
"strokeWidth": "Grubość obramowania",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Styl obrysu",
"strokeStyle_solid": "Pełny",
"strokeStyle_dashed": "Kreskowany",
@ -42,8 +38,8 @@
"fontSize": "Rozmiar tekstu",
"fontFamily": "Krój pisma",
"onlySelected": "Tylko wybrane",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Z tłem",
"exportEmbedScene": "Osadź scenę w eksportowanym pliku",
"exportEmbedScene_details": "Dane sceny zostaną zapisane w eksportowanym pliku PNG/SVG tak, aby scena mogła zostać z niego przywrócona.\nZwiększy to rozmiar eksportowanego pliku.",
"addWatermark": "Dodaj \"Zrobione w Excalidraw\"",
"handDrawn": "Odręczny",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "Tryb widoku",
"toggleExportColorScheme": "",
"share": "",
"toggleTheme": ""
"share": ""
},
"buttons": {
"clearReset": "Wyczyść dokument i zresetuj kolor dokumentu",
"exportJSON": "",
"exportImage": "",
"export": "Zapisz jako",
"exportToPng": "Zapisz jako PNG",
"exportToSvg": "Zapisz jako SVG",
"copyToClipboard": "Skopiuj do schowka",
"copyPngToClipboard": "Skopiuj do schowka jako plik PNG",
"scale": "Skala",
"save": "",
"save": "Zapisz",
"saveAs": "Zapisz jako",
"load": "Otwórz",
"getShareableLink": "Udostępnij",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Zaznaczenie",
"freedraw": "Swobodne rysowanie",
"rectangle": "Prostokąt",
"diamond": "Romb",
"ellipse": "Elipsa",
"arrow": "Strzałka",
"line": "Linia",
"freedraw": "",
"text": "Tekst",
"library": "Biblioteka",
"lock": "Zablokuj wybrane narzędzie"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Wystąpił błąd"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Przeczytaj na naszym blogu",
"click": "kliknięcie",

View File

@ -20,10 +20,6 @@
"background": "Fundo",
"fill": "Preenchimento",
"strokeWidth": "Espessura do traço",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Estilo de traço",
"strokeStyle_solid": "Sólido",
"strokeStyle_dashed": "Tracejado",
@ -42,8 +38,8 @@
"fontSize": "Tamanho da fonte",
"fontFamily": "Família da fonte",
"onlySelected": "Somente a seleção",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Com fundo",
"exportEmbedScene": "Incorporar a cena no arquivo exportado",
"exportEmbedScene_details": "Os dados da cena serão salvos no arquivo PNG/SVG exportado para que a cena possa ser restaurada.\nIrá aumentar o tamanho do arquivo exportado.",
"addWatermark": "Adicionar \"Feito com Excalidraw\"",
"handDrawn": "Manuscrito",
@ -100,20 +96,17 @@
"flipVertical": "Inverter verticalmente",
"viewMode": "Modo de visualização",
"toggleExportColorScheme": "Alternar esquema de cores de exportação",
"share": "Compartilhar",
"toggleTheme": ""
"share": "Compartilhar"
},
"buttons": {
"clearReset": "Limpar o canvas e redefinir a cor de fundo",
"exportJSON": "",
"exportImage": "",
"export": "Exportar",
"exportToPng": "Exportar em PNG",
"exportToSvg": "Exportar em SVG",
"copyToClipboard": "Copiar para o clipboard",
"copyPngToClipboard": "Copiar PNG para área de transferência",
"scale": "Escala",
"save": "",
"save": "Salvar",
"saveAs": "Salvar como",
"load": "Carregar",
"getShareableLink": "Obter um link de compartilhamento",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Seleção",
"freedraw": "Desenho livre",
"rectangle": "Retângulo",
"diamond": "Losango",
"ellipse": "Elipse",
"arrow": "Flecha",
"line": "Linha",
"freedraw": "",
"text": "Texto",
"library": "Biblioteca",
"lock": "Manter ativa a ferramenta selecionada após desenhar"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Erro"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Leia o nosso blog",
"click": "clicar",

View File

@ -20,10 +20,6 @@
"background": "Fundo",
"fill": "Preenchimento",
"strokeWidth": "Espessura do traço",
"strokeShape": "Forma do traço",
"strokeShape_gel": "Caneta de gel",
"strokeShape_fountain": "Caneta de fonte",
"strokeShape_brush": "Caneta de pincel",
"strokeStyle": "Estilo de traço",
"strokeStyle_solid": "Sólido",
"strokeStyle_dashed": "Tracejado",
@ -42,8 +38,8 @@
"fontSize": "Tamanho da fonte",
"fontFamily": "Família da fontes",
"onlySelected": "Somente a seleção",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Com fundo",
"exportEmbedScene": "Incorporar a cena no arquivo exportado",
"exportEmbedScene_details": "Os dados da cena serão salvos no arquivo PNG/SVG exportado para que a cena possa ser restaurada.\nIrá aumentar o tamanho do arquivo exportado.",
"addWatermark": "Adicionar \"Feito com Excalidraw\"",
"handDrawn": "Manuscrito",
@ -100,20 +96,17 @@
"flipVertical": "Inverter verticalmente",
"viewMode": "Modo de visualização",
"toggleExportColorScheme": "Alternar esquema de cores de exportação",
"share": "Partilhar",
"toggleTheme": "Alternar tema"
"share": "Partilhar"
},
"buttons": {
"clearReset": "Limpar o canvas e redefinir a cor de fundo",
"exportJSON": "",
"exportImage": "",
"export": "Exportar",
"exportToPng": "Exportar em PNG",
"exportToSvg": "Exportar em SVG",
"copyToClipboard": "Copiar para o clipboard",
"copyPngToClipboard": "Copiar PNG para área de transferência",
"scale": "Escala",
"save": "",
"save": "Guardar",
"saveAs": "Salvar como",
"load": "Carregar",
"getShareableLink": "Obter um link de partilha",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Seleção",
"freedraw": "Desenho livre",
"rectangle": "Retângulo",
"diamond": "Losango",
"ellipse": "Elipse",
"arrow": "Flecha",
"line": "Linha",
"freedraw": "Desenhar",
"text": "Texto",
"library": "Biblioteca",
"lock": "Manter a ferramenta selecionada ativa após desenhar"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Erro"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Leia o nosso blog",
"click": "clicar",

View File

@ -20,10 +20,6 @@
"background": "Fundal",
"fill": "Umplere",
"strokeWidth": "Lățimea conturului",
"strokeShape": "Forma conturului",
"strokeShape_gel": "Pix cu gel",
"strokeShape_fountain": "Stilou",
"strokeShape_brush": "Pensulă tip stilou",
"strokeStyle": "Stilul conturului",
"strokeStyle_solid": "Neîntrerupt",
"strokeStyle_dashed": "Liniuțe",
@ -42,8 +38,8 @@
"fontSize": "Dimensiune font",
"fontFamily": "Familia de fonturi",
"onlySelected": "Numai selecția",
"withBackground": "Fundal",
"exportEmbedScene": "Încorporare scenă",
"withBackground": "Cu fundal",
"exportEmbedScene": "Încorporează scena în fișierul exportat",
"exportEmbedScene_details": "Datele scenei vor fi salvate în fișierul PNG/SVG exportat, astfel că scena va putea fi restaurată din acesta.\nVa crește dimensiunea fișierului exportat.",
"addWatermark": "Adaugă „Realizat cu Excalidraw”",
"handDrawn": "Scris de mână",
@ -100,23 +96,20 @@
"flipVertical": "Răsturnare verticală",
"viewMode": "Mod de vizualizare",
"toggleExportColorScheme": "Comutare schemă de culori de export",
"share": "Distribuie",
"toggleTheme": "Comutare temă"
"share": "Distribuie"
},
"buttons": {
"clearReset": "Resetare pânză",
"exportJSON": "Exportare la fișiere",
"exportImage": "Salvare ca imagine",
"export": "Exportare",
"exportToPng": "Exportare ca PNG",
"exportToSvg": "Exportare ca SVG",
"copyToClipboard": "Copiere în memoria temporară",
"copyPngToClipboard": "Copiere PNG în memoria temporară",
"scale": "Scală",
"save": "Salvare în fișierul curent",
"save": "Salvare",
"saveAs": "Salvare ca",
"load": "Încărcare",
"getShareableLink": "Obține URL partajabil",
"getShareableLink": "Legătură partajabilă",
"close": "Închidere",
"selectLanguage": "Selectare limbă",
"scrollBackToContent": "Derulare înapoi la conținut",
@ -138,8 +131,8 @@
},
"alerts": {
"clearReset": "Această opțiune va șterge întreaga pânză. Confirmi?",
"couldNotCreateShareableLink": "Nu s-a putut crea un URL partajabil.",
"couldNotCreateShareableLinkTooBig": "Nu s-a putut crea un URL partajabil: scena este prea mare",
"couldNotCreateShareableLink": "Legătura partajabilă nu a putut fi creată.",
"couldNotCreateShareableLinkTooBig": "Nu s-a putut crea o legătură partajabilă: scena este prea mare",
"couldNotLoadInvalidFile": "Fișierul invalid nu a putut fi încărcat",
"importBackendFailed": "Importarea de la nivel de server a eșuat.",
"cannotExportEmptyCanvas": "Nu se poate exporta pânza goală.",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Selecție",
"freedraw": "Desenare liberă",
"rectangle": "Dreptunghi",
"diamond": "Romb",
"ellipse": "Elipsă",
"arrow": "Săgeată",
"line": "Linie",
"freedraw": "Desenare",
"text": "Text",
"library": "Bibliotecă",
"lock": "Menține activ instrumentul selectat după desenare"
@ -210,21 +203,13 @@
"button_startSession": "Pornire sesiune",
"button_stopSession": "Oprire sesiune",
"desc_inProgressIntro": "Sesiunea de colaborare în direct este în curs de desfășurare.",
"desc_shareLink": "Distribuie acest URL persoanelor cu care dorești să colaborezi:",
"desc_shareLink": "Distribuie această legătură persoanelor cu care dorești să colaborezi:",
"desc_exitSession": "Oprirea sesiunii te va deconecta de la sală, însă vei putea lucra în continuare, pe plan local, cu scena. Reține că această opțiune nu va afecta alte persoane, iar acestea vor putea să colaboreze în continuare pe versiunea lor.",
"shareTitle": "Alătură-te unei sesiuni de colaborare în direct pe Excalidraw"
},
"errorDialog": {
"title": "Eroare"
},
"exportDialog": {
"disk_title": "Salvare pe disc",
"disk_details": "Exportă datele scenei pe un fișier din care poți importa mai târziu.",
"disk_button": "Salvare în fișier",
"link_title": "URL partajabil",
"link_details": "Exportă ca URL doar în citire.",
"link_button": "Exportare în URL"
},
"helpDialog": {
"blog": "Citește blogul nostru",
"click": "clic",

View File

@ -20,10 +20,6 @@
"background": "Фон",
"fill": "Заливка",
"strokeWidth": "Толщина штриха",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Стиль обводки",
"strokeStyle_solid": "Сплошная",
"strokeStyle_dashed": "Пунктирная",
@ -42,8 +38,8 @@
"fontSize": "Размер шрифта",
"fontFamily": "Семейство шрифтов",
"onlySelected": "Только выбранные",
"withBackground": "Фон",
"exportEmbedScene": "Встроить сцену",
"withBackground": "С фоном",
"exportEmbedScene": "Встроить информацию о сцене в экспортируемый файл",
"exportEmbedScene_details": "Сцена будет сохранена в PNG/SVG файл так, чтобы всю сцену можно будет восстановить из этого файла. Это увеличит размер файла.",
"addWatermark": "Добавить «Создано в Excalidraw»",
"handDrawn": "От руки",
@ -100,20 +96,17 @@
"flipVertical": "",
"viewMode": "Вид",
"toggleExportColorScheme": "Экспортировать цветовую схему",
"share": "Поделиться",
"toggleTheme": ""
"share": "Поделиться"
},
"buttons": {
"clearReset": "Очистить холст и сбросить цвет фона",
"exportJSON": "Сохранить в",
"exportImage": "Сохранить как изображение",
"export": "Экспортировать",
"exportToPng": "Экспорт в PNG",
"exportToSvg": "Экспорт в SVG",
"copyToClipboard": "Скопировать в буфер обмена",
"copyPngToClipboard": "Скопировать PNG в буфер обмена",
"scale": "Масштаб",
"save": "Сохранить в текущий файл",
"save": "Сохранить",
"saveAs": "Сохранить как",
"load": "Загрузить",
"getShareableLink": "Получить доступ по ссылке",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Выделение области",
"freedraw": "Свободное рисование",
"rectangle": "Прямоугольник",
"diamond": "Ромб",
"ellipse": "Эллипс",
"arrow": "Cтрелка",
"line": "Линия",
"freedraw": "",
"text": "Текст",
"library": "Библиотека",
"lock": "Сохранять выбранный инструмент активным после рисования"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Ошибка"
},
"exportDialog": {
"disk_title": "Сохранить на диск",
"disk_details": "Экспортировать данные сцены в файл, из которого можно импортировать позже.",
"disk_button": "Сохранить в файл",
"link_title": "Поделитесь ссылкой",
"link_details": "Экспорт ссылки только для чтения.",
"link_button": "Экспорт в ссылку"
},
"helpDialog": {
"blog": "Прочитайте наш блог",
"click": "нажать",

View File

@ -20,10 +20,6 @@
"background": "Pozadie",
"fill": "Výplň",
"strokeWidth": "Hrúbka obrysu",
"strokeShape": "Tvar obrysu",
"strokeShape_gel": "Gélové pero",
"strokeShape_fountain": "Plniace pero",
"strokeShape_brush": "Fixka",
"strokeStyle": "Štýl obrysu",
"strokeStyle_solid": "Plný",
"strokeStyle_dashed": "Čiarkovaný",
@ -42,8 +38,8 @@
"fontSize": "Veľkosť písma",
"fontFamily": "Písmo",
"onlySelected": "Iba vybrané",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "S pozadím",
"exportEmbedScene": "Uložiť scénu do exportovaného 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\"",
"handDrawn": "Ručne písané",
@ -100,20 +96,17 @@
"flipVertical": "Prevrátiť zvislo",
"viewMode": "Režim zobrazenia",
"toggleExportColorScheme": "Prepnúť exportovanie farebnej schémy",
"share": "Zdieľať",
"toggleTheme": "Prepnúť tému"
"share": "Zdieľať"
},
"buttons": {
"clearReset": "Obnoviť plátno",
"exportJSON": "",
"exportImage": "",
"export": "Exportovať",
"exportToPng": "Exportovať do PNG",
"exportToSvg": "Exportovať do SVG",
"copyToClipboard": "Kopírovať do schránky",
"copyPngToClipboard": "Kopírovať PNG do schránky",
"scale": "Mierka",
"save": "",
"save": "Uložiť",
"saveAs": "Uložiť ako",
"load": "Nahrať",
"getShareableLink": "Získať odkaz na zdieľanie",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Výber",
"freedraw": "Voľné kreslenie",
"rectangle": "Obdĺžnik",
"diamond": "Diamant",
"ellipse": "Elipsa",
"arrow": "Šípka",
"line": "Čiara",
"freedraw": "Kresliť",
"text": "Text",
"library": "Knižnica",
"lock": "Nechať zvolený nástroj aktívny po skončení kreslenia"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Chyba"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Prečítajte si náš blog",
"click": "kliknutie",

View File

@ -20,10 +20,6 @@
"background": "Bakgrund",
"fill": "Fyllnad",
"strokeWidth": "Linjebredd",
"strokeShape": "Linjeform",
"strokeShape_gel": "Gelépenna",
"strokeShape_fountain": "Reservoarpenna",
"strokeShape_brush": "Penselpenna",
"strokeStyle": "Linjestil",
"strokeStyle_solid": "Solid",
"strokeStyle_dashed": "Streckad",
@ -42,8 +38,8 @@
"fontSize": "Teckenstorlek",
"fontFamily": "Teckensnitt",
"onlySelected": "Endast markering",
"withBackground": "Bakgrund",
"exportEmbedScene": "Bädda in skiss",
"withBackground": "Med bakgrund",
"exportEmbedScene": "Bädda in skiss i exporterad fil",
"exportEmbedScene_details": "Skissdata kommer att sparas i den exporterade PNG/SVG-filen så att skissen kan återställas från den.\nKommer att öka exporterad filstorlek.",
"addWatermark": "Lägg till \"Skapad med Excalidraw\"",
"handDrawn": "Handritad",
@ -100,20 +96,17 @@
"flipVertical": "Vänd vertikalt",
"viewMode": "Visningsläge",
"toggleExportColorScheme": "Växla färgschema för export",
"share": "Dela",
"toggleTheme": "Växla tema"
"share": "Dela"
},
"buttons": {
"clearReset": "Återställ canvasen",
"exportJSON": "Exportera till fil",
"exportImage": "Spara som bild",
"export": "Exportera",
"exportToPng": "Exportera till PNG",
"exportToSvg": "Exportera till SVG",
"copyToClipboard": "Kopiera till urklipp",
"copyPngToClipboard": "Kopiera PNG till urklipp",
"scale": "Skala",
"save": "Spara till aktuell fil",
"save": "Spara",
"saveAs": "Spara som",
"load": "Öppna",
"getShareableLink": "Hämta delbar länk",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Markering",
"freedraw": "Frihand",
"rectangle": "Rektangel",
"diamond": "Diamant",
"ellipse": "Ellips",
"arrow": "Pil",
"line": "Linje",
"freedraw": "Rita",
"text": "Text",
"library": "Bibliotek",
"lock": "Håll valt verktyg aktivt efter ritande"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Fel"
},
"exportDialog": {
"disk_title": "Spara till disk",
"disk_details": "Exportera skissdata till en fil som du kan importera från senare.",
"disk_button": "Spara till fil",
"link_title": "Delbar länk",
"link_details": "Exportera som en skrivskyddad länk.",
"link_button": "Exportera till länk"
},
"helpDialog": {
"blog": "Läs vår blogg",
"click": "klicka",

View File

@ -20,10 +20,6 @@
"background": "Arka plan",
"fill": "Doldur",
"strokeWidth": "Kontur genişliği",
"strokeShape": "",
"strokeShape_gel": "",
"strokeShape_fountain": "",
"strokeShape_brush": "",
"strokeStyle": "Kontur stili",
"strokeStyle_solid": "Dolu",
"strokeStyle_dashed": "Kesik çizgili",
@ -34,7 +30,7 @@
"edges": "Kenarlar",
"sharp": "Keskin",
"round": "Yuvarlak",
"arrowheads": "Ok ları",
"arrowheads": "Ok başları",
"arrowhead_none": "Yok",
"arrowhead_arrow": "Ok",
"arrowhead_bar": "Çizgi",
@ -42,8 +38,8 @@
"fontSize": "Yazı tipi boyutu",
"fontFamily": "Yazı tipi ailesi",
"onlySelected": "Sadece seçilen",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "Arka planla beraber",
"exportEmbedScene": "Sahneyi çıktı dosyasına dahil et",
"exportEmbedScene_details": "Sahne datası, daha sonra geri kullanılabilmesi için çıktı alınan PNG/SVG dosyasına dahil edicelek. Bu işlem dosya boyutunu arttıracaktır.",
"addWatermark": "\"Excalidraw ile yapıldı\" yazısını ekle",
"handDrawn": "El-yazısı",
@ -100,20 +96,17 @@
"flipVertical": "Dikey döndür",
"viewMode": "Görünüm modu",
"toggleExportColorScheme": "Renk şemasını dışa aktar/aktarma",
"share": "Paylaş",
"toggleTheme": "Temayı etkinleştir/devre dışı bırak"
"share": "Paylaş"
},
"buttons": {
"clearReset": "Tuvali sıfırla",
"exportJSON": "",
"exportImage": "",
"export": "Dışa aktar",
"exportToPng": "PNG olarak dışa aktar",
"exportToSvg": "SVG olarak dışa aktar",
"copyToClipboard": "Panoya kopyala",
"copyPngToClipboard": "PNG'yi panoya kopyala",
"scale": "Ölçek",
"save": "",
"save": "Kaydet",
"saveAs": "Farklı kaydet",
"load": "Yükle",
"getShareableLink": "Paylaşılabilir bağlantı al",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Seçme",
"freedraw": "Serbest çizim",
"rectangle": "Dikdörtgen",
"diamond": "Elmas",
"ellipse": "Elips",
"arrow": "Ok",
"line": "Çizgi",
"freedraw": "Çiz",
"text": "Yazı",
"library": "Kütüphane",
"lock": "Seçilen aracı çizimden sonra aktif tut"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Hata"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "Blog'umuzu okuyun",
"click": "tıkla",

View File

@ -20,10 +20,6 @@
"background": "Тло",
"fill": "Заповнити",
"strokeWidth": "Товщина контуру",
"strokeShape": "Форма обведення",
"strokeShape_gel": "Гельручка",
"strokeShape_fountain": "Перо",
"strokeShape_brush": "Пензель",
"strokeStyle": "Стиль контуру",
"strokeStyle_solid": "Суцільний",
"strokeStyle_dashed": "Пунктир",
@ -42,8 +38,8 @@
"fontSize": "Розмір шрифту",
"fontFamily": "Шрифт",
"onlySelected": "Тільки вибране",
"withBackground": "Фон",
"exportEmbedScene": "Вбудована сцена",
"withBackground": "З фоном",
"exportEmbedScene": "Вставити сцену в експортований файл",
"exportEmbedScene_details": "Дані сцени будуть збережені в експортований файл PNG/SVG. Ця сцена може бути відновленна з нього, однак це збільшить розмір експортованого файлу.",
"addWatermark": "Додати «Накреслене в Excalidraw»",
"handDrawn": "Рукописний",
@ -100,20 +96,17 @@
"flipVertical": "Віддзеркалити вертикально",
"viewMode": "Режим перегляду",
"toggleExportColorScheme": "Переключити колірну схему експорту",
"share": "Поділитися",
"toggleTheme": "Перемкнути тему"
"share": "Поділитися"
},
"buttons": {
"clearReset": "Очистити полотно",
"exportJSON": "Експорт у файл",
"exportImage": "Зберегти як зображення",
"export": "Експортувати",
"exportToPng": "Експортувати в PNG",
"exportToSvg": "Експортувати в SVG",
"copyToClipboard": "Скопіювати до буферу обміну",
"copyPngToClipboard": "Скопіювати PNG до буферу обміну",
"scale": "Масштаб",
"save": "Зберегти до поточного файлу",
"save": "Зберегти",
"saveAs": "Зберегти як",
"load": "Завантажити",
"getShareableLink": "Отримати посилання",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "Виділення",
"freedraw": "Вільне креслення",
"rectangle": "Прямокутник",
"diamond": "Ромб",
"ellipse": "Еліпс",
"arrow": "Стрілка",
"line": "Лінія",
"freedraw": "Малювати",
"text": "Текст",
"library": "Бібліотека",
"lock": "Залишити обраний інструмент після креслення"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "Помилка"
},
"exportDialog": {
"disk_title": "Зберегти на диск",
"disk_details": "Експорт даних сцени в файл, з якого можна імпортувати пізніше.",
"disk_button": "Зберегти до файлу",
"link_title": "Доступ за посиланням",
"link_details": "Експортувати як посилання тільки для читання.",
"link_button": "Експортувати у посилання"
},
"helpDialog": {
"blog": "Наш блог",
"click": "натиснути",

View File

@ -20,10 +20,6 @@
"background": "背景",
"fill": "填充",
"strokeWidth": "描边宽度",
"strokeShape": "",
"strokeShape_gel": "中性笔",
"strokeShape_fountain": "钢笔",
"strokeShape_brush": "墨笔",
"strokeStyle": "描边 (样式)",
"strokeStyle_solid": "实线",
"strokeStyle_dashed": "虚线",
@ -42,8 +38,8 @@
"fontSize": "字体大小",
"fontFamily": "字体",
"onlySelected": "仅被选中",
"withBackground": "",
"exportEmbedScene": "",
"withBackground": "包括背景",
"exportEmbedScene": "将画布数据嵌入到导出的文件",
"exportEmbedScene_details": "画布数据将被保存到导出的 PNG/SVG 文件,以便恢复。\n将会增加导出的文件大小。",
"addWatermark": "添加 “使用 Excalidraw 创建” 水印",
"handDrawn": "手写",
@ -100,20 +96,17 @@
"flipVertical": "垂直翻转",
"viewMode": "查看模式",
"toggleExportColorScheme": "切换导出配色方案",
"share": "分享",
"toggleTheme": "切换主题"
"share": "分享"
},
"buttons": {
"clearReset": "重置画布",
"exportJSON": "",
"exportImage": "",
"export": "导出",
"exportToPng": "导出为 PNG",
"exportToSvg": "导出为 SVG",
"copyToClipboard": "复制到剪贴板",
"copyPngToClipboard": "复制 PNG 到剪切板",
"scale": "缩放",
"save": "",
"save": "保存",
"saveAs": "保存为",
"load": "载入文件",
"getShareableLink": "获取共享链接",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "选择",
"freedraw": "自由书写",
"rectangle": "矩形",
"diamond": "菱形",
"ellipse": "椭圆",
"arrow": "箭头",
"line": "线条",
"freedraw": "",
"text": "文字",
"library": "库",
"lock": "绘制后保持所选的工具栏状态"
@ -176,7 +169,7 @@
},
"hints": {
"linearElement": "点击创建多个点 拖动创建直线",
"freeDraw": "点击并拖动,完成时松开",
"freeDraw": "点击并拖动,完成后发布",
"text": "提示:您也可以使用选择工具双击任意位置来添加文字",
"linearElementMulti": "点击最后一个点或按下 Esc/Enter 来完成",
"lockAngle": "可以按住 Shift 来约束角度",
@ -217,14 +210,6 @@
"errorDialog": {
"title": "错误"
},
"exportDialog": {
"disk_title": "",
"disk_details": "",
"disk_button": "",
"link_title": "",
"link_details": "",
"link_button": ""
},
"helpDialog": {
"blog": "浏览我们的博客",
"click": "单击",

View File

@ -20,10 +20,6 @@
"background": "背景",
"fill": "填充",
"strokeWidth": "筆劃寬度",
"strokeShape": "筆畫形狀",
"strokeShape_gel": "中性筆",
"strokeShape_fountain": "鋼筆",
"strokeShape_brush": "毛筆",
"strokeStyle": "筆畫樣式",
"strokeStyle_solid": "實線",
"strokeStyle_dashed": "虛線",
@ -42,8 +38,8 @@
"fontSize": "字型大小",
"fontFamily": "字體",
"onlySelected": "僅選取物件",
"withBackground": "背景",
"exportEmbedScene": "嵌入場景",
"withBackground": "包含背景",
"exportEmbedScene": "在輸出的檔案中嵌入場景",
"exportEmbedScene_details": "用於回復場景的場景資料會被包含在輸出的 PNG/SVG 檔案中。\n會增加輸出的檔案大小。",
"addWatermark": "加上 \"Made with Excalidraw\"",
"handDrawn": "手寫",
@ -100,20 +96,17 @@
"flipVertical": "垂直翻轉",
"viewMode": "檢視模式",
"toggleExportColorScheme": "切換輸出配色",
"share": "共享",
"toggleTheme": "切換主題"
"share": "共享"
},
"buttons": {
"clearReset": "重置 canvas",
"exportJSON": "匯出至檔案",
"exportImage": "另存為圖片",
"export": "輸出",
"exportToPng": "輸出成 PNG",
"exportToSvg": "輸出成 SVG",
"copyToClipboard": "複製至剪貼簿",
"copyPngToClipboard": "複製 PNG 至剪貼簿",
"scale": "縮放比例",
"save": "儲存目前檔案",
"save": "儲存",
"saveAs": "儲存為",
"load": "載入",
"getShareableLink": "取得共享連結",
@ -159,12 +152,12 @@
},
"toolBar": {
"selection": "選取",
"freedraw": "繪圖",
"rectangle": "長方形",
"diamond": "菱形",
"ellipse": "橢圓",
"arrow": "箭頭",
"line": "線條",
"freedraw": "繪圖",
"text": "文字",
"library": "資料庫",
"lock": "可連續使用選取的工具"
@ -217,14 +210,6 @@
"errorDialog": {
"title": "錯誤"
},
"exportDialog": {
"disk_title": "儲存至硬碟",
"disk_details": "將場景匯出為可供匯入之檔案",
"disk_button": "儲存至檔案",
"link_title": "可共享連結",
"link_details": "匯出為唯讀連結",
"link_button": "匯出為連結"
},
"helpDialog": {
"blog": "閱讀部落格",
"click": "點擊",

View File

@ -11,35 +11,6 @@ The change should be grouped under one of the below section and must contain PR
Please add the latest change on the top under the correct section.
-->
## Unreleased
**This changes are not yet released but you can still try it out in [@excalidraw/excalidraw-next](https://www.npmjs.com/package/@excalidraw/excalidraw-next).**
## Excalidraw API
### Features
- 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).
- Export dialog can be customised with [`UiOptions.canvasActions.export`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#exportOpts) [#3658](https://github.com/excalidraw/excalidraw/pull/3658).
Also, [`UIOptions`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#UIOptions) is now memoized to avoid unnecessary rerenders.
#### BREAKING CHANGE
- `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.
### Refactor
- #### BREAKING CHANGE
- Rename `UIOptions.canvasActions.saveScene` to `UIOptions.canvasActions.saveToActiveFile`[#3657](https://github.com/excalidraw/excalidraw/pull/3657).
- Removed `shouldAddWatermark: boolean` attribute from options for [export](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#export-utilities) APIs [#3639](https://github.com/excalidraw/excalidraw/pull/3639).
- Removed `appState.shouldAddWatermark` so in case you were passing `shouldAddWatermark` in [initialData.AppState](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L42) it will not work anymore.
---
## 0.8.0 (2021-05-15)
## Excalidraw API

View File

@ -823,4 +823,5 @@ This function returns a svg with the exported elements.
| --- | --- | --- | --- |
| exportBackground | boolean | true | Indicates whether background should be exported |
| viewBackgroundColor | string | #fff | The default background color |
| shouldAddWatermark | boolean | false | Indicates whether watermark should be exported |
| exportWithDarkMode | boolean | false | Indicates whether to export with dark mode |

View File

@ -363,6 +363,7 @@ To view the full example visit :point_down:
| [`onCollabButtonClick`](#onCollabButtonClick) | Function | | Callback to be triggered when the collab button is clicked |
| [`isCollaborating`](#isCollaborating) | `boolean` | | This implies if the app is in collaboration mode |
| [`onPointerUpdate`](#onPointerUpdate) | Function | | Callback triggered when mouse pointer is updated. |
| [`onExportToBackend`](#onExportToBackend) | Function | | Callback triggered when link button is clicked on export dialog |
| [`langCode`](#langCode) | string | `en` | Language code string |
| [`renderTopRightUI`](#renderTopRightUI) | Function | | Function that renders custom UI in top right corner |
| [`renderFooter `](#renderFooter) | Function | | Function that renders custom UI footer |
@ -487,6 +488,10 @@ This callback is triggered when mouse pointer is updated.
3.`pointersMap`: [`pointers map`](https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L131) of the scene
#### `onExportToBackend`
This callback is triggered when the shareable-link button is clicked in the export dialog. The link button will only be shown if this callback is passed.
```js
(exportedElements, appState, canvas) => void
```
@ -566,21 +571,11 @@ This prop can be used to customise UI of Excalidraw. Currently we support custom
| --- | --- | --- | --- |
| `changeViewBackgroundColor` | boolean | true | Implies whether to show `Background color picker` |
| `clearCanvas` | boolean | true | Implies whether to show `Clear canvas button` |
| `export` | false &#124; [exportOpts](#exportOpts) | <pre>{ saveFileToDisk: true }</pre> | This prop allows to customize the UI inside the export dialog. By default it shows the "saveFileToDisk". If this prop is `false` the export button will not be rendered. For more details visit [`exportOpts`](#exportOpts). |
| `export` | boolean | true | Implies whether to show `Export button` |
| `loadScene` | boolean | true | Implies whether to show `Load button` |
| `saveToActiveFile` | boolean | true | Implies whether to show `Save button` to save to current file |
| `saveAsScene` | boolean | true | Implies whether to show `Save as button` |
| `saveScene` | boolean | true | Implies whether to show `Save button` |
| `theme` | boolean | true | Implies whether to show `Theme toggle` |
| `saveAsImage` | boolean | true | Implies whether to show `Save as image button` |
#### `exportOpts`
The below attributes can be set in `UIOptions.canvasActions.export` to customize the export dialog. If `UIOptions.canvasActions.export` is `false` the export button will not be rendered.
| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `saveFileToDisk` | boolean | true | Implies if save file to disk button should be shown |
| `exportToBackend` | <pre> (exportedElements: readonly NonDeletedExcalidrawElement[],appState: AppState,canvas: HTMLCanvasElement &#124; null) => void </pre> | | This callback is triggered when the shareable-link button is clicked in the export dialog. The link button will only be shown if this callback is passed. |
| `renderCustomUI` | <pre> (exportedElements: readonly NonDeletedExcalidrawElement[],appState: AppState,canvas: HTMLCanvasElement &#124; null) => void </pre> | | This callback should be supplied if you want to render custom UI in the export dialog. |
#### `onPaste`
@ -834,4 +829,5 @@ This function returns a svg with the exported elements.
| --- | --- | --- | --- |
| exportBackground | boolean | true | Indicates whether background should be exported |
| viewBackgroundColor | string | #fff | The default background color |
| shouldAddWatermark | boolean | false | Indicates whether watermark should be exported |
| exportWithDarkMode | boolean | false | Indicates whether to export with dark mode |

View File

@ -7,7 +7,7 @@ import App from "../../components/App";
import "../../css/app.scss";
import "../../css/styles.scss";
import { AppProps, ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types";
import { ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types";
import { defaultLang } from "../../i18n";
import { DEFAULT_UI_OPTIONS } from "../../constants";
@ -19,6 +19,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
onCollabButtonClick,
isCollaborating,
onPointerUpdate,
onExportToBackend,
renderTopRightUI,
renderFooter,
langCode = defaultLang.code,
@ -37,19 +38,13 @@ const Excalidraw = (props: ExcalidrawProps) => {
const canvasActions = props.UIOptions?.canvasActions;
const UIOptions: AppProps["UIOptions"] = {
const UIOptions = {
canvasActions: {
...DEFAULT_UI_OPTIONS.canvasActions,
...canvasActions,
},
};
if (canvasActions?.export) {
UIOptions.canvasActions.export.saveFileToDisk =
canvasActions.export?.saveFileToDisk ||
DEFAULT_UI_OPTIONS.canvasActions.export.saveFileToDisk;
}
useEffect(() => {
// Block pinch-zooming on iOS outside of the content area
const handleTouchMove = (event: TouchEvent) => {
@ -77,6 +72,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
onCollabButtonClick={onCollabButtonClick}
isCollaborating={isCollaborating}
onPointerUpdate={onPointerUpdate}
onExportToBackend={onExportToBackend}
renderTopRightUI={renderTopRightUI}
renderFooter={renderFooter}
langCode={langCode}
@ -103,58 +99,12 @@ const areEqual = (
prevProps: PublicExcalidrawProps,
nextProps: PublicExcalidrawProps,
) => {
const {
initialData: prevInitialData,
UIOptions: prevUIOptions = {},
...prev
} = prevProps;
const {
initialData: nextInitialData,
UIOptions: nextUIOptions = {},
...next
} = nextProps;
// comparing UIOptions
const prevUIOptionsKeys = Object.keys(prevUIOptions) as (keyof Partial<
typeof DEFAULT_UI_OPTIONS
>)[];
const nextUIOptionsKeys = Object.keys(nextUIOptions) as (keyof Partial<
typeof DEFAULT_UI_OPTIONS
>)[];
if (prevUIOptionsKeys.length !== nextUIOptionsKeys.length) {
return false;
}
const isUIOptionsSame = prevUIOptionsKeys.every((key) => {
if (key === "canvasActions") {
const canvasOptionKeys = Object.keys(
prevUIOptions.canvasActions!,
) as (keyof Partial<typeof DEFAULT_UI_OPTIONS.canvasActions>)[];
canvasOptionKeys.every((key) => {
if (
key === "export" &&
prevUIOptions?.canvasActions?.export &&
nextUIOptions?.canvasActions?.export
) {
return (
prevUIOptions.canvasActions.export.saveFileToDisk ===
nextUIOptions.canvasActions.export.saveFileToDisk
);
}
return (
prevUIOptions?.canvasActions?.[key] ===
nextUIOptions?.canvasActions?.[key]
);
});
}
return true;
});
const { initialData: prevInitialData, ...prev } = prevProps;
const { initialData: nextInitialData, ...next } = nextProps;
const prevKeys = Object.keys(prevProps) as (keyof typeof prev)[];
const nextKeys = Object.keys(nextProps) as (keyof typeof next)[];
return (
isUIOptionsSame &&
prevKeys.length === nextKeys.length &&
prevKeys.every((key) => prev[key] === next[key])
);

View File

@ -48,11 +48,11 @@
"react-dom": "^17.0.1"
},
"devDependencies": {
"@babel/core": "7.14.3",
"@babel/core": "7.14.2",
"@babel/plugin-transform-arrow-functions": "7.13.0",
"@babel/plugin-transform-async-to-generator": "7.13.0",
"@babel/plugin-transform-runtime": "7.13.15",
"@babel/plugin-transform-typescript": "7.14.3",
"@babel/plugin-transform-typescript": "7.13.0",
"@babel/preset-env": "7.14.2",
"@babel/preset-react": "7.13.13",
"@babel/preset-typescript": "7.13.0",
@ -60,7 +60,7 @@
"babel-loader": "8.2.2",
"babel-plugin-transform-class-properties": "6.24.1",
"cross-env": "7.0.3",
"css-loader": "5.2.6",
"css-loader": "5.2.4",
"file-loader": "6.2.0",
"mini-css-extract-plugin": "1.6.0",
"postcss-loader": "5.3.0",
@ -68,7 +68,7 @@
"terser-webpack-plugin": "5.1.2",
"ts-loader": "8.1.0",
"typescript": "4.2.4",
"webpack": "5.37.1",
"webpack": "5.37.0",
"webpack-bundle-analyzer": "4.4.1",
"webpack-cli": "4.7.0"
},

View File

@ -14,17 +14,17 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919"
integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==
"@babel/core@7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.3.tgz#5395e30405f0776067fbd9cf0884f15bfb770a38"
integrity sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==
"@babel/core@7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.2.tgz#54e45334ffc0172048e5c93ded36461d3ad4c417"
integrity sha512-OgC1mON+l4U4B4wiohJlQNUU3H73mpTyYY3j/c8U9dr9UagGGSm+WFpzjy/YLdoyjiG++c1kIDgxCo/mLwQJeQ==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.14.3"
"@babel/generator" "^7.14.2"
"@babel/helper-compilation-targets" "^7.13.16"
"@babel/helper-module-transforms" "^7.14.2"
"@babel/helpers" "^7.14.0"
"@babel/parser" "^7.14.3"
"@babel/parser" "^7.14.2"
"@babel/template" "^7.12.13"
"@babel/traverse" "^7.14.2"
"@babel/types" "^7.14.2"
@ -35,10 +35,10 @@
semver "^6.3.0"
source-map "^0.5.0"
"@babel/generator@^7.14.2", "@babel/generator@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.3.tgz#0c2652d91f7bddab7cccc6ba8157e4f40dcedb91"
integrity sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==
"@babel/generator@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.2.tgz#d5773e8b557d421fd6ce0d5efa5fd7fc22567c30"
integrity sha512-OnADYbKrffDVai5qcpkMxQ7caomHOoEwjkouqnN2QhydAjowFAZcsdecFIRUBdb+ZcruwYE4ythYmF1UBZU5xQ==
dependencies:
"@babel/types" "^7.14.2"
jsesc "^2.5.1"
@ -69,16 +69,27 @@
browserslist "^4.14.5"
semver "^6.3.0"
"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0", "@babel/helper-create-class-features-plugin@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.3.tgz#832111bcf4f57ca57a4c5b1a000fc125abc6554a"
integrity sha512-BnEfi5+6J2Lte9LeiL6TxLWdIlEv9Woacc1qXzXBgbikcOzMRM2Oya5XGg/f/ngotv1ej2A/b+3iJH8wbS1+lQ==
"@babel/helper-create-class-features-plugin@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.0.tgz#28d04ad9cfbd1ed1d8b988c9ea7b945263365846"
integrity sha512-twwzhthM4/+6o9766AW2ZBHpIHPSGrPGk1+WfHiu13u/lBnggXGNYCpeAyVfNwGDKfkhEDp+WOD/xafoJ2iLjA==
dependencies:
"@babel/helper-function-name" "^7.12.13"
"@babel/helper-member-expression-to-functions" "^7.13.0"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/helper-replace-supers" "^7.13.0"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/helper-create-class-features-plugin@^7.14.0":
version "7.14.1"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz#1fe11b376f3c41650ad9fedc665b0068722ea76c"
integrity sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==
dependencies:
"@babel/helper-annotate-as-pure" "^7.12.13"
"@babel/helper-function-name" "^7.14.2"
"@babel/helper-function-name" "^7.12.13"
"@babel/helper-member-expression-to-functions" "^7.13.12"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/helper-replace-supers" "^7.14.3"
"@babel/helper-replace-supers" "^7.13.12"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/helper-create-regexp-features-plugin@^7.12.13":
@ -150,6 +161,13 @@
dependencies:
"@babel/types" "^7.12.13"
"@babel/helper-member-expression-to-functions@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz#6aa4bb678e0f8c22f58cdb79451d30494461b091"
integrity sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ==
dependencies:
"@babel/types" "^7.13.0"
"@babel/helper-member-expression-to-functions@^7.13.12":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72"
@ -209,6 +227,16 @@
"@babel/traverse" "^7.12.13"
"@babel/types" "^7.12.13"
"@babel/helper-replace-supers@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.0.tgz#6034b7b51943094cb41627848cb219cb02be1d24"
integrity sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.13.0"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/traverse" "^7.13.0"
"@babel/types" "^7.13.0"
"@babel/helper-replace-supers@^7.13.12":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804"
@ -219,16 +247,6 @@
"@babel/traverse" "^7.13.0"
"@babel/types" "^7.13.12"
"@babel/helper-replace-supers@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz#ca17b318b859d107f0e9b722d58cf12d94436600"
integrity sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.13.12"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/traverse" "^7.14.2"
"@babel/types" "^7.14.2"
"@babel/helper-simple-access@^7.13.12":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6"
@ -293,10 +311,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.3.tgz#9b530eecb071fd0c93519df25c5ff9f14759f298"
integrity sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==
"@babel/parser@^7.12.13", "@babel/parser@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.2.tgz#0c1680aa44ad4605b16cbdcc5c341a61bde9c746"
integrity sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ==
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12":
version "7.13.12"
@ -824,12 +842,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.12.13"
"@babel/plugin-transform-typescript@7.14.3", "@babel/plugin-transform-typescript@^7.13.0":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.3.tgz#44f67f725a60cccee33d9d6fee5e4f338258f34f"
integrity sha512-G5Bb5pY6tJRTC4ag1visSgiDoGgJ1u1fMUgmc2ijLkcIdzP83Q1qyZX4ggFQ/SkR+PNOatkaYC+nKcTlpsX4ag==
"@babel/plugin-transform-typescript@7.13.0", "@babel/plugin-transform-typescript@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853"
integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.14.3"
"@babel/helper-create-class-features-plugin" "^7.13.0"
"@babel/helper-plugin-utils" "^7.13.0"
"@babel/plugin-syntax-typescript" "^7.12.13"
@ -1405,15 +1423,15 @@ braces@^3.0.1:
fill-range "^7.0.1"
browserslist@^4.14.5, browserslist@^4.16.3:
version "4.16.6"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
version "4.16.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717"
integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==
dependencies:
caniuse-lite "^1.0.30001219"
colorette "^1.2.2"
electron-to-chromium "^1.3.723"
caniuse-lite "^1.0.30001181"
colorette "^1.2.1"
electron-to-chromium "^1.3.649"
escalade "^3.1.1"
node-releases "^1.1.71"
node-releases "^1.1.70"
buffer-from@^1.0.0:
version "1.1.1"
@ -1433,10 +1451,20 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001219:
version "1.0.30001230"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71"
integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==
camelcase@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30001181:
version "1.0.30001187"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz#5706942631f83baa5a0218b7dfa6ced29f845438"
integrity sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA==
caniuse-lite@^1.0.30001196:
version "1.0.30001214"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz#70f153c78223515c6d37a9fde6cd69250da9d872"
integrity sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==
chalk@^1.1.3:
version "1.1.3"
@ -1583,14 +1611,15 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
css-loader@5.2.6:
version "5.2.6"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.6.tgz#c3c82ab77fea1f360e587d871a6811f4450cc8d1"
integrity sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==
css-loader@5.2.4:
version "5.2.4"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.4.tgz#e985dcbce339812cb6104ef3670f08f9893a1536"
integrity sha512-OFYGyINCKkdQsTrSYxzGSFnGS4gNjcXkKkQgWxK138jgnPt+lepxdjSZNc8sHAl5vP3DhsJUxufWIjOwI8PMMw==
dependencies:
camelcase "^6.2.0"
icss-utils "^5.1.0"
loader-utils "^2.0.0"
postcss "^8.2.15"
postcss "^8.2.10"
postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0"
@ -1630,10 +1659,10 @@ duplexer@^0.1.2:
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
electron-to-chromium@^1.3.723:
version "1.3.739"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.739.tgz#f07756aa92cabd5a6eec6f491525a64fe62f98b9"
integrity sha512-+LPJVRsN7hGZ9EIUUiWCpO7l4E3qBYHNadazlucBfsXBbccDFNKUBAgzE68FnkWGJPwD/AfKhSzL+G+Iqb8A4A==
electron-to-chromium@^1.3.649:
version "1.3.666"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.666.tgz#59f3ce1e45b860a0ebe439b72664354efbb8bc62"
integrity sha512-/mP4HFQ0fKIX4sXltG6kfcoGrfNDZwCIyWbH2SIcVaa9u7Rm0HKjambiHNg5OEruicTl9s1EwbERLwxZwk19aw==
emojis-list@^3.0.0:
version "3.0.0"
@ -2166,20 +2195,20 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
nanoid@^3.1.23:
version "3.1.23"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
nanoid@^3.1.22:
version "3.1.22"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844"
integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==
neo-async@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
node-releases@^1.1.71:
version "1.1.72"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe"
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==
node-releases@^1.1.70:
version "1.1.70"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08"
integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==
normalize-range@^0.1.2:
version "0.1.2"
@ -2347,14 +2376,14 @@ postcss-value-parser@^4.1.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
postcss@^8.2.15:
version "8.3.0"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f"
integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==
postcss@^8.2.10:
version "8.2.10"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.10.tgz#ca7a042aa8aff494b334d0ff3e9e77079f6f702b"
integrity sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==
dependencies:
colorette "^1.2.2"
nanoid "^3.1.23"
source-map-js "^0.6.2"
nanoid "^3.1.22"
source-map "^0.6.1"
process-nextick-args@~2.0.0:
version "2.0.1"
@ -2574,11 +2603,6 @@ source-list-map@^2.0.0, source-list-map@^2.0.1:
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
source-map-js@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
source-map-support@~0.5.19:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
@ -2825,10 +2849,10 @@ webpack-sources@^2.1.1:
source-list-map "^2.0.1"
source-map "^0.6.1"
webpack@5.37.1:
version "5.37.1"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.37.1.tgz#2deb5acd350583c1ab9338471f323381b0b0c14b"
integrity sha512-btZjGy/hSjCAAVHw+cKG+L0M+rstlyxbO2C+BOTaQ5/XAnxkDrP5sVbqWhXgo4pL3X2dcOib6rqCP20Zr9PLow==
webpack@5.37.0:
version "5.37.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.37.0.tgz#2ab00f613faf494504eb2beef278dab7493cc39d"
integrity sha512-yvdhgcI6QkQkDe1hINBAJ1UNevqNGTVaCkD2SSJcB8rcrNNl922RI8i2DXUAuNfANoxwsiXXEA4ZPZI9q2oGLA==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.47"

View File

@ -26,11 +26,15 @@ export const exportToCanvas = ({
{ elements, appState },
null,
);
const { exportBackground, viewBackgroundColor } = restoredAppState;
const {
exportBackground,
viewBackgroundColor,
shouldAddWatermark,
} = restoredAppState;
return _exportToCanvas(
getNonDeletedElements(restoredElements),
{ ...restoredAppState, offsetTop: 0, offsetLeft: 0, width: 0, height: 0 },
{ exportBackground, viewBackgroundColor },
{ exportBackground, viewBackgroundColor, shouldAddWatermark },
(width: number, height: number) => {
const canvas = document.createElement("canvas");
const ret = getDimensions(width, height);

View File

@ -34,22 +34,22 @@
]
},
"devDependencies": {
"@babel/core": "7.14.3",
"@babel/core": "7.14.2",
"@babel/plugin-transform-arrow-functions": "7.13.0",
"@babel/plugin-transform-async-to-generator": "7.13.0",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/plugin-transform-typescript": "7.14.3",
"@babel/plugin-transform-typescript": "7.13.0",
"@babel/preset-env": "7.14.1",
"@babel/preset-typescript": "7.13.0",
"babel-loader": "8.2.2",
"babel-plugin-transform-class-properties": "6.24.1",
"cross-env": "7.0.3",
"css-loader": "5.2.6",
"css-loader": "5.2.4",
"file-loader": "6.2.0",
"sass-loader": "11.1.1",
"ts-loader": "8.1.0",
"webpack": "5.37.1",
"webpack-bundle-analyzer": "4.4.2",
"webpack-bundle-analyzer": "4.4.1",
"webpack-cli": "4.7.0"
},
"bugs": "https://github.com/excalidraw/excalidraw/issues",

View File

@ -14,17 +14,17 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919"
integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==
"@babel/core@7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.3.tgz#5395e30405f0776067fbd9cf0884f15bfb770a38"
integrity sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==
"@babel/core@7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.2.tgz#54e45334ffc0172048e5c93ded36461d3ad4c417"
integrity sha512-OgC1mON+l4U4B4wiohJlQNUU3H73mpTyYY3j/c8U9dr9UagGGSm+WFpzjy/YLdoyjiG++c1kIDgxCo/mLwQJeQ==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.14.3"
"@babel/generator" "^7.14.2"
"@babel/helper-compilation-targets" "^7.13.16"
"@babel/helper-module-transforms" "^7.14.2"
"@babel/helpers" "^7.14.0"
"@babel/parser" "^7.14.3"
"@babel/parser" "^7.14.2"
"@babel/template" "^7.12.13"
"@babel/traverse" "^7.14.2"
"@babel/types" "^7.14.2"
@ -35,10 +35,10 @@
semver "^6.3.0"
source-map "^0.5.0"
"@babel/generator@^7.14.2", "@babel/generator@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.3.tgz#0c2652d91f7bddab7cccc6ba8157e4f40dcedb91"
integrity sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==
"@babel/generator@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.2.tgz#d5773e8b557d421fd6ce0d5efa5fd7fc22567c30"
integrity sha512-OnADYbKrffDVai5qcpkMxQ7caomHOoEwjkouqnN2QhydAjowFAZcsdecFIRUBdb+ZcruwYE4ythYmF1UBZU5xQ==
dependencies:
"@babel/types" "^7.14.2"
jsesc "^2.5.1"
@ -69,16 +69,27 @@
browserslist "^4.14.5"
semver "^6.3.0"
"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0", "@babel/helper-create-class-features-plugin@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.3.tgz#832111bcf4f57ca57a4c5b1a000fc125abc6554a"
integrity sha512-BnEfi5+6J2Lte9LeiL6TxLWdIlEv9Woacc1qXzXBgbikcOzMRM2Oya5XGg/f/ngotv1ej2A/b+3iJH8wbS1+lQ==
"@babel/helper-create-class-features-plugin@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.0.tgz#28d04ad9cfbd1ed1d8b988c9ea7b945263365846"
integrity sha512-twwzhthM4/+6o9766AW2ZBHpIHPSGrPGk1+WfHiu13u/lBnggXGNYCpeAyVfNwGDKfkhEDp+WOD/xafoJ2iLjA==
dependencies:
"@babel/helper-function-name" "^7.12.13"
"@babel/helper-member-expression-to-functions" "^7.13.0"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/helper-replace-supers" "^7.13.0"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/helper-create-class-features-plugin@^7.14.0":
version "7.14.1"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz#1fe11b376f3c41650ad9fedc665b0068722ea76c"
integrity sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==
dependencies:
"@babel/helper-annotate-as-pure" "^7.12.13"
"@babel/helper-function-name" "^7.14.2"
"@babel/helper-function-name" "^7.12.13"
"@babel/helper-member-expression-to-functions" "^7.13.12"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/helper-replace-supers" "^7.14.3"
"@babel/helper-replace-supers" "^7.13.12"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/helper-create-regexp-features-plugin@^7.12.13":
@ -236,16 +247,6 @@
"@babel/traverse" "^7.13.0"
"@babel/types" "^7.13.12"
"@babel/helper-replace-supers@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz#ca17b318b859d107f0e9b722d58cf12d94436600"
integrity sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.13.12"
"@babel/helper-optimise-call-expression" "^7.12.13"
"@babel/traverse" "^7.14.2"
"@babel/types" "^7.14.2"
"@babel/helper-simple-access@^7.13.12":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6"
@ -310,10 +311,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.3.tgz#9b530eecb071fd0c93519df25c5ff9f14759f298"
integrity sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==
"@babel/parser@^7.12.13", "@babel/parser@^7.14.2":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.2.tgz#0c1680aa44ad4605b16cbdcc5c341a61bde9c746"
integrity sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ==
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12":
version "7.13.12"
@ -801,12 +802,12 @@
dependencies:
"@babel/helper-plugin-utils" "^7.12.13"
"@babel/plugin-transform-typescript@7.14.3", "@babel/plugin-transform-typescript@^7.13.0":
version "7.14.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.3.tgz#44f67f725a60cccee33d9d6fee5e4f338258f34f"
integrity sha512-G5Bb5pY6tJRTC4ag1visSgiDoGgJ1u1fMUgmc2ijLkcIdzP83Q1qyZX4ggFQ/SkR+PNOatkaYC+nKcTlpsX4ag==
"@babel/plugin-transform-typescript@7.13.0", "@babel/plugin-transform-typescript@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853"
integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.14.3"
"@babel/helper-create-class-features-plugin" "^7.13.0"
"@babel/helper-plugin-utils" "^7.13.0"
"@babel/plugin-syntax-typescript" "^7.12.13"
@ -1353,15 +1354,15 @@ braces@^3.0.1:
fill-range "^7.0.1"
browserslist@^4.14.5, browserslist@^4.16.3:
version "4.16.6"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
version "4.16.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717"
integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==
dependencies:
caniuse-lite "^1.0.30001219"
colorette "^1.2.2"
electron-to-chromium "^1.3.723"
caniuse-lite "^1.0.30001181"
colorette "^1.2.1"
electron-to-chromium "^1.3.649"
escalade "^3.1.1"
node-releases "^1.1.71"
node-releases "^1.1.70"
buffer-from@^1.0.0:
version "1.1.1"
@ -1376,10 +1377,15 @@ call-bind@^1.0.0:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
caniuse-lite@^1.0.30001219:
version "1.0.30001230"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71"
integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==
camelcase@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30001181:
version "1.0.30001187"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz#5706942631f83baa5a0218b7dfa6ced29f845438"
integrity sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA==
chalk@^1.1.3:
version "1.1.3"
@ -1515,14 +1521,15 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
css-loader@5.2.6:
version "5.2.6"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.6.tgz#c3c82ab77fea1f360e587d871a6811f4450cc8d1"
integrity sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==
css-loader@5.2.4:
version "5.2.4"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.4.tgz#e985dcbce339812cb6104ef3670f08f9893a1536"
integrity sha512-OFYGyINCKkdQsTrSYxzGSFnGS4gNjcXkKkQgWxK138jgnPt+lepxdjSZNc8sHAl5vP3DhsJUxufWIjOwI8PMMw==
dependencies:
camelcase "^6.2.0"
icss-utils "^5.1.0"
loader-utils "^2.0.0"
postcss "^8.2.15"
postcss "^8.2.10"
postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0"
@ -1562,10 +1569,10 @@ duplexer@^0.1.2:
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
electron-to-chromium@^1.3.723:
version "1.3.739"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.739.tgz#f07756aa92cabd5a6eec6f491525a64fe62f98b9"
integrity sha512-+LPJVRsN7hGZ9EIUUiWCpO7l4E3qBYHNadazlucBfsXBbccDFNKUBAgzE68FnkWGJPwD/AfKhSzL+G+Iqb8A4A==
electron-to-chromium@^1.3.649:
version "1.3.666"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.666.tgz#59f3ce1e45b860a0ebe439b72664354efbb8bc62"
integrity sha512-/mP4HFQ0fKIX4sXltG6kfcoGrfNDZwCIyWbH2SIcVaa9u7Rm0HKjambiHNg5OEruicTl9s1EwbERLwxZwk19aw==
emojis-list@^3.0.0:
version "3.0.0"
@ -2054,20 +2061,20 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
nanoid@^3.1.23:
version "3.1.23"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
nanoid@^3.1.22:
version "3.1.22"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844"
integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==
neo-async@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
node-releases@^1.1.71:
version "1.1.72"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe"
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==
node-releases@^1.1.70:
version "1.1.70"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08"
integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==
npm-run-path@^4.0.1:
version "4.0.1"
@ -2199,14 +2206,14 @@ postcss-value-parser@^4.1.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
postcss@^8.2.15:
version "8.3.0"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f"
integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==
postcss@^8.2.10:
version "8.2.10"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.10.tgz#ca7a042aa8aff494b334d0ff3e9e77079f6f702b"
integrity sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==
dependencies:
colorette "^1.2.2"
nanoid "^3.1.23"
source-map-js "^0.6.2"
nanoid "^3.1.22"
source-map "^0.6.1"
process-nextick-args@~2.0.0:
version "2.0.1"
@ -2421,11 +2428,6 @@ source-list-map@^2.0.1:
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
source-map-js@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
source-map-support@~0.5.19:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
@ -2609,10 +2611,10 @@ watchpack@^2.0.0:
glob-to-regexp "^0.4.1"
graceful-fs "^4.1.2"
webpack-bundle-analyzer@4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.2.tgz#39898cf6200178240910d629705f0f3493f7d666"
integrity sha512-PIagMYhlEzFfhMYOzs5gFT55DkUdkyrJi/SxJp8EF3YMWhS+T9vvs2EoTetpk5qb6VsCq02eXTlRDOydRhDFAQ==
webpack-bundle-analyzer@4.4.1:
version "4.4.1"
resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.1.tgz#c71fb2eaffc10a4754d7303b224adb2342069da1"
integrity sha512-j5m7WgytCkiVBoOGavzNokBOqxe6Mma13X1asfVYtKWM3wxBiRRu1u1iG0Iol5+qp9WgyhkMmBAcvjEfJ2bdDw==
dependencies:
acorn "^8.0.4"
acorn-walk "^8.0.0"

View File

@ -1,13 +1,21 @@
import rough from "roughjs/bin/rough";
import oc from "open-color";
import { newTextElement } from "../element";
import { NonDeletedExcalidrawElement } from "../element/types";
import { getCommonBounds } from "../element/bounds";
import { renderScene, renderSceneToSvg } from "../renderer/renderScene";
import { distance, SVG_NS } from "../utils";
import { AppState } from "../types";
import { THEME_FILTER } from "../constants";
import { t } from "../i18n";
import {
DEFAULT_FONT_FAMILY,
DEFAULT_VERTICAL_ALIGN,
THEME_FILTER,
} from "../constants";
import { getDefaultAppState } from "../appState";
export const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;
const WATERMARK_HEIGHT = 16;
export const exportToCanvas = (
elements: readonly NonDeletedExcalidrawElement[],
@ -17,11 +25,13 @@ export const exportToCanvas = (
exportPadding = 10,
viewBackgroundColor,
scale = 1,
shouldAddWatermark,
}: {
exportBackground: boolean;
exportPadding?: number;
scale?: number;
viewBackgroundColor: string;
shouldAddWatermark: boolean;
},
createCanvas: (
width: number,
@ -33,7 +43,13 @@ export const exportToCanvas = (
return { canvas: tempCanvas, scale };
},
) => {
const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);
const sceneElements = getElementsAndWatermark(elements, shouldAddWatermark);
const [minX, minY, width, height] = getCanvasSize(
sceneElements,
exportPadding,
shouldAddWatermark,
);
const { canvas: tempCanvas, scale: newScale = scale } = createCanvas(
width,
@ -41,7 +57,7 @@ export const exportToCanvas = (
);
renderScene(
elements,
sceneElements,
appState,
null,
newScale,
@ -78,6 +94,7 @@ export const exportToSvg = (
viewBackgroundColor,
exportWithDarkMode,
scale = 1,
shouldAddWatermark,
metadata = "",
}: {
exportBackground: boolean;
@ -85,10 +102,17 @@ export const exportToSvg = (
scale?: number;
viewBackgroundColor: string;
exportWithDarkMode?: boolean;
shouldAddWatermark: boolean;
metadata?: string;
},
): SVGSVGElement => {
const [minX, minY, width, height] = getCanvasSize(elements, exportPadding);
const sceneElements = getElementsAndWatermark(elements, shouldAddWatermark);
const [minX, minY, width, height] = getCanvasSize(
sceneElements,
exportPadding,
shouldAddWatermark,
);
// initialze SVG root
const svgRoot = document.createElementNS(SVG_NS, "svg");
@ -130,7 +154,7 @@ export const exportToSvg = (
}
const rsvg = rough.svg(svgRoot);
renderSceneToSvg(elements, rsvg, svgRoot, {
renderSceneToSvg(sceneElements, rsvg, svgRoot, {
offsetX: -minX + exportPadding,
offsetY: -minY + exportPadding,
});
@ -138,14 +162,52 @@ export const exportToSvg = (
return svgRoot;
};
const getElementsAndWatermark = (
elements: readonly NonDeletedExcalidrawElement[],
shouldAddWatermark: boolean,
): readonly NonDeletedExcalidrawElement[] => {
let _elements = [...elements];
if (shouldAddWatermark) {
const [, , maxX, maxY] = getCommonBounds(elements);
_elements = [..._elements, getWatermarkElement(maxX, maxY)];
}
return _elements;
};
const getWatermarkElement = (maxX: number, maxY: number) => {
return newTextElement({
text: t("labels.madeWithExcalidraw"),
fontSize: WATERMARK_HEIGHT,
fontFamily: DEFAULT_FONT_FAMILY,
textAlign: "right",
verticalAlign: DEFAULT_VERTICAL_ALIGN,
x: maxX,
y: maxY + WATERMARK_HEIGHT,
strokeColor: oc.gray[5],
backgroundColor: "transparent",
fillStyle: "hachure",
strokeWidth: 1,
strokeStyle: "solid",
roughness: 1,
opacity: 100,
strokeSharpness: "sharp",
});
};
// calculate smallest area to fit the contents in
const getCanvasSize = (
elements: readonly NonDeletedExcalidrawElement[],
exportPadding: number,
shouldAddWatermark: boolean,
): [number, number, number, number] => {
const [minX, minY, maxX, maxY] = getCommonBounds(elements);
const width = distance(minX, maxX) + exportPadding * 2;
const height = distance(minY, maxY) + exportPadding + exportPadding;
const height =
distance(minY, maxY) +
exportPadding +
(shouldAddWatermark ? 0 : exportPadding);
return [minX, minY, width, height];
};
@ -153,11 +215,15 @@ const getCanvasSize = (
export const getExportSize = (
elements: readonly NonDeletedExcalidrawElement[],
exportPadding: number,
shouldAddWatermark: boolean,
scale: number,
): [number, number] => {
const sceneElements = getElementsAndWatermark(elements, shouldAddWatermark);
const [, , width, height] = getCanvasSize(
elements,
sceneElements,
exportPadding,
shouldAddWatermark,
).map((dimension) => Math.trunc(dimension * scale));
return [width, height];

View File

@ -57,6 +57,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -115,7 +116,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -128,7 +128,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -222,6 +221,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -306,7 +306,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -319,7 +318,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -356,7 +354,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -416,7 +413,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -533,6 +529,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -617,7 +614,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -630,7 +626,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -667,7 +662,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -727,7 +721,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -844,6 +837,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -902,7 +896,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -915,7 +908,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1007,6 +999,7 @@ Object {
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -1065,7 +1058,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -1078,7 +1070,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1113,7 +1104,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1207,6 +1197,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -1291,7 +1282,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -1304,7 +1294,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1341,7 +1330,6 @@ Object {
"selectedElementIds": Object {
"id0_copy": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1464,6 +1452,7 @@ Object {
"id3": true,
},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -1552,7 +1541,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -1565,7 +1553,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1602,7 +1589,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1664,9 +1650,6 @@ Object {
"id1": true,
"id2": true,
},
"selectedGroupIds": Object {
"id3": true,
},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1772,7 +1755,7 @@ Object {
"name": "Untitled-201933152653",
"offsetLeft": 20,
"offsetTop": 10,
"openMenu": "backgroundColorPicker",
"openMenu": null,
"pasteDialog": Object {
"data": null,
"shown": false,
@ -1787,6 +1770,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -1871,7 +1855,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -1884,7 +1867,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1921,7 +1903,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -1981,7 +1962,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2041,7 +2021,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2101,7 +2080,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2161,7 +2139,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2221,7 +2198,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2281,7 +2257,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2341,7 +2316,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2401,7 +2375,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2459,7 +2432,7 @@ Object {
exports[`contextMenu element selecting 'Paste styles' in context menu pastes styles: [end of test] number of elements 1`] = `2`;
exports[`contextMenu element selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `27`;
exports[`contextMenu element selecting 'Paste styles' in context menu pastes styles: [end of test] number of renders 1`] = `25`;
exports[`contextMenu element selecting 'Send backward' in context menu sends element backward: [end of test] appState 1`] = `
Object {
@ -2518,6 +2491,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -2602,7 +2576,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -2615,7 +2588,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2652,7 +2624,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2712,7 +2683,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2829,6 +2799,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -2913,7 +2884,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -2926,7 +2896,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -2963,7 +2932,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3023,7 +2991,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3144,6 +3111,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -3228,7 +3196,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -3241,7 +3208,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3278,7 +3244,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3340,9 +3305,6 @@ Object {
"id1": true,
"id2": true,
},
"selectedGroupIds": Object {
"id3": true,
},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3408,7 +3370,6 @@ Object {
"id1": true,
"id2": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3531,6 +3492,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -3615,7 +3577,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -3628,7 +3589,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3665,7 +3625,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3790,6 +3749,7 @@ Object {
"id4": true,
},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -3878,7 +3838,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -3891,7 +3850,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3928,7 +3886,6 @@ Object {
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -3991,9 +3948,6 @@ Object {
"id2": true,
"id3": true,
},
"selectedGroupIds": Object {
"id4": true,
},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -4112,6 +4066,7 @@ Object {
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -4144,7 +4099,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -4214,84 +4168,7 @@ Object {
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
"startBoundElement": null,
"suggestedBindings": Array [],
"theme": "light",
"toastMessage": null,
"viewBackgroundColor": "#ffffff",
"viewModeEnabled": false,
"width": 200,
"zenModeEnabled": false,
"zoom": Object {
"translation": Object {
"x": 0,
"y": 0,
},
"value": 1,
},
}
`;
exports[`contextMenu element shows context menu for element: [end of test] appState 2`] = `
Object {
"collaborators": Map {},
"currentChartType": "bar",
"currentItemBackgroundColor": "transparent",
"currentItemEndArrowhead": "arrow",
"currentItemFillStyle": "hachure",
"currentItemFontFamily": 1,
"currentItemFontSize": 20,
"currentItemLinearStrokeSharpness": "round",
"currentItemOpacity": 100,
"currentItemRoughness": 1,
"currentItemStartArrowhead": null,
"currentItemStrokeColor": "#000000",
"currentItemStrokeSharpness": "sharp",
"currentItemStrokeStyle": "solid",
"currentItemStrokeWidth": 1,
"currentItemTextAlign": "left",
"cursorButton": "up",
"draggingElement": null,
"editingElement": null,
"editingGroupId": null,
"editingLinearElement": null,
"elementLocked": false,
"elementType": "selection",
"errorMessage": null,
"exportBackground": true,
"exportEmbedScene": false,
"exportWithDarkMode": false,
"fileHandle": null,
"gridSize": null,
"height": 100,
"isBindingEnabled": true,
"isLibraryOpen": false,
"isLoading": false,
"isResizing": false,
"isRotating": false,
"lastPointerDownWith": "mouse",
"multiElement": null,
"name": "Untitled-201933152653",
"offsetLeft": 20,
"offsetTop": 10,
"openMenu": null,
"pasteDialog": Object {
"data": null,
"shown": false,
},
"previousSelectedElementIds": Object {},
"resizingElement": null,
"scrollX": 0,
"scrollY": 0,
"scrolledOutside": false,
"selectedElementIds": Object {
"id1": true,
},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,
@ -4339,58 +4216,6 @@ Object {
}
`;
exports[`contextMenu element shows context menu for element: [end of test] element 0 2`] = `
Object {
"angle": 0,
"backgroundColor": "red",
"boundElementIds": null,
"fillStyle": "hachure",
"groupIds": Array [],
"height": 200,
"id": "id0",
"isDeleted": false,
"opacity": 100,
"roughness": 1,
"seed": 337897,
"strokeColor": "#000000",
"strokeSharpness": "sharp",
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 1,
"versionNonce": 0,
"width": 200,
"x": 0,
"y": 0,
}
`;
exports[`contextMenu element shows context menu for element: [end of test] element 1 1`] = `
Object {
"angle": 0,
"backgroundColor": "red",
"boundElementIds": null,
"fillStyle": "hachure",
"groupIds": Array [],
"height": 200,
"id": "id1",
"isDeleted": false,
"opacity": 100,
"roughness": 1,
"seed": 1278240551,
"strokeColor": "#000000",
"strokeSharpness": "sharp",
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 1,
"versionNonce": 0,
"width": 200,
"x": 0,
"y": 0,
}
`;
exports[`contextMenu element shows context menu for element: [end of test] history 1`] = `
Object {
"recording": false,
@ -4402,7 +4227,6 @@ Object {
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
@ -4415,7 +4239,6 @@ Object {
"selectedElementIds": Object {
"id0": true,
},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [
@ -4448,30 +4271,6 @@ Object {
}
`;
exports[`contextMenu element shows context menu for element: [end of test] history 2`] = `
Object {
"recording": false,
"redoStack": Array [],
"stateHistory": Array [
Object {
"appState": Object {
"editingGroupId": null,
"editingLinearElement": null,
"name": "Untitled-201933152653",
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"viewBackgroundColor": "#ffffff",
},
"elements": Array [],
},
],
}
`;
exports[`contextMenu element shows context menu for element: [end of test] number of elements 1`] = `1`;
exports[`contextMenu element shows context menu for element: [end of test] number of elements 2`] = `2`;
exports[`contextMenu element shows context menu for element: [end of test] number of renders 1`] = `9`;
exports[`contextMenu element shows context menu for element: [end of test] number of renders 2`] = `6`;

View File

@ -121,9 +121,11 @@ exports[`<Excalidraw/> Test UIOptions prop Test canvasActions should not hide an
>
<path
d="M571 308l-95.7-96.4c-10.1-10.1-27.4-3-27.4 11.3V288h-64v64h64v65.2c0 14.3 17.3 21.4 27.4 11.3L571 332c6.6-6.6 6.6-17.4 0-24zm-187 44v-64 64z"
fill-rule="nonzero"
/>
<path
d="M384 121.941V128H256V0h6.059c6.362 0 12.471 2.53 16.97 7.029l97.941 97.941a24.01 24.01 0 017.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z"
fill-rule="nonzero"
/>
</svg>
</div>
@ -320,9 +322,11 @@ exports[`<Excalidraw/> Test UIOptions prop should not hide any UI element when t
>
<path
d="M571 308l-95.7-96.4c-10.1-10.1-27.4-3-27.4 11.3V288h-64v64h64v65.2c0 14.3 17.3 21.4 27.4 11.3L571 332c6.6-6.6 6.6-17.4 0-24zm-187 44v-64 64z"
fill-rule="nonzero"
/>
<path
d="M384 121.941V128H256V0h6.059c6.362 0 12.471 2.53 16.97 7.029l97.941 97.941a24.01 24.01 0 017.03 16.971zM248 160c-13.2 0-24-10.8-24-24V0H24C10.745 0 0 10.745 0 24v464c0 13.255 10.745 24 24 24h336c13.255 0 24-10.745 24-24V160H248zm-135.455 16c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.491-48 48-48zm208 240h-256l.485-48.485L104.545 328c4.686-4.686 11.799-4.201 16.485.485L160.545 368 264.06 264.485c4.686-4.686 12.284-4.686 16.971 0L320.545 304v112z"
fill-rule="nonzero"
/>
</svg>
</div>

File diff suppressed because it is too large Load Diff

View File

@ -147,46 +147,6 @@ describe("contextMenu element", () => {
});
});
it("shows context menu for element", () => {
const rect1 = API.createElement({
type: "rectangle",
x: 0,
y: 0,
height: 200,
width: 200,
backgroundColor: "red",
});
const rect2 = API.createElement({
type: "rectangle",
x: 0,
y: 0,
height: 200,
width: 200,
backgroundColor: "red",
});
h.elements = [rect1, rect2];
API.setSelectedElements([rect1]);
// lower z-index
fireEvent.contextMenu(GlobalTestState.canvas, {
button: 2,
clientX: 100,
clientY: 100,
});
expect(queryContextMenu()).not.toBeNull();
expect(API.getSelectedElement().id).toBe(rect1.id);
// higher z-index
API.setSelectedElements([rect2]);
fireEvent.contextMenu(GlobalTestState.canvas, {
button: 2,
clientX: 100,
clientY: 100,
});
expect(queryContextMenu()).not.toBeNull();
expect(API.getSelectedElement().id).toBe(rect2.id);
});
it("shows 'Group selection' in context menu for multiple selected elements", () => {
UI.clickTool("rectangle");
mouse.down(10, 10);

View File

@ -167,13 +167,6 @@ describe("<Excalidraw/>", () => {
);
expect(queryByTestId(container, "json-export-button")).toBeNull();
});
it("should hide 'Save as image' button when 'saveAsImage' is false", async () => {
const { container } = await render(
<Excalidraw UIOptions={{ canvasActions: { saveAsImage: false } }} />,
);
expect(queryByTestId(container, "image-export-button")).toBeNull();
});
@ -185,21 +178,17 @@ describe("<Excalidraw/>", () => {
expect(queryByTestId(container, "load-button")).toBeNull();
});
it("should hide save as button when saveFileToDisk is false", async () => {
it("should hide save as button when saveAsScene is false", async () => {
const { container } = await render(
<Excalidraw
UIOptions={{ canvasActions: { export: { saveFileToDisk: false } } }}
/>,
<Excalidraw UIOptions={{ canvasActions: { saveAsScene: false } }} />,
);
expect(queryByTestId(container, "save-as-button")).toBeNull();
});
it("should hide save button when saveToActiveFile is false", async () => {
it("should hide save button when saveScene is false", async () => {
const { container } = await render(
<Excalidraw
UIOptions={{ canvasActions: { saveToActiveFile: false } }}
/>,
<Excalidraw UIOptions={{ canvasActions: { saveScene: false } }} />,
);
expect(queryByTestId(container, "save-button")).toBeNull();

View File

@ -20,15 +20,6 @@ const readFile = util.promisify(fs.readFile);
const { h } = window;
export class API {
static setSelectedElements = (elements: ExcalidrawElement[]) => {
h.setState({
selectedElementIds: elements.reduce((acc, element) => {
acc[element.id] = true;
return acc;
}, {} as Record<ExcalidrawElement["id"], true>),
});
};
static getSelectedElements = (): ExcalidrawElement[] => {
return h.elements.filter(
(element) => h.state.selectedElementIds[element.id],

View File

@ -1,7 +1,7 @@
import React from "react";
import { assertSelectedElements, render } from "./test-utils";
import { render } from "./test-utils";
import ExcalidrawApp from "../excalidraw-app";
import { Keyboard, Pointer, UI } from "./helpers/ui";
import { UI } from "./helpers/ui";
import { API } from "./helpers/api";
import { getDefaultAppState } from "../appState";
import { waitFor } from "@testing-library/react";
@ -10,8 +10,6 @@ import { EXPORT_DATA_TYPES } from "../constants";
const { h } = window;
const mouse = new Pointer("mouse");
describe("history", () => {
it("initializing scene should end up with single history entry", async () => {
await render(<ExcalidrawApp />, {
@ -112,78 +110,4 @@ describe("history", () => {
expect.objectContaining({ id: "A", isDeleted: true }),
]);
});
it("undo/redo works properly with groups", async () => {
await render(<ExcalidrawApp />);
const rect1 = API.createElement({ type: "rectangle", groupIds: ["A"] });
const rect2 = API.createElement({ type: "rectangle", groupIds: ["A"] });
h.elements = [rect1, rect2];
mouse.select(rect1);
assertSelectedElements([rect1, rect2]);
expect(h.state.selectedGroupIds).toEqual({ A: true });
Keyboard.withModifierKeys({ ctrl: true }, () => {
Keyboard.keyPress("d");
});
expect(h.elements.length).toBe(4);
assertSelectedElements([h.elements[2], h.elements[3]]);
expect(h.state.selectedGroupIds).not.toEqual(
expect.objectContaining({ A: true }),
);
Keyboard.withModifierKeys({ ctrl: true }, () => {
Keyboard.keyPress("z");
});
expect(h.elements.length).toBe(4);
expect(h.elements).toEqual([
expect.objectContaining({ id: rect1.id, isDeleted: false }),
expect.objectContaining({ id: rect2.id, isDeleted: false }),
expect.objectContaining({ id: `${rect1.id}_copy`, isDeleted: true }),
expect.objectContaining({ id: `${rect2.id}_copy`, isDeleted: true }),
]);
expect(h.state.selectedGroupIds).toEqual({ A: true });
Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => {
Keyboard.keyPress("z");
});
expect(h.elements.length).toBe(4);
expect(h.elements).toEqual([
expect.objectContaining({ id: rect1.id, isDeleted: false }),
expect.objectContaining({ id: rect2.id, isDeleted: false }),
expect.objectContaining({ id: `${rect1.id}_copy`, isDeleted: false }),
expect.objectContaining({ id: `${rect2.id}_copy`, isDeleted: false }),
]);
expect(h.state.selectedGroupIds).not.toEqual(
expect.objectContaining({ A: true }),
);
// undo again, and duplicate once more
// -------------------------------------------------------------------------
Keyboard.withModifierKeys({ ctrl: true }, () => {
Keyboard.keyPress("z");
Keyboard.keyPress("d");
});
expect(h.elements.length).toBe(6);
expect(h.elements).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: rect1.id, isDeleted: false }),
expect.objectContaining({ id: rect2.id, isDeleted: false }),
expect.objectContaining({ id: `${rect1.id}_copy`, isDeleted: true }),
expect.objectContaining({ id: `${rect2.id}_copy`, isDeleted: true }),
expect.objectContaining({
id: `${rect1.id}_copy_copy`,
isDeleted: false,
}),
expect.objectContaining({
id: `${rect2.id}_copy_copy`,
isDeleted: false,
}),
]),
);
expect(h.state.selectedGroupIds).not.toEqual(
expect.objectContaining({ A: true }),
);
});
});

View File

@ -54,6 +54,7 @@ Object {
"selectedElementIds": Object {},
"selectedGroupIds": Object {},
"selectionElement": null,
"shouldAddWatermark": false,
"shouldCacheIgnoreZoom": false,
"showHelpDialog": false,
"showStats": false,

View File

@ -7,19 +7,21 @@ import * as Renderer from "../renderer/renderScene";
import { setDateTimeForTests } from "../utils";
import { API } from "./helpers/api";
import { Keyboard, Pointer, UI } from "./helpers/ui";
import {
assertSelectedElements,
fireEvent,
render,
screen,
waitFor,
} from "./test-utils";
import { fireEvent, render, screen, waitFor } from "./test-utils";
import { defaultLang } from "../i18n";
const { h } = window;
const renderScene = jest.spyOn(Renderer, "renderScene");
const assertSelectedElements = (...elements: ExcalidrawElement[]) => {
expect(
API.getSelectedElements().map((element) => {
return element.id;
}),
).toEqual(expect.arrayContaining(elements.map((element) => element.id)));
};
const mouse = new Pointer("mouse");
const finger1 = new Pointer("touch", 1);
const finger2 = new Pointer("touch", 2);
@ -700,36 +702,33 @@ describe("regression tests", () => {
"when clicking intersection between A and B " +
"B should be selected on pointer up",
() => {
// set background color since default is transparent
UI.clickTool("rectangle");
// change background color since default is transparent
// and transparent elements can't be selected by clicking inside of them
const rect1 = API.createElement({
type: "rectangle",
backgroundColor: "red",
x: 0,
y: 0,
width: 1000,
height: 1000,
});
const rect2 = API.createElement({
type: "rectangle",
backgroundColor: "red",
x: 500,
y: 500,
width: 500,
height: 500,
});
h.elements = [rect1, rect2];
clickLabeledElement("Background");
clickLabeledElement("#fa5252");
mouse.down();
mouse.up(1000, 1000);
mouse.select(rect1);
// draw ellipse partially over rectangle.
// since ellipse was created after rectangle it has an higher z-index.
// we don't need to change background color again since change above
// affects next drawn elements.
UI.clickTool("ellipse");
mouse.reset();
mouse.down(500, 500);
mouse.up(1000, 1000);
// pointerdown on rect2 covering rect1 while rect1 is selected should
// retain rect1 selection
// select rectangle
mouse.reset();
mouse.click();
// pointer down on intersection between ellipse and rectangle
mouse.down(900, 900);
expect(API.getSelectedElement().id).toBe(rect1.id);
expect(API.getSelectedElement().type).toBe("rectangle");
// pointerup should select rect2
mouse.up();
expect(API.getSelectedElement().id).toBe(rect2.id);
expect(API.getSelectedElement().type).toBe("ellipse");
},
);
@ -738,27 +737,26 @@ describe("regression tests", () => {
"when dragging on intersection between A and B " +
"A should be dragged and keep being selected",
() => {
const rect1 = API.createElement({
type: "rectangle",
backgroundColor: "red",
x: 0,
y: 0,
width: 1000,
height: 1000,
});
const rect2 = API.createElement({
type: "rectangle",
backgroundColor: "red",
x: 500,
y: 500,
width: 500,
height: 500,
});
h.elements = [rect1, rect2];
UI.clickTool("rectangle");
// change background color since default is transparent
// and transparent elements can't be selected by clicking inside of them
clickLabeledElement("Background");
clickLabeledElement("#fa5252");
mouse.down();
mouse.up(1000, 1000);
mouse.select(rect1);
// draw ellipse partially over rectangle.
// since ellipse was created after rectangle it has an higher z-index.
// we don't need to change background color again since change above
// affects next drawn elements.
UI.clickTool("ellipse");
mouse.reset();
mouse.down(500, 500);
mouse.up(1000, 1000);
expect(API.getSelectedElement().id).toBe(rect1.id);
// select rectangle
mouse.reset();
mouse.click();
const { x: prevX, y: prevY } = API.getSelectedElement();
@ -766,7 +764,7 @@ describe("regression tests", () => {
mouse.down(900, 900);
mouse.up(100, 100);
expect(API.getSelectedElement().id).toBe(rect1.id);
expect(API.getSelectedElement().type).toBe("rectangle");
expect(API.getSelectedElement().x).toEqual(prevX + 100);
expect(API.getSelectedElement().y).toEqual(prevY + 100);
},

View File

@ -13,6 +13,7 @@ describe("exportToSvg", () => {
const DEFAULT_OPTIONS = {
exportBackground: false,
viewBackgroundColor: "#ffffff",
shouldAddWatermark: false,
};
it("with default arguments", () => {
@ -36,6 +37,17 @@ describe("exportToSvg", () => {
);
});
it("with watermark", () => {
const svgElement = exportUtils.exportToSvg(ELEMENTS, {
...DEFAULT_OPTIONS,
shouldAddWatermark: true,
});
expect(svgElement.querySelector("text")?.textContent).toMatchInlineSnapshot(
`"Made with Excalidraw"`,
);
});
it("with dark mode", () => {
const svgElement = exportUtils.exportToSvg(ELEMENTS, {
...DEFAULT_OPTIONS,

View File

@ -5,7 +5,6 @@ import {
fireEvent,
mockBoundingClientRect,
restoreOriginalGetBoundingClientRect,
assertSelectedElements,
} from "./test-utils";
import ExcalidrawApp from "../excalidraw-app";
import * as Renderer from "../renderer/renderScene";
@ -13,6 +12,7 @@ import { KEYS } from "../keys";
import { reseed } from "../random";
import { API } from "./helpers/api";
import { Keyboard, Pointer } from "./helpers/ui";
import { getSelectedElements } from "../scene";
// Unmount ReactDOM from root
ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
@ -28,6 +28,12 @@ const { h } = window;
const mouse = new Pointer("mouse");
const assertSelectedIds = (ids: string[]) => {
expect(
getSelectedElements(h.app.getSceneElements(), h.state).map((el) => el.id),
).toEqual(ids);
};
describe("inner box-selection", () => {
beforeEach(async () => {
await render(<ExcalidrawApp />);
@ -62,7 +68,7 @@ describe("inner box-selection", () => {
mouse.moveTo(290, 290);
mouse.up();
assertSelectedElements([rect2.id, rect3.id]);
assertSelectedIds([rect2.id, rect3.id]);
});
});
@ -99,7 +105,7 @@ describe("inner box-selection", () => {
mouse.moveTo(rect2.x + rect2.width + 10, rect2.y + rect2.height + 10);
mouse.up();
assertSelectedElements([rect2.id, rect3.id]);
assertSelectedIds([rect2.id, rect3.id]);
expect(h.state.selectedGroupIds).toEqual({ A: true });
});
});
@ -134,62 +140,16 @@ describe("inner box-selection", () => {
Keyboard.withModifierKeys({ ctrl: true }, () => {
mouse.downAt(rect2.x - 20, rect2.x - 20);
mouse.moveTo(rect2.x + rect2.width + 10, rect2.y + rect2.height + 10);
assertSelectedElements([rect2.id, rect3.id]);
assertSelectedIds([rect2.id, rect3.id]);
expect(h.state.selectedGroupIds).toEqual({ A: true });
mouse.moveTo(rect2.x - 10, rect2.y - 10);
assertSelectedElements([rect1.id]);
assertSelectedIds([rect1.id]);
expect(h.state.selectedGroupIds).toEqual({});
mouse.up();
});
});
});
describe("selecting with cmd/ctrl modifier", () => {
beforeEach(async () => {
await render(<ExcalidrawApp />);
});
it("cycling through elements under cursor", async () => {
const rect1 = API.createElement({
type: "rectangle",
x: 0,
y: 0,
width: 200,
height: 200,
backgroundColor: "red",
fillStyle: "solid",
});
const rect2 = API.createElement({
type: "rectangle",
x: 0,
y: 0,
width: 200,
height: 200,
backgroundColor: "red",
fillStyle: "solid",
});
const rect3 = API.createElement({
type: "rectangle",
x: 0,
y: 0,
width: 200,
height: 200,
backgroundColor: "red",
fillStyle: "solid",
});
h.elements = [rect1, rect2, rect3];
Keyboard.withModifierKeys({ ctrl: true }, () => {
mouse.clickAt(100, 100);
assertSelectedElements(rect3);
mouse.clickAt(100, 100);
assertSelectedElements(rect2);
mouse.clickAt(100, 100);
assertSelectedElements(rect1);
mouse.clickAt(100, 100);
assertSelectedElements(rect3);
});
});
});
describe("selection element", () => {
it("create selection element on pointer down", async () => {
const { getByToolName, container } = await render(<ExcalidrawApp />);

View File

@ -13,8 +13,6 @@ import { ImportedDataState } from "../data/types";
import { STORAGE_KEYS } from "../excalidraw-app/data/localStorage";
import { SceneData } from "../types";
import { getSelectedElements } from "../scene/selection";
import { ExcalidrawElement } from "../element/types";
const customQueries = {
...queries,
@ -126,22 +124,3 @@ export const mockBoundingClientRect = () => {
export const restoreOriginalGetBoundingClientRect = () => {
global.window.HTMLDivElement.prototype.getBoundingClientRect = originalGetBoundingClientRect;
};
export const assertSelectedElements = (
...elements: (
| (ExcalidrawElement["id"] | ExcalidrawElement)[]
| ExcalidrawElement["id"]
| ExcalidrawElement
)[]
) => {
const { h } = window;
const selectedElementIds = getSelectedElements(
h.app.getSceneElements(),
h.state,
).map((el) => el.id);
const ids = elements
.flat()
.map((item) => (typeof item === "string" ? item : item.id));
expect(selectedElementIds.length).toBe(ids.length);
expect(selectedElementIds).toEqual(expect.arrayContaining(ids));
};

View File

@ -58,6 +58,7 @@ export type AppState = {
exportBackground: boolean;
exportEmbedScene: boolean;
exportWithDarkMode: boolean;
shouldAddWatermark: boolean;
currentItemStrokeColor: string;
currentItemBackgroundColor: string;
currentItemFillStyle: ExcalidrawElement["fillStyle"];
@ -81,13 +82,7 @@ export type AppState = {
isResizing: boolean;
isRotating: boolean;
zoom: Zoom;
openMenu:
| "canvas"
| "shape"
| "canvasColorPicker"
| "backgroundColorPicker"
| "strokeColorPicker"
| null;
openMenu: "canvas" | "shape" | null;
lastPointerDownWith: PointerType;
selectedElementIds: { [id: string]: boolean };
previousSelectedElementIds: { [id: string]: boolean };
@ -178,6 +173,11 @@ export interface ExcalidrawProps {
button: "down" | "up";
pointersMap: Gesture["pointers"];
}) => void;
onExportToBackend?: (
exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
canvas: HTMLCanvasElement | null,
) => void;
onPaste?: (
data: ClipboardData,
event: ClipboardEvent | null,
@ -214,28 +214,14 @@ export enum UserIdleState {
IDLE = "idle",
}
export type ExportOpts = {
saveFileToDisk?: boolean;
onExportToBackend?: (
exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
canvas: HTMLCanvasElement | null,
) => void;
renderCustomUI?: (
exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
canvas: HTMLCanvasElement | null,
) => JSX.Element;
};
type CanvasActions = {
changeViewBackgroundColor?: boolean;
clearCanvas?: boolean;
export?: false | ExportOpts;
export?: boolean;
loadScene?: boolean;
saveToActiveFile?: boolean;
saveAsScene?: boolean;
saveScene?: boolean;
theme?: boolean;
saveAsImage?: boolean;
};
export type UIOptions = {
@ -244,7 +230,7 @@ export type UIOptions = {
export type AppProps = ExcalidrawProps & {
UIOptions: {
canvasActions: Required<CanvasActions> & { export: ExportOpts };
canvasActions: Required<CanvasActions>;
};
detectScroll: boolean;
handleKeyboardGlobally: boolean;

View File

@ -4595,9 +4595,8 @@ dns-equal@^1.0.0:
resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz"
dns-packet@^1.3.1:
version "1.3.4"
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f"
integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==
version "1.3.1"
resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz"
dependencies:
ip "^1.1.0"
safe-buffer "^5.0.1"
@ -10900,14 +10899,13 @@ rxjs@^6.4.0, rxjs@^6.6.0, rxjs@^6.6.6:
dependencies:
tslib "^1.9.0"
safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
safe-buffer@^5.2.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
safe-regex@^1.1.0:
version "1.1.0"