mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
calculate coords based on container viewport position (#1955)
* feat: calculate coords based on parent left and top so it renders correctly in host App * fix text * move offsets to state & fix bugs * fix text jumping * account for zoom in textWysiwyg & undo incorrect offsetting Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
parent
63edbb9517
commit
7eff6893c5
20 changed files with 361 additions and 179 deletions
|
@ -2,28 +2,13 @@ import { getDefaultAppState, cleanAppStateForExport } from "../appState";
|
|||
import { restore } from "./restore";
|
||||
import { t } from "../i18n";
|
||||
import { AppState } from "../types";
|
||||
import { calculateScrollCenter } from "../scene";
|
||||
|
||||
export const loadFromBlob = async (blob: any) => {
|
||||
const updateAppState = (contents: string) => {
|
||||
const defaultAppState = getDefaultAppState();
|
||||
let elements = [];
|
||||
let appState = defaultAppState;
|
||||
try {
|
||||
const data = JSON.parse(contents);
|
||||
if (data.type !== "excalidraw") {
|
||||
throw new Error(t("alerts.couldNotLoadInvalidFile"));
|
||||
}
|
||||
elements = data.elements || [];
|
||||
appState = {
|
||||
...defaultAppState,
|
||||
...cleanAppStateForExport(data.appState as Partial<AppState>),
|
||||
};
|
||||
} catch {
|
||||
throw new Error(t("alerts.couldNotLoadInvalidFile"));
|
||||
}
|
||||
return { elements, appState };
|
||||
};
|
||||
|
||||
/**
|
||||
* @param blob
|
||||
* @param appState if provided, used for centering scroll to restored scene
|
||||
*/
|
||||
export const loadFromBlob = async (blob: any, appState?: AppState) => {
|
||||
if (blob.handle) {
|
||||
(window as any).handle = blob.handle;
|
||||
}
|
||||
|
@ -42,6 +27,23 @@ export const loadFromBlob = async (blob: any) => {
|
|||
});
|
||||
}
|
||||
|
||||
const { elements, appState } = updateAppState(contents);
|
||||
return restore(elements, appState, { scrollToContent: true });
|
||||
const defaultAppState = getDefaultAppState();
|
||||
let elements = [];
|
||||
let _appState = appState || defaultAppState;
|
||||
try {
|
||||
const data = JSON.parse(contents);
|
||||
if (data.type !== "excalidraw") {
|
||||
throw new Error(t("alerts.couldNotLoadInvalidFile"));
|
||||
}
|
||||
elements = data.elements || [];
|
||||
_appState = {
|
||||
...defaultAppState,
|
||||
...cleanAppStateForExport(data.appState as Partial<AppState>),
|
||||
...(appState ? calculateScrollCenter(elements, appState, null) : {}),
|
||||
};
|
||||
} catch {
|
||||
throw new Error(t("alerts.couldNotLoadInvalidFile"));
|
||||
}
|
||||
|
||||
return restore(elements, _appState);
|
||||
};
|
||||
|
|
|
@ -237,7 +237,7 @@ export const importFromBackend = async (
|
|||
privateKey: string | undefined,
|
||||
) => {
|
||||
let elements: readonly ExcalidrawElement[] = [];
|
||||
let appState: AppState = getDefaultAppState();
|
||||
let appState = getDefaultAppState();
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
|
@ -245,7 +245,7 @@ export const importFromBackend = async (
|
|||
);
|
||||
if (!response.ok) {
|
||||
window.alert(t("alerts.importBackendFailed"));
|
||||
return restore(elements, appState, { scrollToContent: true });
|
||||
return restore(elements, appState);
|
||||
}
|
||||
let data;
|
||||
if (privateKey) {
|
||||
|
@ -276,7 +276,7 @@ export const importFromBackend = async (
|
|||
window.alert(t("alerts.importBackendFailed"));
|
||||
console.error(error);
|
||||
} finally {
|
||||
return restore(elements, appState, { scrollToContent: true });
|
||||
return restore(elements, appState);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -42,11 +42,11 @@ export const saveAsJSON = async (
|
|||
);
|
||||
};
|
||||
|
||||
export const loadFromJSON = async () => {
|
||||
export const loadFromJSON = async (appState: AppState) => {
|
||||
const blob = await fileOpen({
|
||||
description: "Excalidraw files",
|
||||
extensions: ["json", "excalidraw"],
|
||||
mimeTypes: ["application/json"],
|
||||
});
|
||||
return loadFromBlob(blob);
|
||||
return loadFromBlob(blob, appState);
|
||||
};
|
||||
|
|
|
@ -6,7 +6,6 @@ import {
|
|||
import { AppState } from "../types";
|
||||
import { DataState } from "./types";
|
||||
import { isInvisiblySmallElement, getNormalizedDimensions } from "../element";
|
||||
import { calculateScrollCenter } from "../scene";
|
||||
import { randomId } from "../random";
|
||||
import {
|
||||
FONT_FAMILY,
|
||||
|
@ -110,8 +109,7 @@ const migrateElement = (
|
|||
|
||||
export const restore = (
|
||||
savedElements: readonly ExcalidrawElement[],
|
||||
savedState: AppState | null,
|
||||
opts?: { scrollToContent: boolean },
|
||||
savedState: MarkOptional<AppState, "offsetTop" | "offsetLeft"> | null,
|
||||
): DataState => {
|
||||
const elements = savedElements.reduce((elements, element) => {
|
||||
// filtering out selection, which is legacy, no longer kept in elements,
|
||||
|
@ -125,13 +123,6 @@ export const restore = (
|
|||
return elements;
|
||||
}, [] as ExcalidrawElement[]);
|
||||
|
||||
if (opts?.scrollToContent && savedState) {
|
||||
savedState = {
|
||||
...savedState,
|
||||
...calculateScrollCenter(elements, savedState, null),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
elements: elements,
|
||||
appState: savedState,
|
||||
|
|
|
@ -6,5 +6,5 @@ export interface DataState {
|
|||
version?: string;
|
||||
source?: string;
|
||||
elements: readonly ExcalidrawElement[];
|
||||
appState: AppState | null;
|
||||
appState: MarkOptional<AppState, "offsetTop" | "offsetLeft"> | null;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue