2
2
/// <reference path="../../custom_typings/ng2.d.ts" />
3
3
4
4
// Angular 2
5
- import { Component , View , coreDirectives , onChange , ON_PUSH } from 'angular2/angular2' ;
5
+ import { Directive , Component , View , coreDirectives , onChange , onDestroy , ON_PUSH , ElementRef } from 'angular2/angular2' ;
6
6
import { Observable } from 'angular2/src/facade/async' ;
7
7
import { Inject } from 'angular2/di'
8
8
import { RouteConfig , Router , RouterOutlet , RouterLink } from 'angular2/router' ;
@@ -23,23 +23,89 @@ import {GreetIntent} from '../intents/GreetIntent';
23
23
import { GreetModel } from '../models/GreetModel' ;
24
24
25
25
26
+ @Directive ( {
27
+ selector : '[drag-element]' ,
28
+ hostListeners : {
29
+ // Observable plz
30
+ // 'mouseup': 'onMouseup($event)',
31
+ // 'mousedown': 'onMousedown($event)'
32
+ // 'window:mousemove': 'onMousedown($event)'
33
+ }
34
+ } )
35
+ export class DragElement {
36
+ mouseup : Rx . Observable < any > ;
37
+ mousemove : Rx . Observable < any > ;
38
+ mousedown : Rx . Observable < any > ;
39
+ mousedrag : Rx . Observable < any > ;
40
+ constructor ( { domElement} : ElementRef ) {
41
+
42
+ this . mouseup = this . fromDOMSource ( 'mouseup' , domElement )
43
+ this . mousemove = this . fromDOMSource ( 'mousemove' , window . document ) ;
44
+ this . mousedown = this . fromDOMSource ( 'mousedown' , domElement ) .
45
+ map ( event => {
46
+ event . preventDefault ( ) ;
47
+ // calculate offsets when mouse down
48
+ var { clientY, clientX} = event ;
49
+ return {
50
+ left : clientX - domElement . getBoundingClientRect ( ) . left ,
51
+ top : clientY - domElement . getBoundingClientRect ( ) . top ,
52
+ } ;
53
+ } ) ;
54
+
55
+ // Combine mouse down with mouse move until mouse up
56
+ this . mousedrag = this . mousedown .
57
+ selectMany ( imageOffset => {
58
+ return this . mousemove . map ( pos => {
59
+ var { clientY, clientX} = pos ;
60
+ var { top, left} = imageOffset ;
61
+ // calculate offsets from mouse down to mouse moves
62
+ return {
63
+ top : clientY - top ,
64
+ left : clientX - left
65
+ } ;
66
+ } ) . takeUntil ( this . mouseup ) ;
67
+ } ) ;
68
+ /*
69
+ todo: Use requestAnimationFrame Scheduler
70
+ */
71
+ this . mousedrag . subscribe ( pos => {
72
+ var { top, left} = pos ;
73
+ var { style} = domElement ;
74
+ // Update position
75
+ // requestAnimationFrame
76
+ style . top = top + 'px' ;
77
+ style . left = left + 'px' ;
78
+ } ) ;
79
+ }
80
+
81
+ fromDOMSource ( eventName : string , el : any ) : Rx . Observable < any > {
82
+ return Rx . Observable . fromEventPattern (
83
+ callback => el . addEventListener ( eventName , callback , false ) ,
84
+ callback => el . removeEventListener ( eventName , callback )
85
+ ) ;
86
+ }
87
+ }
88
+
89
+
26
90
@Component ( {
27
91
selector : 'count' ,
28
- lifecycle : [ onChange ] ,
92
+ // lifecycle: [onChange],
29
93
// changeDetection: ON_PUSH,
30
94
properties : { 'counter' : 'counter' }
31
95
} )
32
96
@View ( {
97
+ directives : [ ] ,
33
98
template : `
34
99
<div>
35
100
counter {{ counter }}
36
101
37
- <div>
102
+
103
+ <p>
38
104
<button (click)="incrementCounter()">
39
105
Increment Counter from Component
40
106
</button>
41
107
<content></content>
42
- </div >
108
+ </p >
43
109
44
110
</div>
45
111
`
@@ -53,34 +119,68 @@ export class Count {
53
119
this . counterIntent . incrementCounter ( ) ;
54
120
}
55
121
56
- onChange ( value ) {
57
- console . log ( 'CHANGE Count' , '\n' , JSON . stringify ( value , null , 2 ) ) ;
58
- }
122
+ // onChange(value) {
123
+ // console.log('CHANGE Count','\n', JSON.stringify(value, null, 2));
124
+ // }
59
125
}
60
126
61
127
62
128
63
129
@Component ( {
64
130
selector : 'app' ,
65
- lifecycle : [ onChange ] ,
66
131
// changeDetection: ON_PUSH
67
132
} )
68
133
@View ( {
69
134
// needed in order to tell Angular's compiler what's in the template
70
- directives : [ routerDirectives , coreDirectives , Count ] ,
135
+ directives : [ routerDirectives , coreDirectives , Count , DragElement ] ,
71
136
template : `
137
+ <style>
138
+ [drag-element] {
139
+ -webkit-transform: translate3d(0, 0, 0);
140
+ -moz-transform: translate3d(0, 0, 0);
141
+ -ms-transform: translate3d(0, 0, 0);
142
+ transform: translate3d(0, 0, 0);
143
+ background-image: url(https://cdn.rawgit.com/Reactive-Extensions/rx.angular.js/master/examples/draganddrop/logo.png);
144
+ background-repeat: no-repeat;
145
+ background-position: center;
146
+ background-size: contain;
147
+ height: 200px;
148
+ width: 200px;
149
+ color: #000000;
150
+ border: 1px solid #666666;
151
+ padding: 10px;
152
+ position: absolute;
153
+ cursor: move;
154
+ }
155
+ </style>
156
+
157
+ <header>
158
+ <h1 class="title">Hello Reactive Angular 2</h1>
159
+ </header>
160
+
161
+ <main>
162
+ <count [counter]="appState | async | get('counter')">
163
+ <button (click)="handleIncrement()">Increment Counter from App</button>
164
+ </count>
165
+
166
+ <h2>
167
+ Greet {{ appState | async | get('greeting') }}
168
+ </h2>
169
+
170
+ <p>
171
+ <button (^click)="toggleGreet()">Greet {{ appState | async | get('greeting') }} </button>
172
+ </p>
173
+ <p>
174
+ <pre>appState = {{ appState | async | json }}</pre>
175
+ </p>
176
+ </main>
177
+
178
+ <footer>
179
+ <div drag-element>
180
+ Draggable Div
181
+ </div>
182
+ </footer>
72
183
73
- <h1 class="title">Hello Reactive Angular 2</h1>
74
-
75
- <count [counter]="appState | async | get('counter')">
76
- <button (click)="handleIncrement()">Increment Counter from App</button>
77
- </count>
78
-
79
- <h2>Greet {{ appState | async | get('greeting') }}</h2>
80
- <div>
81
- <button (^click)="toggleGreet()">Greet {{ appState | async | get('greeting') }} </button>
82
- </div>
83
- <pre>appState = {{ appState | async | json }}</pre>
84
184
`
85
185
} )
86
186
export class App {
@@ -107,8 +207,4 @@ export class App {
107
207
this . greetIntent . toggleGreet ( ) ;
108
208
}
109
209
110
- onChange ( value ) {
111
- console . log ( 'CHANGE App' , '\n' , JSON . stringify ( value , null , 2 ) ) ;
112
- }
113
-
114
210
}
0 commit comments