Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add option to disable scroll overlap detection #55

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var container = SmoothDnD(containerElement, options);
|dragBeginDelay|number| `0` (`200` for touch devices)|Time in milisecond. Delay to start dragging after item is pressed. Moving cursor before the delay more than 5px will cancel dragging.
|animationDuration|number|`250`|Animation duration in milisecond. To be consistent this animation duration will be applied to both drop and reorder animations.|
|autoScrollEnabled|boolean|`true`|First scrollable parent will scroll automatically if dragging item is close to boundaries.
|disableScrollOverlapDetection|boolean|`false`|Will detect what elements overlap and only scroll on the direct element you're dragging over. Disabling this will scroll on all scrollable elements at the same time.
|dragClass|string|`undefined`|Class to be added to the ghost item being dragged. The class will be added after it's added to the DOM so any transition in the class will be applied as intended.
|dropClass|string|`undefined`|Class to be added to the ghost item just before the drop animation begins.|
|removeOnDropOut|boolean|`undefined`|When set true onDrop will be called with a removedIndex if you drop element out of any relevant container|
Expand Down Expand Up @@ -212,4 +213,4 @@ The function to be called by the relevant container whenever a dragged item leav
function onDragLeave() {
...
}
```
```
3 changes: 2 additions & 1 deletion src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const defaultOptions: ContainerOptions = {
getChildPayload: undefined,
animationDuration: 250,
autoScrollEnabled: true,
disableScrollOverlapDetection: false,
shouldAcceptDrop: undefined,
shouldAnimateDrop: undefined,
};
};
2 changes: 2 additions & 0 deletions src/exportTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type SmoothDnDCreator = ((element: HTMLElement, options?: ContainerOption
dropHandler?: any;
wrapChild?: boolean;
maxScrollSpeed?: number;
disableScrollOverlapDetection?: boolean;
useTransformForGhost?: boolean;
cancelDrag: () => void;
isDragging: () => boolean;
Expand Down Expand Up @@ -45,6 +46,7 @@ export interface ContainerOptions {
dragBeginDelay?: number;
animationDuration?: number;
autoScrollEnabled?: boolean;
disableScrollOverlapDetection?: boolean;
lockAxis?: 'x' | 'y';
dragClass?: string;
dropClass?: string;
Expand Down
13 changes: 5 additions & 8 deletions src/mediator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,10 @@ function getGhostParent() {
}

function getGhostElement(wrapperElement: HTMLElement, { x, y }: Position, container: IContainer, cursor: string): GhostInfo {
const wrapperRect = wrapperElement.getBoundingClientRect();
const { left, top, right, bottom } = wrapperRect;

const wrapperVisibleRect = Utils.getIntersection(container.layout.getContainerRectangles().visibleRect, wrapperRect);

const midX = wrapperVisibleRect.left + (wrapperVisibleRect.right - wrapperVisibleRect.left) / 2;
const midY = wrapperVisibleRect.top + (wrapperVisibleRect.bottom - wrapperVisibleRect.top) / 2;
const { left, top, right, bottom } = wrapperElement.getBoundingClientRect();
const midX = left + (right - left) / 2;
const midY = top + (bottom - top) / 2;

const ghost: HTMLElement = wrapperElement.cloneNode(true) as HTMLElement;
ghost.style.zIndex = '1000';
ghost.style.boxSizing = 'border-box';
Expand Down Expand Up @@ -541,7 +538,7 @@ function dragHandler(dragListeningContainers: IContainer[]): (draggableInfo: Dra

function getScrollHandler(container: IContainer, dragListeningContainers: IContainer[]) {
if (container.getOptions().autoScrollEnabled) {
return dragScroller(dragListeningContainers, container.getScrollMaxSpeed());
return dragScroller(dragListeningContainers, container.getScrollMaxSpeed(), container.getOptions().disableScrollOverlapDetection);
} else {
return (props: { draggableInfo?: DraggableInfo; reset?: boolean }) => null;
}
Expand Down
30 changes: 16 additions & 14 deletions src/scroller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ function getTopmostScrollAnimator(animatorInfos: ScrollerAnimator[], position: P
return null;
}

export default (containers: IContainer[], maxScrollSpeed = maxSpeed) => {
export default (containers: IContainer[], maxScrollSpeed = maxSpeed, disableOverlapDetection = false) => {
const animatorInfos = containers.reduce((acc: ScrollerAnimator[], container: IContainer) => {
const filteredAnimators = getScrollerAnimator(container).filter(p => {
return !acc.find(q => q.scrollerElement === p.scrollerElement);
Expand Down Expand Up @@ -256,20 +256,22 @@ export default (containers: IContainer[], maxScrollSpeed = maxSpeed) => {
}
});

const overlappingAnimators = animatorInfos.filter(p => p.cachedRect);
if (overlappingAnimators.length && overlappingAnimators.length > 1) {
// stop animations except topmost
const topScrollerAnimator = getTopmostScrollAnimator(overlappingAnimators, draggableInfo.mousePosition);

if (topScrollerAnimator) {
overlappingAnimators.forEach(p => {
if (p !== topScrollerAnimator) {
p.axisAnimations.x && p.axisAnimations.x.animator.stop();
p.axisAnimations.y && p.axisAnimations.y.animator.stop();
}
})
if (disableOverlapDetection !== true) {
const overlappingAnimators = animatorInfos.filter(p => p.cachedRect);
if (overlappingAnimators.length && overlappingAnimators.length > 1) {
// stop animations except topmost
const topScrollerAnimator = getTopmostScrollAnimator(overlappingAnimators, draggableInfo.mousePosition);

if (topScrollerAnimator) {
overlappingAnimators.forEach(p => {
if (p !== topScrollerAnimator) {
p.axisAnimations.x && p.axisAnimations.x.animator.stop();
p.axisAnimations.y && p.axisAnimations.y.animator.stop();
}
})
}
}
}
}
}
}
}