mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
feat: animate the scroll to constrained area
This commit is contained in:
parent
7336b1c276
commit
c0bd9027cb
2 changed files with 51 additions and 4 deletions
|
@ -7657,6 +7657,10 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
// Set the overscroll allowance percentage
|
// Set the overscroll allowance percentage
|
||||||
const OVERSCROLL_ALLOWANCE_PERCENTAGE = 0.2;
|
const OVERSCROLL_ALLOWANCE_PERCENTAGE = 0.2;
|
||||||
|
|
||||||
|
if (!scrollConstraints || scrollConstraints.isAnimating) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the state has changed since the last render
|
// Check if the state has changed since the last render
|
||||||
const stateUnchanged =
|
const stateUnchanged =
|
||||||
zoom.value === prevState.zoom.value &&
|
zoom.value === prevState.zoom.value &&
|
||||||
|
@ -7671,11 +7675,11 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the maximum possible zoom based on the viewport and scrollable area sizes
|
// Calculate the zoom level on which will constrained area fit the viewport for each axis
|
||||||
const scrollableWidth = scrollConstraints.width;
|
const scrollableWidth = scrollConstraints.width;
|
||||||
const scrollableHeight = scrollConstraints.height;
|
const scrollableHeight = scrollConstraints.height;
|
||||||
const maxZoomX = width / scrollableWidth;
|
const zoomLevelX = width / scrollableWidth;
|
||||||
const maxZoomY = height / scrollableHeight;
|
const zoomLevelY = height / scrollableHeight;
|
||||||
|
|
||||||
// Default scroll and zoom values
|
// Default scroll and zoom values
|
||||||
let constrainedScrollX = scrollX;
|
let constrainedScrollX = scrollX;
|
||||||
|
@ -7689,7 +7693,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
|
|
||||||
// When we are zoomed out enough to contain constrained area in the viewport we will center the view
|
// When we are zoomed out enough to contain constrained area in the viewport we will center the view
|
||||||
const shouldAdjustForCenteredView =
|
const shouldAdjustForCenteredView =
|
||||||
zoom.value <= maxZoomX || zoom.value <= maxZoomY;
|
zoom.value <= zoomLevelX || zoom.value <= zoomLevelY;
|
||||||
|
|
||||||
// When viewport is smaller than the scrollable area, user can pan freely within the constrained area,
|
// When viewport is smaller than the scrollable area, user can pan freely within the constrained area,
|
||||||
// otherwilse the viewport is centered to the center of the scrollable area
|
// otherwilse the viewport is centered to the center of the scrollable area
|
||||||
|
@ -7767,6 +7771,48 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
constrainedScrollX !== scrollX || constrainedScrollY !== scrollY;
|
constrainedScrollX !== scrollX || constrainedScrollY !== scrollY;
|
||||||
|
|
||||||
if (isStateChanged) {
|
if (isStateChanged) {
|
||||||
|
// Animate the scroll position when the cursor button is not down and scroll position is outside of the scroll constraints
|
||||||
|
if (
|
||||||
|
(scrollX < scrollConstraints.x ||
|
||||||
|
scrollX + width > scrollConstraints.x + scrollConstraints.width ||
|
||||||
|
scrollY < scrollConstraints.y ||
|
||||||
|
scrollY + height > scrollConstraints.y + scrollConstraints.height) &&
|
||||||
|
cursorButton !== "down" &&
|
||||||
|
!scrollConstraints.isAnimating
|
||||||
|
) {
|
||||||
|
this.setState({
|
||||||
|
scrollConstraints: { ...scrollConstraints, isAnimating: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
easeToValuesRAF({
|
||||||
|
fromValues: { scrollX, scrollY },
|
||||||
|
toValues: {
|
||||||
|
scrollX: constrainedScrollX,
|
||||||
|
scrollY: constrainedScrollY,
|
||||||
|
},
|
||||||
|
onStep: ({ scrollX, scrollY }) => {
|
||||||
|
console.log("onStep");
|
||||||
|
this.setState({
|
||||||
|
scrollX,
|
||||||
|
scrollY,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onStart: () => {
|
||||||
|
this.setState({
|
||||||
|
scrollConstraints: { ...scrollConstraints, isAnimating: true },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onEnd: () => {
|
||||||
|
this.setState({
|
||||||
|
scrollConstraints: { ...scrollConstraints, isAnimating: false },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("isAnimating");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const constrainedState = {
|
const constrainedState = {
|
||||||
scrollX: constrainedScrollX,
|
scrollX: constrainedScrollX,
|
||||||
scrollY: constrainedScrollY,
|
scrollY: constrainedScrollY,
|
||||||
|
|
|
@ -228,6 +228,7 @@ export type AppState = {
|
||||||
y: number;
|
y: number;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
isAnimating?: boolean;
|
||||||
} | null;
|
} | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue