UNPKG

motion-v

Version:

<h1 align="center"> <img width="35" height="35" alt="Motion logo" src="https://github.com/user-attachments/assets/00d6d1c3-72c4-4c2f-a664-69da13182ffc" /><br />Motion for Vue</h1>

84 lines (83 loc) 3.21 kB
var threshold = 50; var maxSpeed = 25; var overflowStyles = new Set(["auto", "scroll"]); var initialScrollLimits = /* @__PURE__ */ new WeakMap(); var activeScrollEdge = /* @__PURE__ */ new WeakMap(); var currentGroupElement = null; function resetAutoScrollState() { if (currentGroupElement) { const scrollableAncestor = findScrollableAncestor(currentGroupElement, "y"); if (scrollableAncestor) { activeScrollEdge.delete(scrollableAncestor); initialScrollLimits.delete(scrollableAncestor); } const scrollableAncestorX = findScrollableAncestor(currentGroupElement, "x"); if (scrollableAncestorX && scrollableAncestorX !== scrollableAncestor) { activeScrollEdge.delete(scrollableAncestorX); initialScrollLimits.delete(scrollableAncestorX); } currentGroupElement = null; } } function isScrollableElement(element, axis) { const style = getComputedStyle(element); const overflow = axis === "x" ? style.overflowX : style.overflowY; return overflowStyles.has(overflow); } function findScrollableAncestor(element, axis) { let current = element?.parentElement; while (current) { if (isScrollableElement(current, axis)) return current; current = current.parentElement; } return null; } function getScrollAmount(pointerPosition, scrollElement, axis) { const rect = scrollElement.getBoundingClientRect(); const start = axis === "x" ? rect.left : rect.top; const end = axis === "x" ? rect.right : rect.bottom; const distanceFromStart = pointerPosition - start; const distanceFromEnd = end - pointerPosition; if (distanceFromStart < threshold) { const intensity = 1 - distanceFromStart / threshold; return { amount: -maxSpeed * intensity * intensity, edge: "start" }; } else if (distanceFromEnd < threshold) { const intensity = 1 - distanceFromEnd / threshold; return { amount: maxSpeed * intensity * intensity, edge: "end" }; } return { amount: 0, edge: null }; } function autoScrollIfNeeded(groupElement, pointerPosition, axis, velocity) { if (!groupElement) return; currentGroupElement = groupElement; const scrollableAncestor = findScrollableAncestor(groupElement, axis); if (!scrollableAncestor) return; const { amount: scrollAmount, edge } = getScrollAmount(pointerPosition, scrollableAncestor, axis); if (edge === null) { activeScrollEdge.delete(scrollableAncestor); initialScrollLimits.delete(scrollableAncestor); return; } if (activeScrollEdge.get(scrollableAncestor) !== edge) { if (!(edge === "start" && velocity < 0 || edge === "end" && velocity > 0)) return; activeScrollEdge.set(scrollableAncestor, edge); const maxScroll = axis === "x" ? scrollableAncestor.scrollWidth - scrollableAncestor.clientWidth : scrollableAncestor.scrollHeight - scrollableAncestor.clientHeight; initialScrollLimits.set(scrollableAncestor, maxScroll); } if (scrollAmount > 0) { const initialLimit = initialScrollLimits.get(scrollableAncestor); if ((axis === "x" ? scrollableAncestor.scrollLeft : scrollableAncestor.scrollTop) >= initialLimit) return; } if (axis === "x") scrollableAncestor.scrollLeft += scrollAmount; else scrollableAncestor.scrollTop += scrollAmount; } export { autoScrollIfNeeded, resetAutoScrollState };