From 50b9da6a61dead020197943e19f068d4e6430160 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 28 Nov 2018 16:53:01 +0100 Subject: [PATCH] fix(drag-drop): dragged elements blurry in some browsers (#14299) Rounds the `transform` value before they're assigned, in order to avoid blurriness in some browsers. Fixes #14283. --- src/cdk/drag-drop/drag.spec.ts | 13 ++++++++++++- src/cdk/drag-drop/drag.ts | 4 +++- src/cdk/drag-drop/drop-list.ts | 6 ++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/cdk/drag-drop/drag.spec.ts b/src/cdk/drag-drop/drag.spec.ts index a37613983cb..6aeb5e05117 100644 --- a/src/cdk/drag-drop/drag.spec.ts +++ b/src/cdk/drag-drop/drag.spec.ts @@ -504,6 +504,7 @@ describe('CdkDrag', () => { expect(dragElement.style.touchAction) .not.toEqual('none', 'should not disable touchAction on when there is a drag handle'); }); + it('should be able to reset a freely-dragged item to its initial position', fakeAsync(() => { const fixture = createComponent(StandaloneDraggable); fixture.detectChanges(); @@ -556,7 +557,17 @@ describe('CdkDrag', () => { expect(fixture.componentInstance.endedSpy).toHaveBeenCalledTimes(1); })); - }); + it('should round the transform value', fakeAsync(() => { + const fixture = createComponent(StandaloneDraggable); + fixture.detectChanges(); + const dragElement = fixture.componentInstance.dragElement.nativeElement; + + expect(dragElement.style.transform).toBeFalsy(); + dragElementViaMouse(fixture, dragElement, 13.37, 37); + expect(dragElement.style.transform).toBe('translate3d(13px, 37px, 0px)'); + })); + + }); describe('draggable with a handle', () => { it('should not be able to drag the entire element if it has a handle', fakeAsync(() => { diff --git a/src/cdk/drag-drop/drag.ts b/src/cdk/drag-drop/drag.ts index c852a91a397..0a553e18fb5 100644 --- a/src/cdk/drag-drop/drag.ts +++ b/src/cdk/drag-drop/drag.ts @@ -866,7 +866,9 @@ interface Point { * @param y Desired position of the element along the Y axis. */ function getTransform(x: number, y: number): string { - return `translate3d(${x}px, ${y}px, 0)`; + // Round the transforms since some browsers will + // blur the elements, for sub-pixel transforms. + return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`; } /** Creates a deep clone of an element. */ diff --git a/src/cdk/drag-drop/drop-list.ts b/src/cdk/drag-drop/drop-list.ts index 00ab3c667af..bd2e4be865b 100644 --- a/src/cdk/drag-drop/drop-list.ts +++ b/src/cdk/drag-drop/drop-list.ts @@ -362,10 +362,12 @@ export class CdkDropList implements OnInit, OnDestroy { // Note that we shouldn't use `getBoundingClientRect` here to update the cache, because the // elements may be mid-animation which will give us a wrong result. if (isHorizontal) { - elementToOffset.style.transform = `translate3d(${sibling.offset}px, 0, 0)`; + // Round the transforms since some browsers will + // blur the elements, for sub-pixel transforms. + elementToOffset.style.transform = `translate3d(${Math.round(sibling.offset)}px, 0, 0)`; this._adjustClientRect(sibling.clientRect, 0, offset); } else { - elementToOffset.style.transform = `translate3d(0, ${sibling.offset}px, 0)`; + elementToOffset.style.transform = `translate3d(0, ${Math.round(sibling.offset)}px, 0)`; this._adjustClientRect(sibling.clientRect, offset, 0); } });