Skip to content

Commit 722dd3c

Browse files
authored
Merge pull request #5858 from IgniteUI/SKrastev/drag-offset-8.2.x
Enhance the ghostOffsetX and ghostOffsetY so they can be applied regardless of ghost or not.
2 parents ab5a8c6 + 35ea49e commit 722dd3c

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
282282
public ghostHost;
283283

284284
/**
285-
* An @Input property that specifies the offset of the ghost created relative to the mouse in pixels.
285+
* An @Input property that specifies the offset of the dragged element relative to the mouse in pixels.
286286
* By default it's taking the relative position to the mouse when the drag started and keeps it the same.
287287
* ```html
288288
* <div #hostDiv></div>
@@ -294,15 +294,15 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
294294
*/
295295
@Input()
296296
public set ghostOffsetX(value) {
297-
this._ghostOffsetX = parseInt(value, 10);
297+
this._offsetX = parseInt(value, 10);
298298
}
299299

300300
public get ghostOffsetX() {
301-
return this._ghostOffsetX;
301+
return this._offsetX !== undefined ? this._offsetX : this._defaultOffsetX;
302302
}
303303

304304
/**
305-
* An @Input property that specifies the offset of the ghost created relative to the mouse in pixels.
305+
* An @Input property that specifies the offset of the dragged element relative to the mouse in pixels.
306306
* By default it's taking the relative position to the mouse when the drag started and keeps it the same.
307307
* ```html
308308
* <div #hostDiv></div>
@@ -314,11 +314,11 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
314314
*/
315315
@Input()
316316
public set ghostOffsetY(value) {
317-
this._ghostOffsetY = parseInt(value, 10);
317+
this._offsetY = parseInt(value, 10);
318318
}
319319

320320
public get ghostOffsetY() {
321-
return this._ghostOffsetY;
321+
return this._offsetY !== undefined ? this._offsetY : this._defaultOffsetY ;
322322
}
323323

324324
/**
@@ -613,17 +613,17 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
613613
protected _baseMarginTop = 0;
614614
protected _baseOriginX;
615615
protected _baseOriginY;
616-
protected _baseLeft;
617-
protected _baseTop;
618616
protected _startX = 0;
619617
protected _startY = 0;
620618
protected _lastX = 0;
621619
protected _lastY = 0;
622620
protected _dragStarted = false;
623621

624622
/** Drag ghost related properties */
625-
protected _ghostOffsetX;
626-
protected _ghostOffsetY;
623+
protected _defaultOffsetX;
624+
protected _defaultOffsetY;
625+
protected _offsetX;
626+
protected _offsetY;
627627
protected _ghostStartX;
628628
protected _ghostStartY;
629629
protected _ghostHostX = 0;
@@ -887,22 +887,10 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
887887
this._startY = event.touches[0].pageY;
888888
}
889889

890-
let offsetX;
891-
if (this.ghostOffsetX !== undefined) {
892-
offsetX = this.ghostOffsetX;
893-
} else {
894-
offsetX = this.baseLeft + this.getWindowScrollLeft() - this._startX;
895-
}
896-
897-
let offsetY;
898-
if (this.ghostOffsetY !== undefined) {
899-
offsetY = this.ghostOffsetY;
900-
} else {
901-
offsetY = this.baseTop + this.getWindowScrollTop() - this._startY;
902-
}
903-
904-
this._ghostStartX = this._startX + offsetX;
905-
this._ghostStartY = this._startY + offsetY;
890+
this._defaultOffsetX = this.baseLeft + this.getWindowScrollLeft() - this._startX;
891+
this._defaultOffsetY = this.baseTop + this.getWindowScrollTop() - this._startY;
892+
this._ghostStartX = this._startX + this.ghostOffsetX;
893+
this._ghostStartY = this._startY + this.ghostOffsetY;
906894
this._lastX = this._startX;
907895
this._lastY = this._startY;
908896
}
@@ -950,7 +938,15 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
950938
this._dragStarted = true;
951939
if (this.ghost) {
952940
// We moved enough so ghostElement can be rendered and actual dragging to start.
941+
// When creating it will take into account any offset set by the user by default.
953942
this.createGhost(pageX, pageY);
943+
} else if (this._offsetX !== undefined || this._offsetY !== undefined) {
944+
// There is no need for ghost, but we will need to position initially the base element to reflect any offset.
945+
const transformX = (this._offsetX !== undefined ? this._offsetX - this._defaultOffsetX : 0) +
946+
this.getTransformX(this.element.nativeElement);
947+
const transformY = (this._offsetY !== undefined ? this._offsetY - this._defaultOffsetY : 0) +
948+
this.getTransformY(this.element.nativeElement);
949+
this.setTransformXY(transformX, transformY);
954950
}
955951
} else {
956952
return;
@@ -1393,10 +1389,6 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy {
13931389

13941390
/** Method setting transformation to the base draggable element. */
13951391
protected setTransformXY(x: number, y: number) {
1396-
const curX = this.getTransformX(this.element.nativeElement);
1397-
const curY = this.getTransformY(this.element.nativeElement);
1398-
this._baseLeft += x - curX;
1399-
this._baseTop += y - curY;
14001392
this.element.nativeElement.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0px)';
14011393
}
14021394

projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,43 @@ describe('General igxDrag/igxDrop', () => {
547547
expect(firstDrag.dragStart.emit).toHaveBeenCalled();
548548
}));
549549

550+
it('should position the base element relative to the mouse using offsetX and offsetY correctly.', (async() => {
551+
const firstDrag = fix.componentInstance.dragElems.first;
552+
const firstElement = firstDrag.element.nativeElement;
553+
const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2;
554+
const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2;
555+
firstDrag.ghost = false;
556+
firstDrag.ghostOffsetX = 0;
557+
firstDrag.ghostOffsetY = 0;
558+
firstDrag.ghostTemplate = fix.componentInstance.ghostTemplate;
559+
560+
// Step 1.
561+
UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY);
562+
fix.detectChanges();
563+
await wait();
564+
565+
// Step 2.
566+
UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10);
567+
fix.detectChanges();
568+
await wait(100);
569+
570+
// Step 3.
571+
UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20);
572+
fix.detectChanges();
573+
await wait(100);
574+
575+
// We compare the base position and the new position + how much the mouse has moved.
576+
// + 10 margin to the final ghost position
577+
expect(firstElement.getBoundingClientRect().left).toEqual(startingX + 20);
578+
expect(firstElement.getBoundingClientRect().top).toEqual(startingY + 20);
579+
expect(firstElement.innerText).toEqual('Drag 1');
580+
581+
// Step 4.
582+
UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20);
583+
fix.detectChanges();
584+
await wait();
585+
}));
586+
550587
it('should correctly set location using setLocation() method when ghost is disabled', (async() => {
551588
const firstDrag = fix.componentInstance.dragElems.first;
552589
const firstElement = firstDrag.element.nativeElement;

0 commit comments

Comments
 (0)