mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: use single function for animating canvas translation
This commit is contained in:
parent
edf54d1543
commit
ddb08ce732
2 changed files with 91 additions and 82 deletions
|
@ -228,6 +228,7 @@ import {
|
|||
SidebarName,
|
||||
SidebarTabName,
|
||||
ScrollConstraints,
|
||||
AnimateTranslateCanvasValues,
|
||||
} from "../types";
|
||||
import {
|
||||
debounce,
|
||||
|
@ -2627,28 +2628,18 @@ class App extends React.Component<AppProps, AppState> {
|
|||
const origScrollY = this.state.scrollY;
|
||||
const origZoom = this.state.zoom.value;
|
||||
|
||||
const cancel = easeToValuesRAF({
|
||||
fromValues: {
|
||||
scrollX: origScrollX,
|
||||
scrollY: origScrollY,
|
||||
zoom: origZoom,
|
||||
},
|
||||
toValues: { scrollX, scrollY, zoom: zoom.value },
|
||||
interpolateValue: (from, to, progress, key) => {
|
||||
// for zoom, use different easing
|
||||
if (key === "zoom") {
|
||||
return from * Math.pow(to / from, easeOut(progress));
|
||||
}
|
||||
// handle using default
|
||||
return undefined;
|
||||
},
|
||||
onStep: ({ scrollX, scrollY, zoom }) => {
|
||||
this.setState({
|
||||
scrollX,
|
||||
scrollY,
|
||||
zoom: { value: zoom },
|
||||
});
|
||||
},
|
||||
const fromValues = {
|
||||
scrollX: this.state.scrollX,
|
||||
scrollY: this.state.scrollY,
|
||||
zoom: this.state.zoom.value,
|
||||
};
|
||||
|
||||
const toValues = { scrollX, scrollY, zoom: zoom.value };
|
||||
|
||||
this.animateTranslateCanvas({
|
||||
fromValues,
|
||||
toValues,
|
||||
duration: opts?.duration ?? 500,
|
||||
onStart: () => {
|
||||
this.setState({ shouldCacheIgnoreZoom: true });
|
||||
},
|
||||
|
@ -2658,13 +2649,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||
onCancel: () => {
|
||||
this.setState({ shouldCacheIgnoreZoom: false });
|
||||
},
|
||||
duration: opts?.duration ?? 500,
|
||||
});
|
||||
|
||||
this.cancelInProgresAnimation = () => {
|
||||
cancel();
|
||||
this.cancelInProgresAnimation = null;
|
||||
};
|
||||
} else {
|
||||
this.setState({ scrollX, scrollY, zoom });
|
||||
}
|
||||
|
@ -2707,17 +2692,65 @@ class App extends React.Component<AppProps, AppState> {
|
|||
this.setState(state, () => {
|
||||
if (shouldAnimate && animateTo) {
|
||||
scrollConstraintsAnimationTimeout = setTimeout(() => {
|
||||
const cancel = easeToValuesRAF({
|
||||
fromValues: {
|
||||
const fromValues = {
|
||||
scrollX: newState.scrollX,
|
||||
scrollY: newState.scrollY,
|
||||
zoom: newState.zoom.value,
|
||||
},
|
||||
toValues: {
|
||||
};
|
||||
const toValues = {
|
||||
scrollX: animateTo.scrollX,
|
||||
scrollY: animateTo.scrollY,
|
||||
zoom: animateTo.zoom.value,
|
||||
};
|
||||
const cleanUp = () => {
|
||||
this.setState((inAnimationState) => ({
|
||||
shouldCacheIgnoreZoom: false,
|
||||
scrollConstraints: {
|
||||
...inAnimationState.scrollConstraints!,
|
||||
isAnimating: false,
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
this.animateTranslateCanvas({
|
||||
fromValues,
|
||||
toValues,
|
||||
duration: 200,
|
||||
onStart: () => {
|
||||
this.setState((inAnimationState) => ({
|
||||
shouldCacheIgnoreZoom: true,
|
||||
scrollConstraints: {
|
||||
...inAnimationState.scrollConstraints!,
|
||||
isAnimating: true,
|
||||
},
|
||||
}));
|
||||
},
|
||||
onEnd: cleanUp,
|
||||
onCancel: cleanUp,
|
||||
});
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
animateTranslateCanvas = ({
|
||||
fromValues,
|
||||
toValues,
|
||||
duration,
|
||||
onStart,
|
||||
onEnd,
|
||||
onCancel,
|
||||
}: {
|
||||
fromValues: AnimateTranslateCanvasValues;
|
||||
toValues: AnimateTranslateCanvasValues;
|
||||
duration: number;
|
||||
onStart: () => void;
|
||||
onEnd: () => void;
|
||||
onCancel: () => void;
|
||||
}) => {
|
||||
const cancel = easeToValuesRAF({
|
||||
fromValues,
|
||||
toValues,
|
||||
interpolateValue: (from, to, progress, key) => {
|
||||
// for zoom, use different easing
|
||||
if (key === "zoom") {
|
||||
|
@ -2730,49 +2763,19 @@ class App extends React.Component<AppProps, AppState> {
|
|||
this.setState({
|
||||
scrollX,
|
||||
scrollY,
|
||||
zoom: { value: getNormalizedZoom(zoom) },
|
||||
zoom: { value: zoom },
|
||||
});
|
||||
},
|
||||
onStart: () => {
|
||||
this.setState((inAnimationState) => ({
|
||||
shouldCacheIgnoreZoom: true,
|
||||
scrollConstraints: {
|
||||
...inAnimationState.scrollConstraints!, // existance scrollConstraints is checked in test for shouldAnimate
|
||||
isAnimating: true,
|
||||
},
|
||||
}));
|
||||
cancelRender();
|
||||
},
|
||||
onEnd: () => {
|
||||
this.setState((inAnimationState) => ({
|
||||
shouldCacheIgnoreZoom: false,
|
||||
scrollConstraints: {
|
||||
...inAnimationState.scrollConstraints!,
|
||||
isAnimating: false,
|
||||
},
|
||||
}));
|
||||
},
|
||||
onCancel: () => {
|
||||
this.setState((inAnimationState) => {
|
||||
return {
|
||||
shouldCacheIgnoreZoom: false,
|
||||
scrollConstraints: {
|
||||
...inAnimationState.scrollConstraints!,
|
||||
isAnimating: false,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
duration: 200,
|
||||
onStart,
|
||||
onEnd,
|
||||
onCancel,
|
||||
duration,
|
||||
});
|
||||
|
||||
this.cancelInProgresAnimation = () => {
|
||||
cancel();
|
||||
this.cancelInProgresAnimation = null;
|
||||
};
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
setToast = (
|
||||
|
|
|
@ -665,3 +665,9 @@ export type ScrollConstraints = {
|
|||
viewportZoomFactor?: number;
|
||||
lockZoom?: boolean;
|
||||
};
|
||||
|
||||
export type AnimateTranslateCanvasValues = {
|
||||
scrollX: AppState["scrollX"];
|
||||
scrollY: AppState["scrollY"];
|
||||
zoom: AppState["zoom"]["value"];
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue