Skip to content

Instantly share code, notes, and snippets.

@devdilson
Created November 16, 2020 07:00
Show Gist options
  • Select an option

  • Save devdilson/d790ba38aafaa99c8e04b563b7f88484 to your computer and use it in GitHub Desktop.

Select an option

Save devdilson/d790ba38aafaa99c8e04b563b7f88484 to your computer and use it in GitHub Desktop.
A very simple draggable directive.
import { Directive, ElementRef, HostListener } from '@angular/core';
/**
* Prevents the event and stop the propagation.
*/
function StopEvent(): any {
return (target: any, propqrtyKey: string, descriptor: PropertyDescriptor) => {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
if (args[0] instanceof Event) {
const evt: Event = args[0] as Event;
evt.preventDefault();
evt.stopImmediatePropagation();
}
return originalMethod.apply(this, args);
}
return descriptor;
}
}
@Directive({
selector: "[draggableElement]"
})
export class DraggableElementDirective {
startX: number = 0;
startY: number = 0;
posDiffX = 0;
posDiffY = 0;
isDragging = false;
zIndex = 0;
nativeEl: HTMLElement;
parentNativeEl: HTMLElement;
constructor(private readonly ref: ElementRef) {
this.nativeEl = this.ref.nativeElement;
this.parentNativeEl = this.ref.nativeElement.parentElement;
this.zIndex = +this.nativeEl.style.zIndex;
}
@StopEvent() @HostListener('mousedown', ['$event']) onMouseDown(evt: MouseEvent) {
this.startX = evt.clientX;
this.startY = evt.clientY;
this.isDragging = true;
this.nativeEl.onmousemove = (evt) => this.onMouseMove(evt);
this.nativeEl.style.position = "absolute";
this.nativeEl.style.cursor = 'move';
this.zIndex = +this.nativeEl.style.zIndex;
this.nativeEl.style.zIndex = 9999 + '';
this.nativeEl.style.userSelect = 'none';
}
@HostListener('mouseup', ['$event']) onMouseUp(evt: MouseEvent) {
this.nativeEl.style.cursor = '';
this.startX = evt.clientX;
this.startY = evt.clientY;
this.isDragging = false;
this.nativeEl.onmousemove = () => { };
this.nativeEl.style.zIndex = this.zIndex + '';
this.nativeEl.style.userSelect = '';
}
@StopEvent() onMouseMove(evt: MouseEvent) {
if (!this.isDragging) {
return;
}
this.posDiffX = this.startX - evt.clientX;
this.posDiffY = this.startY - evt.clientY;
this.startX = evt.clientX;
this.startY = evt.clientY;
const el = this.nativeEl;
el.style.top = (el.offsetTop - this.posDiffY) + "px";
el.style.left = (el.offsetLeft - this.posDiffX) + "px";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment