feat: Animation support (#10042)
This commit is contained in:
@@ -1813,6 +1813,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
/>
|
||||
)}
|
||||
<InteractiveCanvas
|
||||
app={this}
|
||||
containerRef={this.excalidrawContainerRef}
|
||||
canvas={this.interactiveCanvas}
|
||||
elementsMap={elementsMap}
|
||||
|
||||
@@ -6,6 +6,15 @@ import {
|
||||
sceneCoordsToViewportCoords,
|
||||
type EditorInterface,
|
||||
} from "@excalidraw/common";
|
||||
import { AnimationController } from "@excalidraw/excalidraw/renderer/animation";
|
||||
|
||||
import type {
|
||||
InteractiveCanvasRenderConfig,
|
||||
InteractiveSceneRenderAnimationState,
|
||||
InteractiveSceneRenderConfig,
|
||||
RenderableElementsMap,
|
||||
RenderInteractiveSceneCallback,
|
||||
} from "@excalidraw/excalidraw/scene/types";
|
||||
|
||||
import type {
|
||||
NonDeletedExcalidrawElement,
|
||||
@@ -13,15 +22,13 @@ import type {
|
||||
} from "@excalidraw/element/types";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
import { isRenderThrottlingEnabled } from "../../reactUtils";
|
||||
import { renderInteractiveScene } from "../../renderer/interactiveScene";
|
||||
|
||||
import type {
|
||||
InteractiveCanvasRenderConfig,
|
||||
RenderableElementsMap,
|
||||
RenderInteractiveSceneCallback,
|
||||
} from "../../scene/types";
|
||||
import type { AppState, InteractiveCanvasAppState } from "../../types";
|
||||
AppClassProperties,
|
||||
AppState,
|
||||
InteractiveCanvasAppState,
|
||||
} from "../../types";
|
||||
import type { DOMAttributes } from "react";
|
||||
|
||||
type InteractiveCanvasProps = {
|
||||
@@ -37,6 +44,7 @@ type InteractiveCanvasProps = {
|
||||
appState: InteractiveCanvasAppState;
|
||||
renderScrollbars: boolean;
|
||||
editorInterface: EditorInterface;
|
||||
app: AppClassProperties;
|
||||
renderInteractiveSceneCallback: (
|
||||
data: RenderInteractiveSceneCallback,
|
||||
) => void;
|
||||
@@ -71,8 +79,11 @@ type InteractiveCanvasProps = {
|
||||
>;
|
||||
};
|
||||
|
||||
export const INTERACTIVE_SCENE_ANIMATION_KEY = "animateInteractiveScene";
|
||||
|
||||
const InteractiveCanvas = (props: InteractiveCanvasProps) => {
|
||||
const isComponentMounted = useRef(false);
|
||||
const rendererParams = useRef(null as InteractiveSceneRenderConfig | null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isComponentMounted.current) {
|
||||
@@ -129,29 +140,58 @@ const InteractiveCanvas = (props: InteractiveCanvasProps) => {
|
||||
)) ||
|
||||
"#6965db";
|
||||
|
||||
renderInteractiveScene(
|
||||
{
|
||||
canvas: props.canvas,
|
||||
elementsMap: props.elementsMap,
|
||||
visibleElements: props.visibleElements,
|
||||
selectedElements: props.selectedElements,
|
||||
allElementsMap: props.allElementsMap,
|
||||
scale: window.devicePixelRatio,
|
||||
appState: props.appState,
|
||||
renderConfig: {
|
||||
remotePointerViewportCoords,
|
||||
remotePointerButton,
|
||||
remoteSelectedElementIds,
|
||||
remotePointerUsernames,
|
||||
remotePointerUserStates,
|
||||
selectionColor,
|
||||
renderScrollbars: props.renderScrollbars,
|
||||
},
|
||||
editorInterface: props.editorInterface,
|
||||
callback: props.renderInteractiveSceneCallback,
|
||||
rendererParams.current = {
|
||||
app: props.app,
|
||||
canvas: props.canvas,
|
||||
elementsMap: props.elementsMap,
|
||||
visibleElements: props.visibleElements,
|
||||
selectedElements: props.selectedElements,
|
||||
allElementsMap: props.allElementsMap,
|
||||
scale: window.devicePixelRatio,
|
||||
appState: props.appState,
|
||||
renderConfig: {
|
||||
remotePointerViewportCoords,
|
||||
remotePointerButton,
|
||||
remoteSelectedElementIds,
|
||||
remotePointerUsernames,
|
||||
remotePointerUserStates,
|
||||
selectionColor,
|
||||
renderScrollbars: props.renderScrollbars,
|
||||
},
|
||||
isRenderThrottlingEnabled(),
|
||||
);
|
||||
editorInterface: props.editorInterface,
|
||||
callback: props.renderInteractiveSceneCallback,
|
||||
animationState: {
|
||||
bindingHighlight: undefined,
|
||||
},
|
||||
deltaTime: 0,
|
||||
};
|
||||
|
||||
if (!AnimationController.running(INTERACTIVE_SCENE_ANIMATION_KEY)) {
|
||||
AnimationController.start<InteractiveSceneRenderAnimationState>(
|
||||
INTERACTIVE_SCENE_ANIMATION_KEY,
|
||||
({ deltaTime, state }) => {
|
||||
const nextAnimationState = renderInteractiveScene({
|
||||
...rendererParams.current!,
|
||||
deltaTime,
|
||||
animationState: state,
|
||||
}).animationState;
|
||||
|
||||
if (nextAnimationState) {
|
||||
for (const key in nextAnimationState) {
|
||||
if (
|
||||
nextAnimationState[
|
||||
key as keyof InteractiveSceneRenderAnimationState
|
||||
] !== undefined
|
||||
) {
|
||||
return nextAnimationState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user