Skip to content

Commit d137d0e

Browse files
committed
feat(auto-scrolling): Added auto scrolling feature (vertical & horizontal).
When dragging a grid item, an auto scroll is performed if the pointer is near it's scrollParent borders. ScrollParent needs to be provided in order to enable scroll. Scroll vertical is always performed but scroll horizontal is only performed if the scrollParent has explicitly a current horizontal overflowing.
1 parent 223a14f commit d137d0e

21 files changed

+737
-103
lines changed

projects/angular-grid-layout/src/lib/grid.component.ts

Lines changed: 129 additions & 81 deletions
Large diffs are not rendered by default.

projects/angular-grid-layout/src/lib/grid.definitions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,9 @@ export interface KtdGridItemRenderData<T = number | string> {
4242
export type KtdGridItemRenderDataTokenType = (id: string) => KtdGridItemRenderData<string>;
4343
export const GRID_ITEM_GET_RENDER_DATA_TOKEN: InjectionToken<KtdGridItemRenderDataTokenType> = new InjectionToken('GRID_ITEM_GET_RENDER_DATA_TOKEN');
4444

45+
export interface KtdDraggingData {
46+
pointerDownEvent: MouseEvent | TouchEvent;
47+
pointerDragEvent: MouseEvent | TouchEvent;
48+
parentElemClientRect: ClientRect;
49+
dragElemClientRect: ClientRect;
50+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
// tslint:disable
3+
4+
/**
5+
* Client rect utilities.
6+
* This file is taken from Angular Material repository. This is the reason why the tslint is disabled on this case.
7+
* Don't enable it until some custom change is done on this file.
8+
*/
9+
10+
11+
/** Gets a mutable version of an element's bounding `ClientRect`. */
12+
export function getMutableClientRect(element: Element): ClientRect {
13+
const clientRect = element.getBoundingClientRect();
14+
15+
// We need to clone the `clientRect` here, because all the values on it are readonly
16+
// and we need to be able to update them. Also we can't use a spread here, because
17+
// the values on a `ClientRect` aren't own properties. See:
18+
// https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes
19+
return {
20+
top: clientRect.top,
21+
right: clientRect.right,
22+
bottom: clientRect.bottom,
23+
left: clientRect.left,
24+
width: clientRect.width,
25+
height: clientRect.height
26+
};
27+
}
28+
29+
/**
30+
* Checks whether some coordinates are within a `ClientRect`.
31+
* @param clientRect ClientRect that is being checked.
32+
* @param x Coordinates along the X axis.
33+
* @param y Coordinates along the Y axis.
34+
*/
35+
export function isInsideClientRect(clientRect: ClientRect, x: number, y: number) {
36+
const {top, bottom, left, right} = clientRect;
37+
return y >= top && y <= bottom && x >= left && x <= right;
38+
}
39+
40+
/**
41+
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
42+
* @param clientRect `ClientRect` that should be updated.
43+
* @param top Amount to add to the `top` position.
44+
* @param left Amount to add to the `left` position.
45+
*/
46+
export function adjustClientRect(clientRect: ClientRect, top: number, left: number) {
47+
clientRect.top += top;
48+
clientRect.bottom = clientRect.top + clientRect.height;
49+
50+
clientRect.left += left;
51+
clientRect.right = clientRect.left + clientRect.width;
52+
}
53+
54+
/**
55+
* Checks whether the pointer coordinates are close to a ClientRect.
56+
* @param rect ClientRect to check against.
57+
* @param threshold Threshold around the ClientRect.
58+
* @param pointerX Coordinates along the X axis.
59+
* @param pointerY Coordinates along the Y axis.
60+
*/
61+
export function isPointerNearClientRect(rect: ClientRect,
62+
threshold: number,
63+
pointerX: number,
64+
pointerY: number): boolean {
65+
const {top, right, bottom, left, width, height} = rect;
66+
const xThreshold = width * threshold;
67+
const yThreshold = height * threshold;
68+
69+
return pointerY > top - yThreshold && pointerY < bottom + yThreshold &&
70+
pointerX > left - xThreshold && pointerX < right + xThreshold;
71+
}

projects/angular-grid-layout/src/lib/utils/grid.utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { compact, CompactType, LayoutItem, moveElement } from './react-grid-layout.utils';
2-
import { KtdGridCfg, KtdGridCompactType, KtdGridItemRect, KtdGridLayout, KtdGridLayoutItem } from '../grid.definitions';
2+
import { KtdDraggingData, KtdGridCfg, KtdGridCompactType, KtdGridItemRect, KtdGridLayout, KtdGridLayoutItem } from '../grid.definitions';
33
import { ktdPointerClientX, ktdPointerClientY } from './pointer.utils';
44
import { KtdDictionary } from '../../types';
55

@@ -53,7 +53,7 @@ export function ktdGetGridLayoutDiff(gridLayoutA: KtdGridLayoutItem[], gridLayou
5353
* @param compactionType type of compaction that will be performed
5454
* @param draggingData contains all the information about the drag
5555
*/
56-
export function ktdGridItemDragging(gridItemId: string, config: KtdGridCfg, compactionType: CompactType, draggingData: { pointerDownEvent: MouseEvent | TouchEvent, pointerDragEvent: MouseEvent | TouchEvent, parentElemClientRect: ClientRect, dragElemClientRect: ClientRect }): { layout: KtdGridLayoutItem[]; draggedItemPos: KtdGridItemRect } {
56+
export function ktdGridItemDragging(gridItemId: string, config: KtdGridCfg, compactionType: CompactType, draggingData: KtdDraggingData): { layout: KtdGridLayoutItem[]; draggedItemPos: KtdGridItemRect } {
5757
const {pointerDownEvent, pointerDragEvent, parentElemClientRect, dragElemClientRect} = draggingData;
5858

5959
const draggingElemPrevItem = config.layout.find(item => item.id === gridItemId)!;
@@ -120,7 +120,7 @@ export function ktdGridItemDragging(gridItemId: string, config: KtdGridCfg, comp
120120
* @param compactionType type of compaction that will be performed
121121
* @param draggingData contains all the information about the drag
122122
*/
123-
export function ktdGridItemResizing(gridItemId: string, config: KtdGridCfg, compactionType: CompactType, draggingData: { pointerDownEvent: MouseEvent | TouchEvent, pointerDragEvent: MouseEvent | TouchEvent, parentElemClientRect: ClientRect, dragElemClientRect: ClientRect }): { layout: KtdGridLayoutItem[]; draggedItemPos: KtdGridItemRect } {
123+
export function ktdGridItemResizing(gridItemId: string, config: KtdGridCfg, compactionType: CompactType, draggingData: KtdDraggingData): { layout: KtdGridLayoutItem[]; draggedItemPos: KtdGridItemRect } {
124124
const {pointerDownEvent, pointerDragEvent, parentElemClientRect, dragElemClientRect} = draggingData;
125125

126126
const clientStartX = ktdPointerClientX(pointerDownEvent);

0 commit comments

Comments
 (0)