fix jumping/flashing when zooming in or out too quickly
This commit is contained in:
parent
bc6cc83b1e
commit
84c396aec2
@ -531,6 +531,7 @@ import type { Action, ActionResult } from "../actions/types";
|
||||
import {
|
||||
constrainScrollState,
|
||||
calculateConstrainedScrollCenter,
|
||||
areCanvasViewsClose,
|
||||
} from "../scene/scrollConstraints";
|
||||
|
||||
const AppContext = React.createContext<AppClassProperties>(null!);
|
||||
@ -2975,20 +2976,27 @@ class App extends React.Component<AppProps, AppState> {
|
||||
const newState = constrainScrollState(this.state, {
|
||||
allowOverscroll: false,
|
||||
});
|
||||
const fromValues = {
|
||||
scrollX: this.state.scrollX,
|
||||
scrollY: this.state.scrollY,
|
||||
zoom: this.state.zoom.value,
|
||||
};
|
||||
const toValues = {
|
||||
scrollX: newState.scrollX,
|
||||
scrollY: newState.scrollY,
|
||||
zoom: newState.zoom.value,
|
||||
};
|
||||
|
||||
if (areCanvasViewsClose(fromValues, toValues)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (scrollConstraintsAnimationTimeout) {
|
||||
clearTimeout(scrollConstraintsAnimationTimeout);
|
||||
}
|
||||
|
||||
scrollConstraintsAnimationTimeout = setTimeout(() => {
|
||||
this.cancelInProgressAnimation?.();
|
||||
const fromValues = {
|
||||
scrollX: this.state.scrollX,
|
||||
scrollY: this.state.scrollY,
|
||||
zoom: this.state.zoom.value,
|
||||
};
|
||||
const toValues = {
|
||||
scrollX: newState.scrollX,
|
||||
scrollY: newState.scrollY,
|
||||
zoom: newState.zoom.value,
|
||||
};
|
||||
|
||||
this.animateToConstrainedArea(fromValues, toValues);
|
||||
}, 200);
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { isShallowEqual } from "@excalidraw/common";
|
||||
import { AppState, ScrollConstraints } from "../types";
|
||||
import {
|
||||
AnimateTranslateCanvasValues,
|
||||
AppState,
|
||||
ScrollConstraints,
|
||||
} from "../types";
|
||||
import { getNormalizedZoom } from "./normalize";
|
||||
|
||||
/**
|
||||
@ -18,14 +22,13 @@ import { getNormalizedZoom } from "./normalize";
|
||||
*
|
||||
* const { scrollX, scrollY, zoom } = this.calculateConstrainedScrollCenter(scrollConstraints, { scrollX, scrollY });
|
||||
*/
|
||||
|
||||
type CanvasTranslate = Pick<AppState, "scrollX" | "scrollY" | "zoom">;
|
||||
|
||||
export const calculateConstrainedScrollCenter = (
|
||||
state: AppState,
|
||||
{ scrollX, scrollY }: Pick<AppState, "scrollX" | "scrollY">,
|
||||
): {
|
||||
scrollX: AppState["scrollX"];
|
||||
scrollY: AppState["scrollY"];
|
||||
zoom: AppState["zoom"];
|
||||
} => {
|
||||
): CanvasTranslate => {
|
||||
const {
|
||||
width,
|
||||
height,
|
||||
@ -352,7 +355,7 @@ const constrainScrollValues = ({
|
||||
maxScrollY: number;
|
||||
minScrollY: number;
|
||||
constrainedZoom: AppState["zoom"];
|
||||
}) => {
|
||||
}): CanvasTranslate => {
|
||||
const constrainedScrollX = Math.min(
|
||||
maxScrollX,
|
||||
Math.max(scrollX, minScrollX),
|
||||
@ -389,7 +392,7 @@ const alignScrollConstraints = (
|
||||
* Determines whether the current viewport is outside the constrained area defined in the AppState.
|
||||
*
|
||||
* @param state - The application state containing scroll, zoom, and constraint information.
|
||||
* @returns True if the viewport is outside the constrained area; otherwise undefined.
|
||||
* @returns True if the viewport is outside the constrained area, false otherwise.
|
||||
*/
|
||||
const isViewportOutsideOfConstrainedArea = (state: AppState) => {
|
||||
if (!state.scrollConstraints) {
|
||||
@ -521,3 +524,15 @@ export const constrainScrollState = (
|
||||
...constrainedValues,
|
||||
};
|
||||
};
|
||||
|
||||
export const areCanvasViewsClose = (
|
||||
from: AnimateTranslateCanvasValues,
|
||||
to: AnimateTranslateCanvasValues,
|
||||
): boolean => {
|
||||
const threshold = 0.1; // Adjust based on your needs
|
||||
return (
|
||||
Math.abs(from.scrollX - to.scrollX) < threshold &&
|
||||
Math.abs(from.scrollY - to.scrollY) < threshold &&
|
||||
Math.abs(from.zoom - to.zoom) < threshold
|
||||
);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user