Skip to content

Commit f504737

Browse files
author
Xie, Ziyu
committed
Pre-release v2.0.0-beta.1
Add events and methods
1 parent bbf96bb commit f504737

File tree

14 files changed

+321
-53
lines changed

14 files changed

+321
-53
lines changed

README.md

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ angular2-draggable has angular (ver >= 4.x) directives that make the DOM element
2121
+ `ngResizable`
2222

2323
# Latest Update
24+
+ 2018.06.26: 2.0.0-beta.1
25+
+ ngResizable: Provide `(rzStart)`, `(rzResizing)`, `(rzStop)` event emitters
26+
+ ngResizable: Provide `resetSize()`, `getStatus()` methods
27+
2428
+ 2018.06.25: 2.0.0-beta.0
2529
+ New: `ngResizable` directive which you can use to make the element resizable! More resizable options are planning. Refer to [demo](https://xieziyu.github.io/angular2-draggable/#/resizable/default)
2630

@@ -130,28 +134,25 @@ Well you can use both directives concurrently if you wish:
130134

131135
## Directive:
132136
+ `ngDraggable` directive support following input porperties:
133-
+ `ngDraggable`: boolean. You can toggle the draggable capability by setting `true`/`false` to `ngDraggable`
134-
135-
+ `handle`: HTMLElement. Use template variable to refer to the handle element. Then only the handle element is draggable.
136-
137-
+ `zIndex`: string. Use it to set z-index property when element is not moving.
138-
139-
+ `zIndexMoving`: string. Use it to set z-index property when element is moving.
140-
141-
+ `bounds`: HTMLElemnt. Use it to set the boundary.
142-
143-
+ `inBounds`: boolean, default is `false`. Use it make element stay in the bounds.
144137

145-
+ `outOfBounds`: { top: boolean; bottom: boolean; right: boolean; left: boolean }, default are `false`. Set it to allow element get out of bounds from the direction. Refer to [demo](https://xieziyu.github.io/angular2-draggable/#/usage/boundary)
146-
147-
+ `position`: IPosition: `{ x: number, y: number }`, default is `{ x:0, y:0 }`. Use it to set initial position offset.
148-
149-
+ `gridSize`: number, default is `1`. Use it for snapping to grid. Refer to [demo](https://xieziyu.github.io/angular2-draggable/#/advance/snap-grid).
138+
| Input | Type | Default | Description |
139+
| ----- | ---- | ------- | ----------- |
140+
| `ngDraggable` | boolean | `true` | You can toggle the draggable capability by setting `true` or `false` |
141+
| `handle` | HTMLElement | null | Use template variable to refer to the handle element. Then only the handle element is draggable |
142+
| `zIndex` | string | null | Use it to set z-index property when element is not moving |
143+
| `zIndexMoving` | string | null | Use it to set z-index property when element is moving |
144+
| `bounds` | HTMLElemnt | null | Use it to set the boundary |
145+
| `inBounds` | boolean | `false` | Use it make element stay in the bounds |
146+
| `outOfBounds` | `{ top: boolean; bottom: boolean; right: boolean; left: boolean }` | `false` | Set it to allow element get out of bounds from the direction. Refer to [demo](https://xieziyu.github.io/angular2-draggable/#/usage/boundary) |
147+
| `position` | `{ x: number, y: number }` | `{ x:0, y:0 }` | Use it to set position offset |
148+
| `gridSize` | number | 1 | Use it for snapping to grid. Refer to [demo](https://xieziyu.github.io/angular2-draggable/#/advance/snap-grid) |
150149

151150
+ `ngResizable` directive support following input porperties:
152-
+ `ngResizable`: boolean. You can disable the resizable capability by setting it to `false`.
153151

154-
+ `rzHandles`: Default is `"e,s,se"`. Which handles can be used for resizing. Optional types: `"n,e,s,w,se,sw,ne,nw"`.
152+
| Input | Type | Default | Description |
153+
| ----- | ---- | ------- | ----------- |
154+
| `ngResizable` | boolean | `true` | You can toggle the resizable capability by setting `true` or `false` |
155+
| `rzHandles` | string | `"e,s,se"` | Which handles can be used for resizing. Optional types in `"n,e,s,w,se,sw,ne,nw"` or `"all"` |
155156

156157
## CSS:
157158
+ When `ngDraggable` is enabled on some element, `ng-draggable` class is automatically assigned to it. You can use it to customize the pointer style. For example:
@@ -166,24 +167,58 @@ Well you can use both directives concurrently if you wish:
166167
167168
# Events
168169
+ `ngDraggable` directive:
169-
1. Support `started` and `stopped` events. The `nativeElement` of the host would be emitted.
170-
2. Support `edge` events only when `[bounds]` is set. It would emit the result of the boundary check.
171-
3. `(movingOffset)` event emitter: emit position offset when moving
172-
4. `(endOffset)` event emitter: emit position offset when stop moving
173170
174-
+ Simple example:
175-
+ html:
176-
```html
177-
<div ngDraggable
178-
(started)="onDragBegin($event)"
179-
(stopped)="onDragEnd($event)"
180-
(movingOffset)="onMoving($event)"
181-
(endOffset)="onMoveEnd($event)">
182-
Drag me!
183-
</div>
184-
```
171+
| Output | $event | Description |
172+
| ------ | ------ | ----------- |
173+
| `started` | `nativeElement` of host | emitted when start dragging |
174+
| `stopped` | `nativeElement` of host | emitted when stop dragging |
175+
| `edge` | { top: boolean, right: boolean, bottom: boolean, left: boolean } | emitted after `[bounds]` is set |
176+
| `movingOffset` | { x: number, y: number } | emit position offset when moving |
177+
| `endOffset` | { x: number, y: number } | emit position offset when stop moving |
178+
179+
Simple example:
180+
```html
181+
<div ngDraggable
182+
(started)="onDragBegin($event)"
183+
(stopped)="onDragEnd($event)"
184+
(movingOffset)="onMoving($event)"
185+
(endOffset)="onMoveEnd($event)">
186+
Drag me!
187+
</div>
188+
```
189+
190+
+ `ngResizable` directive:
191+
192+
| Output | $event | description |
193+
| ------ | ------ | ----------- |
194+
| `rzStart` | `IResizeEvent` | emitted when start resizing |
195+
| `rzResizing` | `IResizeEvent` | emitted when stop resizing |
196+
| `rzStop` | `IResizeEvent` | emitted when resizing |
185197
186-
+ `ngResizable` directive: on-going
198+
```typescript
199+
export interface IResizeEvent {
200+
host: any;
201+
handle: any;
202+
size: {
203+
width: number;
204+
height: number;
205+
};
206+
position: {
207+
top: number;
208+
left: number;
209+
};
210+
}
211+
```
212+
213+
Simple example:
214+
```html
215+
<div ngResizable
216+
(rzStart)="onResizeStart($event)"
217+
(rzResizing)="onResizing($event)"
218+
(rzStop)="onResizeStop($event)">
219+
Resizable
220+
</div>
221+
```
187222
188223
# Demo
189224
You can clone this repo to your working copy and then launch the demo page in your local machine:

angular.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
"prefix": "app",
1111
"schematics": {
1212
"@schematics/angular:component": {
13-
"styleext": "scss"
13+
"styleext": "scss",
14+
"spec": false
15+
},
16+
"@schematics/angular:service": {
17+
"spec": false
1418
}
1519
},
1620
"architect": {

projects/angular2-draggable/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular2-draggable",
3-
"version": "2.0.0-beta.0",
3+
"version": "2.0.0-beta.1",
44
"peerDependencies": {
55
"@angular/common": "^6.0.0-rc.0 || ^6.0.0",
66
"@angular/core": "^6.0.0-rc.0 || ^6.0.0"

projects/angular2-draggable/src/lib/angular-resizable.directive.ts

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,38 @@ import {
22
Directive, ElementRef, Renderer2,
33
Input, Output, OnInit, HostListener,
44
EventEmitter, OnChanges, SimpleChanges,
5-
OnDestroy
5+
OnDestroy, AfterViewInit
66
} from '@angular/core';
77

88
import { ResizeHandle } from './widgets/resize-handle';
99
import { ResizeHandleType } from './models/resize-handle-type';
1010
import { Position } from './models/position';
1111
import { Size } from './models/size';
12+
import { IResizeEvent } from './models/resize-event';
1213

1314
@Directive({
1415
selector: '[ngResizable]',
1516
exportAs: 'ngResizable'
1617
})
17-
export class AngularResizableDirective implements OnInit, OnChanges, OnDestroy {
18+
export class AngularResizableDirective implements OnInit, OnChanges, OnDestroy, AfterViewInit {
1819
private _resizable = true;
1920
private _handles: { [key: string]: ResizeHandle } = {};
2021
private _handleType: string[] = [];
2122
private _handleResizing: ResizeHandle = null;
2223
private _origMousePos: Position = null;
24+
25+
/** Original Size and Position */
2326
private _origSize: Size = null;
2427
private _origPos: Position = null;
2528

29+
/** Current Size and Position */
30+
private _currSize: Size = null;
31+
private _currPos: Position = null;
32+
33+
/** Initial Size and Position */
34+
private _initSize: Size = null;
35+
private _initPos: Position = null;
36+
2637
/** Disables the resizable if set to false. */
2738
@Input() set ngResizable(v: any) {
2839
if (v !== undefined && v !== null && v !== '') {
@@ -35,11 +46,20 @@ export class AngularResizableDirective implements OnInit, OnChanges, OnDestroy {
3546
* Which handles can be used for resizing.
3647
* @example
3748
* [rzHandles] = "'n,e,s,w,se,ne,sw,nw'"
38-
* [rzHandles] = { n: 'ng-resizable-n', e: 'ng-resizable-e' }
49+
* equals to: [rzHandles] = "'all'"
3950
*
4051
* */
4152
@Input() rzHandles: ResizeHandleType = 'e,s,se';
4253

54+
/** emitted when start resizing */
55+
@Output() rzStart = new EventEmitter<IResizeEvent>();
56+
57+
/** emitted when start resizing */
58+
@Output() rzResizing = new EventEmitter<IResizeEvent>();
59+
60+
/** emitted when stop resizing */
61+
@Output() rzStop = new EventEmitter<IResizeEvent>();
62+
4363
constructor(private el: ElementRef, private renderer: Renderer2) { }
4464

4565
ngOnChanges(changes: SimpleChanges) {
@@ -56,6 +76,39 @@ export class AngularResizableDirective implements OnInit, OnChanges, OnDestroy {
5676
this.removeHandles();
5777
}
5878

79+
ngAfterViewInit() {
80+
const elm = this.el.nativeElement;
81+
this._initSize = Size.getCurrent(elm);
82+
this._initPos = Position.getCurrent(elm);
83+
this._currSize = Size.copy(this._initSize);
84+
this._currPos = Position.copy(this._initPos);
85+
}
86+
87+
/** A method to reset size */
88+
public resetSize() {
89+
this._currSize = Size.copy(this._initSize);
90+
this._currPos = Position.copy(this._initPos);
91+
this.doResize();
92+
}
93+
94+
/** A method to reset size */
95+
public getStatus() {
96+
if (!this._currPos || !this._currSize) {
97+
return null;
98+
}
99+
100+
return {
101+
size: {
102+
width: this._currSize.width,
103+
height: this._currSize.height
104+
},
105+
position: {
106+
top: this._currPos.y,
107+
left: this._currPos.x
108+
}
109+
};
110+
}
111+
59112
private updateResizable() {
60113
const element = this.el.nativeElement;
61114

@@ -78,7 +131,12 @@ export class AngularResizableDirective implements OnInit, OnChanges, OnDestroy {
78131

79132
let tmpHandleTypes: string[];
80133
if (typeof this.rzHandles === 'string') {
81-
tmpHandleTypes = this.rzHandles.replace(/ /g, '').toLowerCase().split(',');
134+
if (this.rzHandles === 'all') {
135+
tmpHandleTypes = ['n', 'e', 's', 'w', 'ne', 'se', 'nw', 'sw'];
136+
} else {
137+
tmpHandleTypes = this.rzHandles.replace(/ /g, '').toLowerCase().split(',');
138+
}
139+
82140
for (let type of tmpHandleTypes) {
83141
// default handle theme: ng-resizable-$type.
84142
let handle = this.createHandleByType(type, `ng-resizable-${type}`);
@@ -137,6 +195,8 @@ export class AngularResizableDirective implements OnInit, OnChanges, OnDestroy {
137195
this._origMousePos = Position.fromEvent(event);
138196
this._origSize = Size.getCurrent(elm);
139197
this._origPos = Position.getCurrent(elm); // x: left, y: top
198+
this._currSize = Size.copy(this._origSize);
199+
this._currPos = Position.copy(this._origPos);
140200
this.startResize(handle);
141201
}
142202
}
@@ -159,37 +219,68 @@ export class AngularResizableDirective implements OnInit, OnChanges, OnDestroy {
159219
onMouseMove(event: MouseEvent | TouchEvent) {
160220
if (this._handleResizing && this._resizable && this._origMousePos && this._origPos && this._origSize) {
161221
this.resizeTo(Position.fromEvent(event));
222+
this.onResizing();
162223
}
163224
}
164225

165-
startResize(handle: ResizeHandle) {
226+
private startResize(handle: ResizeHandle) {
166227
this._handleResizing = handle;
228+
this.rzStart.emit(this.getResizingEvent());
167229
}
168230

169-
stopResize() {
231+
private stopResize() {
232+
this.rzStop.emit(this.getResizingEvent());
170233
this._handleResizing = null;
171234
}
172235

173-
resizeTo(p: Position) {
174-
const container = this.el.nativeElement;
236+
private onResizing() {
237+
this.rzResizing.emit(this.getResizingEvent());
238+
}
239+
240+
private getResizingEvent(): IResizeEvent {
241+
return {
242+
host: this.el.nativeElement,
243+
handle: this._handleResizing ? this._handleResizing.el : null,
244+
size: {
245+
width: this._currSize.width,
246+
height: this._currSize.height
247+
},
248+
position: {
249+
top: this._currPos.y,
250+
left: this._currPos.x
251+
}
252+
};
253+
}
254+
255+
private resizeTo(p: Position) {
175256
p.subtract(this._origMousePos);
176257

177258
if (this._handleResizing.type.match(/n/)) {
178259
// n, ne, nw
179-
this.renderer.setStyle(container, 'height', (this._origSize.height - p.y) + 'px');
180-
this.renderer.setStyle(container, 'top', (this._origPos.y + p.y) + 'px');
260+
this._currSize.height = this._origSize.height - p.y;
261+
this._currPos.y = this._origPos.y + p.y;
181262
} else if (this._handleResizing.type.match(/s/)) {
182263
// s, se, sw
183-
this.renderer.setStyle(container, 'height', (this._origSize.height + p.y) + 'px');
264+
this._currSize.height = this._origSize.height + p.y;
184265
}
185266

186267
if (this._handleResizing.type.match(/e/)) {
187268
// e, ne, se
188-
this.renderer.setStyle(container, 'width', (this._origSize.width + p.x) + 'px');
269+
this._currSize.width = this._origSize.width + p.x;
189270
} else if (this._handleResizing.type.match(/w/)) {
190271
// w, nw, sw
191-
this.renderer.setStyle(container, 'width', (this._origSize.width - p.x) + 'px');
192-
this.renderer.setStyle(container, 'left', (this._origPos.x + p.x) + 'px');
272+
this._currSize.width = this._origSize.width - p.x;
273+
this._currPos.x = this._origPos.x + p.x;
193274
}
275+
276+
this.doResize();
277+
}
278+
279+
private doResize() {
280+
const container = this.el.nativeElement;
281+
this.renderer.setStyle(container, 'height', this._currSize.height + 'px');
282+
this.renderer.setStyle(container, 'width', this._currSize.width + 'px');
283+
this.renderer.setStyle(container, 'left', this._currPos.x + 'px');
284+
this.renderer.setStyle(container, 'top', this._currPos.y + 'px');
194285
}
195286
}

projects/angular2-draggable/src/lib/models/position.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export class Position implements IPosition {
3434
}
3535
}
3636

37+
static copy(p: Position) {
38+
return new Position(0, 0).set(p);
39+
}
40+
3741
add(p: IPosition) {
3842
this.x += p.x;
3943
this.y += p.y;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { ISize } from './size';
2+
3+
export interface IResizeEvent {
4+
host: any;
5+
handle: any;
6+
size: ISize;
7+
position: {
8+
top: number;
9+
left: number;
10+
};
11+
}

projects/angular2-draggable/src/lib/models/size.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,14 @@ export class Size implements ISize {
2121
return null;
2222
}
2323
}
24+
25+
static copy(s: Size) {
26+
return new Size(0, 0).set(s);
27+
}
28+
29+
set(s: ISize) {
30+
this.width = s.width;
31+
this.height = s.height;
32+
return this;
33+
}
2434
}

0 commit comments

Comments
 (0)