Compare commits

...

8 Commits

Author SHA1 Message Date
Aakansha Doshi
e9d5b41fbf
tweaks
Co-authored-by: David Luzar <luzar.david@gmail.com>
2021-04-11 19:01:38 +05:30
Aakansha Doshi
ef5614b697
Update src/packages/excalidraw/CHANGELOG.md 2021-04-11 14:26:50 +05:30
Aakansha Doshi
cd5d9111e9
tweak docs 2021-04-11 14:20:24 +05:30
Aakansha Doshi
8467093e83 update 2021-04-11 14:16:00 +05:30
Aakansha Doshi
504ea987b0 update docs 2021-04-11 14:08:50 +05:30
Aakansha Doshi
ac08f433e9 update prop name to detectPosition 2021-04-11 13:49:40 +05:30
Aakansha Doshi
4fb906baad disable detectPositionChange by default 2021-04-11 01:40:46 +05:30
Aakansha Doshi
bfc8415554 feat: poll to detect if position of excalidraw was updated and allow consumer to disable it 2021-04-10 03:09:56 +05:30
6 changed files with 40 additions and 6 deletions

View File

@ -46,6 +46,7 @@ import {
CURSOR_TYPE,
DEFAULT_UI_OPTIONS,
DEFAULT_VERTICAL_ALIGN,
DETECT_POSITION_CHANGE_INTERVAL,
DRAGGING_THRESHOLD,
ELEMENT_SHIFT_TRANSLATE_AMOUNT,
ELEMENT_TRANSLATE_AMOUNT,
@ -305,6 +306,8 @@ class App extends React.Component<AppProps, AppState> {
private scene: Scene;
private resizeObserver: ResizeObserver | undefined;
private nearestScrollableContainer: HTMLElement | Document | undefined;
private detectPositionIntervalId: NodeJS.Timeout | undefined;
constructor(props: AppProps) {
super(props);
const defaultAppState = getDefaultAppState();
@ -788,6 +791,13 @@ class App extends React.Component<AppProps, AppState> {
this.scene.addCallback(this.onSceneUpdated);
this.addEventListeners();
if (this.props.detectPosition) {
this.detectPositionIntervalId = setInterval(
this.updateOffsetsIfChanged,
DETECT_POSITION_CHANGE_INTERVAL,
);
}
if ("ResizeObserver" in window && this.excalidrawContainerRef?.current) {
this.resizeObserver = new ResizeObserver(() => {
// compute isMobile state
@ -829,6 +839,9 @@ class App extends React.Component<AppProps, AppState> {
this.removeEventListeners();
this.scene.destroy();
clearTimeout(touchTimeout);
if (this.detectPositionIntervalId) {
clearInterval(this.detectPositionIntervalId);
}
touchTimeout = 0;
}
@ -1091,7 +1104,7 @@ class App extends React.Component<AppProps, AppState> {
}
}
private onScroll = debounce(() => {
private updateOffsetsIfChanged = () => {
const { offsetTop, offsetLeft } = this.getCanvasOffsets();
this.setState((state) => {
if (state.offsetLeft === offsetLeft && state.offsetTop === offsetTop) {
@ -1099,7 +1112,9 @@ class App extends React.Component<AppProps, AppState> {
}
return { offsetTop, offsetLeft };
});
}, SCROLL_TIMEOUT);
};
private onScroll = debounce(this.updateOffsetsIfChanged, SCROLL_TIMEOUT);
// Copy/paste

View File

@ -102,6 +102,7 @@ export const TITLE_TIMEOUT = 10000;
export const TOAST_TIMEOUT = 5000;
export const VERSION_TIMEOUT = 30000;
export const SCROLL_TIMEOUT = 100;
export const DETECT_POSITION_CHANGE_INTERVAL = 500;
export const ZOOM_STEP = 0.1;
// Report a user inactive after IDLE_THRESHOLD milliseconds

View File

@ -15,6 +15,7 @@ Please add the latest change on the top under the correct section.
## Excalidraw API
- Support detecting position of the component and recompute offsets when the position changes [#3428](https://github.com/excalidraw/excalidraw/pull/3428). Disabled by default. You can enable this by setting [`detectPosition`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#detectPosition) to `true`.
- Recompute offsets on `scroll` of the nearest scrollable container [#3408](https://github.com/excalidraw/excalidraw/pull/3408). This can be disabled by setting [`detectScroll`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#detectScroll) to `false`.
- Add `onPaste` prop to handle custom clipboard behaviours [#3420](https://github.com/excalidraw/excalidraw/pull/3420).

View File

@ -365,7 +365,8 @@ To view the full example visit :point_down:
| [`name`](#name) | string | | Name of the drawing |
| [`UIOptions`](#UIOptions) | <pre>{ canvasActions: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L208"> CanvasActions<a/> }</pre> | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L129) | To customise UI options. Currently we support customising [`canvas actions`](#canvasActions) |
| [`onPaste`](#onPaste) | <pre>(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L17">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean</pre> | | Callback to be triggered if passed when the something is pasted in to the scene |
| [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. |
| [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to recompute the offsets when nearest ancestor is scrolled. |
| [`detectPosition`](#detectPosition) | boolean | false | Indicates whether to recompute the offsets when position of the Excalidraw component is updated. |
### Dimensions of Excalidraw
@ -441,8 +442,8 @@ You can pass a `ref` when you want to access some excalidraw APIs. We expose the
| getAppState | <pre> () => <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L37">AppState</a></pre> | Returns current appState |
| history | `{ clear: () => void }` | This is the history API. `history.clear()` will clear the history |
| setScrollToContent | <pre> (<a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>) => void </pre> | Scroll to the nearest element to center |
| refresh | `() => void` | Updates the offsets for the Excalidraw component so that the coordinates are computed correctly (for example the cursor position). You don't have to call this when the position is changed on page scroll or when the excalidraw container resizes (we handle that ourselves). For any other cases if the position of excalidraw is updated (example due to scroll on parent container and not page scroll) you should call this API. |
| [importLibrary](#importlibrary) | `(url: string, token?: string) => void` | Imports library from given URL |
| [`refresh`](#refresh) | `() => void` | Recomputes the offsets for the Excalidraw component. |
| [`importLibrary`](#importlibrary) | `(url: string, token?: string) => void` | Imports library from given URL. |
| setToastMessage | `(message: string) => void` | This API can be used to show the toast with custom message. |
#### `readyPromise`
@ -566,6 +567,10 @@ In case you want to prevent the excalidraw paste action you must return `true`,
No Excalidraw package doesn't come with collaboration, since this would have different implementations on the consumer so we expose the API's which you can use to communicate with Excalidraw as mentioned above. If you are interested in understanding how Excalidraw does it you can check it [here](https://github.com/excalidraw/excalidraw/blob/master/src/excalidraw-app/index.tsx).
### refresh
Recomputes the offsets for the Excalidraw component so that the coordinates are computed correctly (for example the cursor position). You don't have to call this when the position is changed due to scrolling on the nearest scrollable parent or when the excalidraw container resizes (we handle that ourselves). For any other cases if the position of excalidraw is updated (for example due to multiple scrolls or add / removal of elements in flex container) you can enable [`detectPosition`](#detectposition) or handle it manually by calling this API.
### importLibrary
Imports library from given URL. You should call this on `hashchange`, passing the `addLibrary` value if you detect it as shown below. Optionally pass a CSRF `token` to skip prompting during installation (retrievable via `token` key from the url coming from [https://libraries.excalidraw.com](https://libraries.excalidraw.com/)).
@ -590,7 +595,15 @@ Try out the [Demo](#Demo) to see it in action.
### detectScroll
Indicates whether Excalidraw should listen for `scroll` event on the nearest scrollable container in the DOM tree and recompute the coordinates (e.g. to correctly handle the cursor) when the component's position changes. You can disable this when you either know this doesn't affect your app or you want to take care of it yourself (calling the [`refresh()`](#ref) method).
Indicates whether Excalidraw should listen for `scroll` event on the nearest scrollable container in the DOM tree and recompute the coordinates (e.g. to correctly handle the cursor) when the component's position changes. You can disable this when you either know this doesn't affect your app or you want to take care of it yourself (calling the [`refresh()`](#refresh) method).
### detectPosition
Indicates whether the coordinates should be recomputed (e.g. to correctly handle the cursor) when the component's position changes. This is disabled by default.
Resizing and handling nearest scrollable parent ([detectScroll](#detectScroll)) is already handled so if there is any other case where position gets updated is where you will want to enable this prop (eg multiple scroll containers, or position updating due to addition/removal of elements in flex container).
You might want to disable [detectScroll](#detectScroll) when you enable this prop.
### Extra API's

View File

@ -31,6 +31,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
renderCustomStats,
onPaste,
detectScroll = true,
detectPosition = false,
} = props;
const canvasActions = props.UIOptions?.canvasActions;
@ -82,6 +83,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
UIOptions={UIOptions}
onPaste={onPaste}
detectScroll={detectScroll}
detectPosition={detectPosition}
/>
</InitializeApp>
);

View File

@ -196,6 +196,7 @@ export interface ExcalidrawProps {
) => JSX.Element;
UIOptions?: UIOptions;
detectScroll?: boolean;
detectPosition?: boolean;
}
export type SceneData = {
@ -230,4 +231,5 @@ export type AppProps = ExcalidrawProps & {
canvasActions: Required<CanvasActions>;
};
detectScroll: boolean;
detectPosition: boolean;
};