import { Directive, Input, ElementRef, NgZone } from '@angular/core'; import { Subject } from 'rxjs'; var Rx = require('rxjs-compat'); var Observable = Rx.Observable; // DEPRICATED - REFACTOR @Directive({ selector: '[hborDraggable]' }) export class DraggableDirective { @Input() dragHandle: string; @Input() dragTarget: string; // Element to be dragged private target: HTMLElement; // Drag handle private handle: HTMLElement; private delta = { x: 0, y: 0 }; private offset = { x: 0, y: 0 }; private destroy$ = new Subject(); constructor(private elementRef: ElementRef, private zone: NgZone) { } public ngAfterViewInit(): void { this.handle = this.dragHandle ? document.querySelector(this.dragHandle) as HTMLElement : this.elementRef.nativeElement; this.target = document.querySelector(this.dragTarget) as HTMLElement; this.setupEvents(); } public ngOnDestroy(): void { this.destroy$.next(); } private setupEvents() { this.zone.runOutsideAngular(() => { let mousedown$ = Observable.fromEvent(this.handle, 'mousedown'); let mousemove$ = Observable.fromEvent(document, 'mousemove'); let mouseup$ = Observable.fromEvent(document, 'mouseup'); let mousedrag$ = mousedown$.switchMap((event: MouseEvent) => { let startX = event.clientX; let startY = event.clientY; return mousemove$ .map((event: MouseEvent) => { event.preventDefault(); this.delta = { x: event.clientX - startX, y: event.clientY - startY }; }) .takeUntil(mouseup$); }).takeUntil(this.destroy$); mousedrag$.subscribe(() => { if (this.delta.x === 0 && this.delta.y === 0) { return; } this.translate(); }); mouseup$.takeUntil(this.destroy$).subscribe(() => { this.offset.x += this.delta.x; this.offset.y += this.delta.y; this.delta = { x: 0, y: 0 }; }); }); } private translate() { requestAnimationFrame(() => { this.target.style.transform = ` translate(${this.offset.x + this.delta.x}px, ${this.offset.y + this.delta.y}px) `; }); } }