1+ import { Directive , ElementRef , Renderer , OnDestroy , OnInit , AfterViewInit , Input } from '@angular/core' ;
2+
3+
4+ @Directive ( {
5+ selector : '[draggable]' ,
6+ host : {
7+ '(dragstart)' : 'onDragStart($event)' ,
8+ '(dragend)' : 'onDragEnd($event)' ,
9+ '(drag)' : 'onDrag($event)'
10+ }
11+ } )
12+ export class DraggableDirecrtive implements OnDestroy , OnInit , AfterViewInit {
13+ private Δx : number = 0 ;
14+ private Δy : number = 0 ;
15+
16+ private canDrag :boolean = true ;
17+
18+ @Input ( 'draggable' )
19+ set draggable ( val :any ) {
20+ if ( val === undefined || val === null || val === '' ) return ;
21+ this . canDrag = ! ! val ;
22+ }
23+ private mustBePosition : Array < string > = [ 'absolute' , 'fixed' , 'relative' ] ;
24+ constructor (
25+ private el : ElementRef , private renderer : Renderer
26+ ) {
27+
28+ }
29+
30+ ngOnInit ( ) : void {
31+ this . renderer . setElementAttribute ( this . el . nativeElement , 'draggable' , 'true' ) ;
32+ }
33+ ngAfterViewInit ( ) {
34+ try {
35+ let position = window . getComputedStyle ( this . el . nativeElement ) . position ;
36+ if ( this . mustBePosition . indexOf ( position ) === - 1 ) {
37+ console . warn ( this . el . nativeElement , 'Must be having position attribute set to ' + this . mustBePosition . join ( '|' ) ) ;
38+ }
39+ } catch ( ex ) {
40+ console . error ( ex ) ;
41+ }
42+ }
43+ ngOnDestroy ( ) : void {
44+ this . renderer . setElementAttribute ( this . el . nativeElement , 'draggable' , 'false' ) ;
45+ }
46+
47+ onDragStart ( event : MouseEvent ) {
48+ this . Δx = event . x - this . el . nativeElement . offsetLeft ;
49+ this . Δy = event . y - this . el . nativeElement . offsetTop ;
50+ }
51+
52+ onDrag ( event : MouseEvent ) {
53+ this . doTranslation ( event . x , event . y ) ;
54+ }
55+
56+ onDragEnd ( event : MouseEvent ) {
57+ this . Δx = 0 ;
58+ this . Δy = 0 ;
59+ }
60+
61+ doTranslation ( x : number , y : number ) {
62+ if ( ! x || ! y ) return ;
63+ this . renderer . setElementStyle ( this . el . nativeElement , 'top' , ( y - this . Δy ) + 'px' ) ;
64+ this . renderer . setElementStyle ( this . el . nativeElement , 'left' , ( x - this . Δx ) + 'px' ) ;
65+ }
66+
67+
68+ }
0 commit comments