fix: drag handle scrolling fixed (#5619)
* fix: drag handle scrolling fixed * fix: closest scrollable parent found and scrolled * fix: removed overflow auto from framerenderer * fix: make dragging dynamic and smoother
This commit is contained in:
parent
328b6961a2
commit
5fb7e98b7c
2 changed files with 39 additions and 7 deletions
|
|
@ -42,7 +42,7 @@ export const SideMenuExtension = (props: Props) => {
|
||||||
ai: aiEnabled,
|
ai: aiEnabled,
|
||||||
dragDrop: dragDropEnabled,
|
dragDrop: dragDropEnabled,
|
||||||
},
|
},
|
||||||
scrollThreshold: { up: 300, down: 100 },
|
scrollThreshold: { up: 200, down: 100 },
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -233,14 +233,46 @@ export const DragHandlePlugin = (options: SideMenuPluginProps): SideMenuHandleOp
|
||||||
dragHandleElement.addEventListener("click", (e) => handleClick(e, view));
|
dragHandleElement.addEventListener("click", (e) => handleClick(e, view));
|
||||||
dragHandleElement.addEventListener("contextmenu", (e) => handleClick(e, view));
|
dragHandleElement.addEventListener("contextmenu", (e) => handleClick(e, view));
|
||||||
|
|
||||||
|
const isScrollable = (node: HTMLElement | SVGElement) => {
|
||||||
|
if (!(node instanceof HTMLElement || node instanceof SVGElement)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const style = getComputedStyle(node);
|
||||||
|
return ["overflow", "overflow-y"].some((propertyName) => {
|
||||||
|
const value = style.getPropertyValue(propertyName);
|
||||||
|
return value === "auto" || value === "scroll";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getScrollParent = (node: HTMLElement | SVGElement) => {
|
||||||
|
let currentParent = node.parentElement;
|
||||||
|
while (currentParent) {
|
||||||
|
if (isScrollable(currentParent)) {
|
||||||
|
return currentParent;
|
||||||
|
}
|
||||||
|
currentParent = currentParent.parentElement;
|
||||||
|
}
|
||||||
|
return document.scrollingElement || document.documentElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
const maxScrollSpeed = 100;
|
||||||
|
|
||||||
dragHandleElement.addEventListener("drag", (e) => {
|
dragHandleElement.addEventListener("drag", (e) => {
|
||||||
hideDragHandle();
|
hideDragHandle();
|
||||||
const frameRenderer = document.querySelector(".frame-renderer");
|
const scrollableParent = getScrollParent(dragHandleElement);
|
||||||
if (!frameRenderer) return;
|
if (!scrollableParent) return;
|
||||||
if (e.clientY < options.scrollThreshold.up) {
|
const scrollThreshold = options.scrollThreshold;
|
||||||
frameRenderer.scrollBy({ top: -70, behavior: "smooth" });
|
|
||||||
} else if (window.innerHeight - e.clientY < options.scrollThreshold.down) {
|
if (e.clientY < scrollThreshold.up) {
|
||||||
frameRenderer.scrollBy({ top: 70, behavior: "smooth" });
|
const overflow = scrollThreshold.up - e.clientY;
|
||||||
|
const ratio = Math.min(overflow / scrollThreshold.up, 1);
|
||||||
|
const scrollAmount = -maxScrollSpeed * ratio;
|
||||||
|
scrollableParent.scrollBy({ top: scrollAmount });
|
||||||
|
} else if (window.innerHeight - e.clientY < scrollThreshold.down) {
|
||||||
|
const overflow = e.clientY - (window.innerHeight - scrollThreshold.down);
|
||||||
|
const ratio = Math.min(overflow / scrollThreshold.down, 1);
|
||||||
|
const scrollAmount = maxScrollSpeed * ratio;
|
||||||
|
scrollableParent.scrollBy({ top: scrollAmount });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue