1
- import { Directive , EventEmitter , HostListener , Output } from '@angular/core' ;
1
+ import { Directive , ElementRef , EventEmitter , HostListener , Output } from '@angular/core' ;
2
+ import { PositionMapper } from '@ui-model/angular/src/lib/services/position-mapper.service' ;
2
3
import { Distance , Point } from '@ui-model/core' ;
3
4
4
- // TODO: 处理 svg 坐标系映射
5
-
6
5
@Directive ( {
7
6
selector : '[uiMovable]' ,
8
7
exportAs : 'uiMovable' ,
9
8
} )
10
9
export class MovableDirective {
11
- @Output ( 'uiMoveStart' ) start = new EventEmitter < MouseEvent > ( ) ;
12
- @Output ( 'uiMoving' ) move = new EventEmitter < MouseEvent > ( ) ;
13
- @Output ( 'uiMoveStop' ) stop = new EventEmitter < MouseEvent > ( ) ;
10
+ constructor ( private elementRef : ElementRef < Element > , private mapper : PositionMapper ) {
11
+ }
14
12
15
- moving = false ;
13
+ @Output ( 'uiMoveStart' ) start = new EventEmitter < Distance > ( ) ;
14
+ @Output ( 'uiMoving' ) move = new EventEmitter < Distance > ( ) ;
15
+ @Output ( 'uiMoveStop' ) stop = new EventEmitter < Distance > ( ) ;
16
+ offset = new Distance ( ) ;
17
+ private previousPoint = new Point ( ) ;
16
18
17
- startPos = new Point ( ) ;
18
- latestPos = new Point ( ) ;
19
- pos = new Point ( ) ;
19
+ private _moving = false ;
20
20
21
- get offset ( ) : Distance {
22
- return this . pos . getDistanceTo ( this . startPos ) ;
21
+ get moving ( ) : boolean {
22
+ return this . _moving ;
23
23
}
24
24
25
- get delta ( ) : Distance {
26
- return this . pos . getDistanceTo ( this . latestPos ) ;
25
+ get element ( ) : Element {
26
+ return this . elementRef . nativeElement ;
27
27
}
28
28
29
29
@HostListener ( 'click' , [ '$event' ] )
@@ -38,25 +38,23 @@ export class MovableDirective {
38
38
}
39
39
40
40
const target = event . target as Element ;
41
- target . setPointerCapture ( 1 ) ;
41
+ target . setPointerCapture ( event . which ) ;
42
42
event . stopPropagation ( ) ;
43
- this . moving = true ;
44
- this . startPos = new Point ( event . screenX , event . screenY ) ;
45
- this . pos = new Point ( event . screenX , event . screenY ) ;
46
- this . start . emit ( event ) ;
43
+ this . _moving = true ;
44
+ this . previousPoint = this . svgPos ( event . clientX , event . clientY ) ;
45
+ this . start . emit ( this . offset ) ;
47
46
}
48
47
49
48
@HostListener ( 'mouseup' , [ '$event' ] )
50
49
mouseUp ( event : MouseEvent ) : void {
51
50
if ( ! isMajorButton ( event ) ) {
52
51
return ;
53
52
}
54
- ( event . target as Element ) . releasePointerCapture ( 1 ) ;
53
+ const target = event . target as Element ;
54
+ target . releasePointerCapture ( event . which ) ;
55
55
event . stopPropagation ( ) ;
56
- this . moving = false ;
57
- this . stop . emit ( event ) ;
58
- this . startPos = new Point ( event . screenX , event . screenY ) ;
59
- this . pos = new Point ( event . screenX , event . screenY ) ;
56
+ this . _moving = false ;
57
+ this . stop . emit ( this . offset ) ;
60
58
}
61
59
62
60
@HostListener ( 'mousemove' , [ '$event' ] )
@@ -65,12 +63,18 @@ export class MovableDirective {
65
63
return ;
66
64
}
67
65
event . stopPropagation ( ) ;
68
- if ( this . moving ) {
69
- this . latestPos = this . pos ;
70
- this . pos = new Point ( event . screenX , event . screenY ) ;
71
- this . move . emit ( event ) ;
66
+ if ( this . _moving ) {
67
+ const currentPoint = this . svgPos ( event . clientX , event . clientY ) ;
68
+ this . offset . x += currentPoint . x - this . previousPoint . x ;
69
+ this . offset . y += currentPoint . y - this . previousPoint . y ;
70
+ this . previousPoint = currentPoint ;
71
+ this . move . emit ( this . offset ) ;
72
72
}
73
73
}
74
+
75
+ svgPos ( x : number , y : number ) : Point {
76
+ return this . mapper . mapToLocal ( this . element , new Point ( x , y ) ) ;
77
+ }
74
78
}
75
79
76
80
function isMajorButton ( event : MouseEvent ) : boolean {
0 commit comments