mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: Calculate width/height
of canvas based on container dimensions (".excalidraw" selector) & remove props width & height (#3379)
* Remove width/height from the ".excalidraw" container so it will sized automatically. * updated all ref calculation to ".excalidraw" instead of parent since now ".excalidraw" will get resized * Remove props width/height as its not needed anymore. * Resize handler is also not needed anymore. * Position absolute canvas due to #3379 (comment) * move css to style and remove one extra rerendering * factor out mock logic for test * set height, width so as to avoid unnecessary updates of regression snap * better mock * better type checking and omit width,height from getDefaultAppState and also restore * revert * default to window dimensions in constructor * update docs * update * update * tweaks
This commit is contained in:
parent
3b976613ba
commit
c54a099010
24 changed files with 243 additions and 258 deletions
|
@ -293,19 +293,12 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
actionManager: ActionManager;
|
||||
private excalidrawContainerRef = React.createRef<HTMLDivElement>();
|
||||
|
||||
public static defaultProps: Partial<ExcalidrawProps> = {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
};
|
||||
private scene: Scene;
|
||||
private resizeObserver: ResizeObserver | undefined;
|
||||
constructor(props: ExcalidrawProps) {
|
||||
super(props);
|
||||
const defaultAppState = getDefaultAppState();
|
||||
|
||||
const {
|
||||
width = window.innerWidth,
|
||||
height = window.innerHeight,
|
||||
excalidrawRef,
|
||||
viewModeEnabled = false,
|
||||
zenModeEnabled = false,
|
||||
|
@ -317,13 +310,13 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
...defaultAppState,
|
||||
theme,
|
||||
isLoading: true,
|
||||
width,
|
||||
height,
|
||||
...this.getCanvasOffsets(),
|
||||
viewModeEnabled,
|
||||
zenModeEnabled,
|
||||
gridSize: gridModeEnabled ? GRID_SIZE : null,
|
||||
name,
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
};
|
||||
if (excalidrawRef) {
|
||||
const readyPromise =
|
||||
|
@ -447,10 +440,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
"excalidraw--view-mode": viewModeEnabled,
|
||||
})}
|
||||
ref={this.excalidrawContainerRef}
|
||||
style={{
|
||||
width: canvasDOMWidth,
|
||||
height: canvasDOMHeight,
|
||||
}}
|
||||
>
|
||||
<LayerUI
|
||||
canvas={this.canvas}
|
||||
|
@ -561,7 +550,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
if (typeof this.props.name !== "undefined") {
|
||||
name = this.props.name;
|
||||
}
|
||||
|
||||
this.setState(
|
||||
(state) => {
|
||||
// using Object.assign instead of spread to fool TS 4.2.2+ into
|
||||
|
@ -570,10 +558,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
return Object.assign(actionResult.appState || {}, {
|
||||
editingElement:
|
||||
editingElement || actionResult.appState?.editingElement || null,
|
||||
width: state.width,
|
||||
height: state.height,
|
||||
offsetTop: state.offsetTop,
|
||||
offsetLeft: state.offsetLeft,
|
||||
viewModeEnabled,
|
||||
zenModeEnabled,
|
||||
gridSize,
|
||||
|
@ -706,7 +690,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
if (!this.state.isLoading) {
|
||||
this.setState({ isLoading: true });
|
||||
}
|
||||
|
||||
let initialData = null;
|
||||
try {
|
||||
initialData = (await this.props.initialData) || null;
|
||||
|
@ -715,7 +698,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
}
|
||||
|
||||
const scene = restore(initialData, null);
|
||||
|
||||
scene.appState = {
|
||||
...scene.appState,
|
||||
isLoading: false,
|
||||
|
@ -787,14 +769,11 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
this.scene.addCallback(this.onSceneUpdated);
|
||||
this.addEventListeners();
|
||||
|
||||
if (
|
||||
"ResizeObserver" in window &&
|
||||
this.excalidrawContainerRef?.current?.parentElement
|
||||
) {
|
||||
this.resizeObserver = new ResizeObserver(() => this.setCanvasOffsets());
|
||||
this.resizeObserver?.observe(
|
||||
this.excalidrawContainerRef.current.parentElement,
|
||||
);
|
||||
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
|
||||
this.resizeObserver = new ResizeObserver(() => {
|
||||
this.updateDOMRect();
|
||||
});
|
||||
this.resizeObserver?.observe(this.excalidrawContainerRef.current);
|
||||
}
|
||||
const searchParams = new URLSearchParams(window.location.search.slice(1));
|
||||
|
||||
|
@ -802,9 +781,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
// Obtain a file that was shared via the Web Share Target API.
|
||||
this.restoreFileFromShare();
|
||||
} else {
|
||||
this.setState(this.getCanvasOffsets(), () => {
|
||||
this.initializeScene();
|
||||
});
|
||||
this.updateDOMRect(this.initializeScene);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -906,17 +883,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
this.updateLanguage();
|
||||
}
|
||||
|
||||
if (
|
||||
prevProps.width !== this.props.width ||
|
||||
prevProps.height !== this.props.height
|
||||
) {
|
||||
this.setState({
|
||||
width: this.props.width ?? window.innerWidth,
|
||||
height: this.props.height ?? window.innerHeight,
|
||||
...this.getCanvasOffsets(),
|
||||
});
|
||||
}
|
||||
|
||||
if (prevProps.viewModeEnabled !== this.props.viewModeEnabled) {
|
||||
this.setState(
|
||||
{ viewModeEnabled: !!this.props.viewModeEnabled },
|
||||
|
@ -4093,14 +4059,56 @@ class App extends React.Component<ExcalidrawProps, AppState> {
|
|||
}
|
||||
}, 300);
|
||||
|
||||
private updateDOMRect = (cb?: () => void) => {
|
||||
if (this.excalidrawContainerRef?.current) {
|
||||
const excalidrawContainer = this.excalidrawContainerRef.current;
|
||||
const {
|
||||
width,
|
||||
height,
|
||||
left: offsetLeft,
|
||||
top: offsetTop,
|
||||
} = excalidrawContainer.getBoundingClientRect();
|
||||
const {
|
||||
width: currentWidth,
|
||||
height: currentHeight,
|
||||
offsetTop: currentOffsetTop,
|
||||
offsetLeft: currentOffsetLeft,
|
||||
} = this.state;
|
||||
|
||||
if (
|
||||
width === currentWidth &&
|
||||
height === currentHeight &&
|
||||
offsetLeft === currentOffsetLeft &&
|
||||
offsetTop === currentOffsetTop
|
||||
) {
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState(
|
||||
{
|
||||
width,
|
||||
height,
|
||||
offsetLeft,
|
||||
offsetTop,
|
||||
},
|
||||
() => {
|
||||
cb && cb();
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
public setCanvasOffsets = () => {
|
||||
this.setState({ ...this.getCanvasOffsets() });
|
||||
};
|
||||
|
||||
private getCanvasOffsets(): Pick<AppState, "offsetTop" | "offsetLeft"> {
|
||||
if (this.excalidrawContainerRef?.current?.parentElement) {
|
||||
const parentElement = this.excalidrawContainerRef.current.parentElement;
|
||||
const { left, top } = parentElement.getBoundingClientRect();
|
||||
if (this.excalidrawContainerRef?.current) {
|
||||
const excalidrawContainer = this.excalidrawContainerRef.current;
|
||||
const { left, top } = excalidrawContainer.getBoundingClientRect();
|
||||
return {
|
||||
offsetLeft: left,
|
||||
offsetTop: top,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue