mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
[debug] 2
This commit is contained in:
parent
72de65e482
commit
d5f55aba44
2 changed files with 207 additions and 21 deletions
|
@ -27,6 +27,7 @@ import {
|
|||
LiveCollaborationTrigger,
|
||||
TTDDialog,
|
||||
TTDDialogTrigger,
|
||||
getCommonBounds,
|
||||
} from "../packages/excalidraw/index";
|
||||
import {
|
||||
AppState,
|
||||
|
@ -35,6 +36,7 @@ import {
|
|||
BinaryFiles,
|
||||
ExcalidrawInitialDataState,
|
||||
UIAppState,
|
||||
ScrollConstraints,
|
||||
} from "../packages/excalidraw/types";
|
||||
import {
|
||||
debounce,
|
||||
|
@ -98,15 +100,161 @@ import { useAtomWithInitialValue } from "../packages/excalidraw/jotai";
|
|||
import { appJotaiStore } from "./app-jotai";
|
||||
|
||||
import "./index.scss";
|
||||
import { ResolutionType } from "../packages/excalidraw/utility-types";
|
||||
import { Merge, ResolutionType } from "../packages/excalidraw/utility-types";
|
||||
import { ShareableLinkDialog } from "../packages/excalidraw/components/ShareableLinkDialog";
|
||||
import { openConfirmModal } from "../packages/excalidraw/components/OverwriteConfirm/OverwriteConfirmState";
|
||||
import { OverwriteConfirmDialog } from "../packages/excalidraw/components/OverwriteConfirm/OverwriteConfirm";
|
||||
import Trans from "../packages/excalidraw/components/Trans";
|
||||
import { ShareDialog, shareDialogStateAtom } from "./share/ShareDialog";
|
||||
import { getSelectedElements } from "../packages/excalidraw/scene";
|
||||
|
||||
polyfill();
|
||||
|
||||
type DebugScrollConstraints = Merge<
|
||||
ScrollConstraints,
|
||||
{ viewportZoomFactor: number; enabled: boolean }
|
||||
>;
|
||||
|
||||
const ConstraintsSettings = ({
|
||||
initialConstraints,
|
||||
excalidrawAPI,
|
||||
}: {
|
||||
initialConstraints: DebugScrollConstraints;
|
||||
excalidrawAPI: ExcalidrawImperativeAPI;
|
||||
}) => {
|
||||
const [constraints, setConstraints] =
|
||||
useState<DebugScrollConstraints>(initialConstraints);
|
||||
|
||||
useEffect(() => {
|
||||
// add JSON-stringified constraints into url hash for easy sharing
|
||||
const hash = new URLSearchParams(window.location.hash.slice(1));
|
||||
hash.set(
|
||||
"constraints",
|
||||
encodeURIComponent(
|
||||
window.btoa(JSON.stringify(constraints)).replace(/=+/, ""),
|
||||
),
|
||||
);
|
||||
window.location.hash = decodeURIComponent(hash.toString());
|
||||
}, [constraints]);
|
||||
|
||||
const [selection, setSelection] = useState<ExcalidrawElement[]>([]);
|
||||
useEffect(() => {
|
||||
return excalidrawAPI.onChange((elements, appState) => {
|
||||
setSelection(getSelectedElements(elements, appState));
|
||||
});
|
||||
}, [excalidrawAPI]);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
position: "fixed",
|
||||
bottom: 10,
|
||||
left: "calc(50%)",
|
||||
transform: "translateX(-50%)",
|
||||
gap: "0.6rem",
|
||||
zIndex: 999999,
|
||||
}}
|
||||
>
|
||||
enabled:{" "}
|
||||
<input
|
||||
type="checkbox"
|
||||
defaultChecked={!!constraints.enabled}
|
||||
onChange={(e) =>
|
||||
setConstraints((s) => ({ ...s, enabled: e.target.checked }))
|
||||
}
|
||||
/>
|
||||
x:{" "}
|
||||
<input
|
||||
placeholder="x"
|
||||
size={4}
|
||||
value={constraints.x.toString()}
|
||||
onChange={(e) =>
|
||||
setConstraints((s) => ({
|
||||
...s,
|
||||
x: parseInt(e.target.value) ?? 0,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
y:{" "}
|
||||
<input
|
||||
placeholder="y"
|
||||
size={4}
|
||||
value={constraints.y.toString()}
|
||||
onChange={(e) =>
|
||||
setConstraints((s) => ({
|
||||
...s,
|
||||
y: parseInt(e.target.value) ?? 0,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
w:{" "}
|
||||
<input
|
||||
placeholder="width"
|
||||
size={4}
|
||||
value={constraints.width.toString()}
|
||||
onChange={(e) =>
|
||||
setConstraints((s) => ({
|
||||
...s,
|
||||
x: parseInt(e.target.value) ?? 200,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
h:{" "}
|
||||
<input
|
||||
placeholder="height"
|
||||
size={4}
|
||||
value={constraints.height.toString()}
|
||||
onChange={(e) =>
|
||||
setConstraints((s) => ({
|
||||
...s,
|
||||
x: parseInt(e.target.value) ?? 200,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
zoomFactor:
|
||||
<input
|
||||
placeholder="height"
|
||||
type="number"
|
||||
min="0.1"
|
||||
max="1"
|
||||
step="0.1"
|
||||
value={constraints.viewportZoomFactor.toString()}
|
||||
onChange={(e) =>
|
||||
setConstraints((s) => ({
|
||||
...s,
|
||||
viewportZoomFactor: parseFloat(e.target.value.toString()) ?? 0.7,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
lockZoom:{" "}
|
||||
<input
|
||||
type="checkbox"
|
||||
defaultChecked={!!constraints.lockZoom}
|
||||
onChange={(e) =>
|
||||
setConstraints((s) => ({ ...s, lockZoom: e.target.checked }))
|
||||
}
|
||||
/>
|
||||
{selection.length > 0 && (
|
||||
<button
|
||||
onClick={() => {
|
||||
const bbox = getCommonBounds(selection);
|
||||
setConstraints((s) => ({
|
||||
...s,
|
||||
x: Math.round(bbox[0]),
|
||||
y: Math.round(bbox[1]),
|
||||
width: Math.round(bbox[2] - bbox[0]),
|
||||
height: Math.round(bbox[3] - bbox[1]),
|
||||
}));
|
||||
}}
|
||||
>
|
||||
use selection
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
window.EXCALIDRAW_THROTTLE_RENDER = true;
|
||||
|
||||
let isSelfEmbedding = false;
|
||||
|
@ -151,10 +299,22 @@ const initializeScene = async (opts: {
|
|||
)
|
||||
> => {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const hashParams = new URLSearchParams(window.location.hash.slice(1));
|
||||
const id = searchParams.get("id");
|
||||
const jsonBackendMatch = window.location.hash.match(
|
||||
/^#json=([a-zA-Z0-9_-]+),([a-zA-Z0-9_-]+)$/,
|
||||
);
|
||||
const shareableLink = hashParams.get("json")?.split(",");
|
||||
|
||||
if (shareableLink) {
|
||||
hashParams.delete("json");
|
||||
const hash = `#${decodeURIComponent(hashParams.toString())}`;
|
||||
window.history.replaceState(
|
||||
{},
|
||||
APP_NAME,
|
||||
`${window.location.origin}${hash}`,
|
||||
);
|
||||
}
|
||||
|
||||
console.log({ shareableLink });
|
||||
|
||||
const externalUrlMatch = window.location.hash.match(/^#url=(.*)$/);
|
||||
|
||||
const localDataState = importFromLocalStorage();
|
||||
|
@ -164,7 +324,7 @@ const initializeScene = async (opts: {
|
|||
} = await loadScene(null, null, localDataState);
|
||||
|
||||
let roomLinkData = getCollaborationLinkData(window.location.href);
|
||||
const isExternalScene = !!(id || jsonBackendMatch || roomLinkData);
|
||||
const isExternalScene = !!(id || shareableLink || roomLinkData);
|
||||
if (isExternalScene) {
|
||||
if (
|
||||
// don't prompt if scene is empty
|
||||
|
@ -174,16 +334,17 @@ const initializeScene = async (opts: {
|
|||
// otherwise, prompt whether user wants to override current scene
|
||||
(await openConfirmModal(shareableLinkConfirmDialog))
|
||||
) {
|
||||
if (jsonBackendMatch) {
|
||||
if (shareableLink) {
|
||||
scene = await loadScene(
|
||||
jsonBackendMatch[1],
|
||||
jsonBackendMatch[2],
|
||||
shareableLink[0],
|
||||
shareableLink[1],
|
||||
localDataState,
|
||||
);
|
||||
console.log(">>>>", scene);
|
||||
}
|
||||
scene.scrollToContent = true;
|
||||
if (!roomLinkData) {
|
||||
window.history.replaceState({}, APP_NAME, window.location.origin);
|
||||
// window.history.replaceState({}, APP_NAME, window.location.origin);
|
||||
}
|
||||
} else {
|
||||
// https://github.com/excalidraw/excalidraw/issues/1919
|
||||
|
@ -200,7 +361,7 @@ const initializeScene = async (opts: {
|
|||
}
|
||||
|
||||
roomLinkData = null;
|
||||
window.history.replaceState({}, APP_NAME, window.location.origin);
|
||||
// window.history.replaceState({}, APP_NAME, window.location.origin);
|
||||
}
|
||||
} else if (externalUrlMatch) {
|
||||
window.history.replaceState({}, APP_NAME, window.location.origin);
|
||||
|
@ -261,12 +422,12 @@ const initializeScene = async (opts: {
|
|||
key: roomLinkData.roomKey,
|
||||
};
|
||||
} else if (scene) {
|
||||
return isExternalScene && jsonBackendMatch
|
||||
return isExternalScene && shareableLink
|
||||
? {
|
||||
scene,
|
||||
isExternalScene,
|
||||
id: jsonBackendMatch[1],
|
||||
key: jsonBackendMatch[2],
|
||||
id: shareableLink[0],
|
||||
key: shareableLink[1],
|
||||
}
|
||||
: { scene, isExternalScene: false };
|
||||
}
|
||||
|
@ -672,6 +833,31 @@ const ExcalidrawWrapper = () => {
|
|||
[setShareDialogState],
|
||||
);
|
||||
|
||||
const [constraints] = useState<DebugScrollConstraints>(() => {
|
||||
const stored = new URLSearchParams(location.hash.slice(1)).get(
|
||||
"constraints",
|
||||
);
|
||||
let storedConstraints = {};
|
||||
if (stored) {
|
||||
try {
|
||||
storedConstraints = JSON.parse(window.atob(stored));
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: document.body.clientWidth,
|
||||
height: document.body.clientHeight,
|
||||
lockZoom: false,
|
||||
viewportZoomFactor: 0.7,
|
||||
enabled: true,
|
||||
...storedConstraints,
|
||||
};
|
||||
});
|
||||
|
||||
console.log(constraints);
|
||||
|
||||
// browsers generally prevent infinite self-embedding, there are
|
||||
// cases where it still happens, and while we disallow self-embedding
|
||||
// by not whitelisting our own origin, this serves as an additional guard
|
||||
|
@ -753,14 +939,14 @@ const ExcalidrawWrapper = () => {
|
|||
/>
|
||||
);
|
||||
}}
|
||||
scrollConstraints={{
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 2560,
|
||||
height: 1300,
|
||||
lockZoom: false,
|
||||
}}
|
||||
scrollConstraints={constraints.enabled ? constraints : undefined}
|
||||
>
|
||||
{excalidrawAPI && (
|
||||
<ConstraintsSettings
|
||||
excalidrawAPI={excalidrawAPI}
|
||||
initialConstraints={constraints}
|
||||
/>
|
||||
)}
|
||||
<AppMainMenu
|
||||
onCollabDialogOpen={onCollabDialogOpen}
|
||||
isCollaborating={isCollaborating}
|
||||
|
|
|
@ -77,7 +77,7 @@ const calculateZoomLevel = (
|
|||
width: AppState["width"],
|
||||
height: AppState["height"],
|
||||
) => {
|
||||
const DEFAULT_VIEWPORT_ZOOM_FACTOR = 0.7;
|
||||
const DEFAULT_VIEWPORT_ZOOM_FACTOR = 0.2;
|
||||
|
||||
const viewportZoomFactor = scrollConstraints.viewportZoomFactor
|
||||
? Math.min(1, Math.max(scrollConstraints.viewportZoomFactor, 0.1))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue