UNPKG

fluid-dnd

Version:

An agnostic drag and drop library to sort all kind of lists. With current support for vue, react and svelte

53 lines (52 loc) 2.46 kB
import { draggableIsCompleteOutside, getAxisValue, getBefore, getDistanceValue, getRect } from '../utils/GetStyles'; const scrollByDirection = (element, direction, scrollAmount) => { if (scrollAmount == 0) { return; } if (direction === 'vertical') { element.scrollBy(0, scrollAmount); } else { element.scrollBy(scrollAmount, 0); } }; export const useScroll = (draggedElement) => { let lastScrollAmount = 0.5; const minScrollAmountDiff = 0.03; const updateScrollByPosition = (direction, parent, position, translate) => { const [distanceValue] = getDistanceValue(direction, getRect(draggedElement)); const parentBoundingClientRect = getRect(parent); const positionInsideParent = getBefore(direction, position) - getBefore(direction, parentBoundingClientRect) + getAxisValue(direction, translate); const [parentDistance] = getDistanceValue(direction, parentBoundingClientRect); const totalDistance = parentDistance - distanceValue; const relativePosition = positionInsideParent / totalDistance; const relativeDistanceValue = distanceValue / totalDistance; const velocity = 0.25; const infLimit = 0.2; const upperLimit = 0.8; let percent = 0; const isOutside = draggableIsCompleteOutside(draggedElement, parent); if (!isOutside && relativePosition < infLimit && relativePosition > -relativeDistanceValue) { percent = scrollFuncionToStart(relativePosition < 0 ? 0 : relativePosition, infLimit); } else if (!isOutside && relativePosition > upperLimit && relativePosition < 1 + relativeDistanceValue) { percent = scrollFuncionToEnd(relativePosition, upperLimit); } const scrollAmount = velocity * distanceValue * percent; lastScrollAmount = Math.sign(scrollAmount) * Math.min(Math.abs(scrollAmount), Math.abs(lastScrollAmount) + minScrollAmountDiff); scrollByDirection(parent, direction, lastScrollAmount); }; const scrollFuncionToStart = (relativePosition, infLimit) => { return Math.pow(relativePosition / infLimit, 1 / 3) - 1; }; const scrollFuncionToEnd = (relativePosition, upperLimit) => { return Math.pow((1 / (1 - upperLimit)) * (relativePosition - upperLimit), 3); }; return [updateScrollByPosition]; };