@leafer-ui/interaction 1.0.0-rc.17 → 1.0.0-rc.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer-ui/interaction",
3
- "version": "1.0.0-rc.17",
3
+ "version": "1.0.0-rc.19",
4
4
  "description": "@leafer-ui/interaction",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -22,10 +22,11 @@
22
22
  "leaferjs"
23
23
  ],
24
24
  "dependencies": {
25
- "@leafer/core": "1.0.0-rc.17",
26
- "@leafer-ui/event": "1.0.0-rc.17"
25
+ "@leafer/core": "1.0.0-rc.19",
26
+ "@leafer-ui/draw": "1.0.0-rc.19",
27
+ "@leafer-ui/event": "1.0.0-rc.19"
27
28
  },
28
29
  "devDependencies": {
29
- "@leafer/interface": "1.0.0-rc.17"
30
+ "@leafer/interface": "1.0.0-rc.19"
30
31
  }
31
32
  }
package/src/Dragger.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IPointerEvent, IDragEvent, ILeaf, ILeafList, ITimer, IFunction } from '@leafer/interface'
2
- import { BoundsHelper, PointHelper, LeafHelper, LeafList } from '@leafer/core'
2
+ import { BoundsHelper, PointHelper, LeafList } from '@leafer/core'
3
3
 
4
4
  import { MoveEvent, DragEvent, DropEvent, PointerButton } from '@leafer-ui/event'
5
5
 
@@ -26,7 +26,8 @@ export class Dragger {
26
26
 
27
27
  protected autoMoveTimer: ITimer
28
28
 
29
- protected canAnimate: boolean
29
+ public canAnimate: boolean
30
+ public canDragOut: boolean
30
31
  protected animateWait: IFunction
31
32
 
32
33
  constructor(interaction: InteractionBase) {
@@ -37,6 +38,7 @@ export class Dragger {
37
38
  if (this.animateWait) this.dragEndReal()
38
39
  this.downData = this.interaction.downData
39
40
  this.dragData = getDragEventData(data, data, data)
41
+ this.canAnimate = this.canDragOut = true
40
42
  }
41
43
 
42
44
  public getList(): ILeafList {
@@ -51,12 +53,10 @@ export class Dragger {
51
53
  this.canAnimate = false // 防止dragEnd动画
52
54
  interaction.pointerCancel() // 按住中键/右键拖出页面后的up事件接收不到
53
55
  return
54
- } else {
55
- this.canAnimate = true
56
56
  }
57
57
 
58
58
  if (!this.moving && canDrag) {
59
- if (this.moving = interaction.moveMode || interaction.isHoldRightKey) interaction.emit(MoveEvent.START, this.dragData)
59
+ if (this.moving = interaction.canMove(this.downData) || interaction.isHoldRightKey) interaction.emit(MoveEvent.START, this.dragData)
60
60
  }
61
61
 
62
62
  if (!this.moving) {
@@ -109,7 +109,7 @@ export class Dragger {
109
109
  const list = this.getList()
110
110
  if (list.length && running) {
111
111
  const { moveX, moveY } = this.dragData
112
- list.forEach(leaf => LeafHelper.moveWorld(leaf, moveX, moveY))
112
+ list.forEach(leaf => leaf.moveWorld(moveX, moveY))
113
113
  }
114
114
  }
115
115
 
@@ -117,6 +117,7 @@ export class Dragger {
117
117
  const { interaction } = this
118
118
  const { dragOverPath } = this
119
119
  const { path } = data
120
+ this.dragOverPath = path
120
121
 
121
122
  if (dragOverPath) {
122
123
  if (path.indexAt(0) !== dragOverPath.indexAt(0)) {
@@ -126,7 +127,7 @@ export class Dragger {
126
127
  } else {
127
128
  interaction.emit(DragEvent.OVER, data, path)
128
129
  }
129
- this.dragOverPath = path
130
+
130
131
  }
131
132
 
132
133
  public dragEnterOrLeave(data: IPointerEvent): void {
@@ -143,7 +144,7 @@ export class Dragger {
143
144
  if (!this.dragData) return
144
145
 
145
146
  const { moveX, moveY } = this.dragData
146
- if (this.canAnimate && this.moving && (Math.abs(moveX) > 1 || Math.abs(moveY) > 1)) {
147
+ if (this.interaction.config.move.dragAnimate && this.canAnimate && this.moving && (Math.abs(moveX) > 1 || Math.abs(moveY) > 1)) {
147
148
  data = { ...data }
148
149
  speed = (speed || (data.pointerType === 'touch' ? 2 : 1)) * 0.9
149
150
  PointHelper.move(data, moveX * speed, moveY * speed)
@@ -179,14 +180,13 @@ export class Dragger {
179
180
 
180
181
  protected animate(func?: IFunction, off?: 'off'): void { // dragEnd animation
181
182
  const animateWait = func || this.animateWait
182
- if (animateWait) this.interaction.target.nextRender(animateWait, off)
183
+ if (animateWait) this.interaction.target.nextRender(animateWait, null, off)
183
184
  this.animateWait = func
184
185
  }
185
186
 
186
187
 
187
188
  protected swipe(data: IPointerEvent, endDragData: IDragEvent): void {
188
- const { interaction } = this
189
- const { downData } = interaction
189
+ const { interaction, downData } = this
190
190
  if (PointHelper.getDistance(downData, data) > interaction.config.pointer.swipeDistance) {
191
191
  const swipeData = getSwipeEventData(downData, this.dragData, endDragData)
192
192
  this.interaction.emit(swipeData.type, swipeData)
@@ -214,9 +214,9 @@ export class Dragger {
214
214
 
215
215
 
216
216
  protected autoMoveOnDragOut(data: IPointerEvent): void {
217
- const { interaction, downData } = this
217
+ const { interaction, downData, canDragOut } = this
218
218
  const { autoDistance, dragOut } = interaction.config.move
219
- if (!dragOut || !autoDistance) return
219
+ if (!dragOut || !canDragOut || !autoDistance) return
220
220
 
221
221
  const bounds = interaction.shrinkCanvasBounds
222
222
  const { x, y } = bounds
@@ -21,7 +21,7 @@ export class InteractionBase implements IInteraction {
21
21
  public running: boolean
22
22
 
23
23
  public get dragging(): boolean { return this.dragger.dragging }
24
- public get isDragEmpty(): boolean { return this.config.move.dragEmpty && (this.hoverData && (this.hoverData.path.list[0] as ILeaf).isLeafer) && (!this.downData || (this.downData.path.list[0] as ILeaf).isLeafer) }
24
+ public get isDragEmpty(): boolean { return this.config.move.dragEmpty && this.isRootPath(this.hoverData) && (!this.downData || this.isRootPath(this.downData)) }
25
25
  public get isHoldRightKey(): boolean { return this.config.move.holdRightKey && this.downData && PointerButton.right(this.downData) }
26
26
  public get moveMode(): boolean { return this.config.move.drag || (this.config.move.holdSpaceKey && Keyboard.isHoldSpaceKey()) || (this.downData && ((this.config.move.holdMiddleKey && PointerButton.middle(this.downData)) || (this.isHoldRightKey && this.dragger.moving))) || this.isDragEmpty }
27
27
 
@@ -33,10 +33,11 @@ export class InteractionBase implements IInteraction {
33
33
  public shrinkCanvasBounds: IBounds
34
34
 
35
35
  public downData: IPointerEvent
36
- protected oldDownData?: IPointerEvent // 通过updateDownData强制更新下来的数据
37
36
  public hoverData: IPointerEvent
37
+ public focusData: ILeaf
38
38
 
39
39
  public downTime: number
40
+
40
41
  protected overPath: LeafList
41
42
  protected enterPath: LeafList
42
43
 
@@ -87,14 +88,12 @@ export class InteractionBase implements IInteraction {
87
88
  PointerButton.defaultLeft(data)
88
89
 
89
90
  this.updateDownData(data)
90
- if (useDefaultPath) data.path = this.defaultPath
91
-
92
- this.emit(PointerEvent.BEFORE_DOWN, data)
93
- this.emit(PointerEvent.DOWN, data)
91
+ this.checkPath(data, useDefaultPath)
94
92
 
95
93
  this.downTime = Date.now()
96
94
 
97
- this.dragger.setDragData(data)
95
+ this.emit(PointerEvent.BEFORE_DOWN, data) // downData maybe changed
96
+ this.emit(PointerEvent.DOWN, data)
98
97
 
99
98
  if (PointerButton.left(data)) {
100
99
  this.tapWait()
@@ -103,19 +102,21 @@ export class InteractionBase implements IInteraction {
103
102
  this.waitMenuTap = true
104
103
  }
105
104
 
105
+ this.dragger.setDragData(data) // must after down event
106
106
  this.updateCursor(data)
107
107
  }
108
108
 
109
109
  public pointerMove(data?: IPointerEvent): void {
110
110
  if (!data) data = this.hoverData
111
111
  if (!data) return
112
- if (this.downData) PointerButton.defaultLeft(data)
112
+
113
+ const { downData } = this
114
+ if (downData) PointerButton.defaultLeft(data)
113
115
 
114
116
  const hit = this.canvas.bounds.hitPoint(data)
115
- if (hit || this.downData) {
116
- if (hit && !this.downData && PointerButton.left(data)) this.pointerDown(data, true) // 从外部拖拽内容进入,需要先模拟down事件
117
+ if (hit || downData) {
117
118
  this.pointerMoveReal(data)
118
- this.dragger.checkDragOut(data)
119
+ if (downData) this.dragger.checkDragOut(data)
119
120
  }
120
121
  }
121
122
 
@@ -134,10 +135,12 @@ export class InteractionBase implements IInteraction {
134
135
 
135
136
  if (!this.dragger.moving) {
136
137
  this.updateHoverData(data)
138
+ this.checkPath(data)
139
+
137
140
  this.emit(PointerEvent.MOVE, data)
138
141
 
139
- this.pointerOverOrOut(data)
140
- this.pointerEnterOrLeave(data)
142
+ if (!(this.dragging && !this.config.pointer.dragHover)) this.pointerHover(data)
143
+
141
144
  if (this.dragger.dragging) {
142
145
  this.dragger.dragOverOrOut(data)
143
146
  this.dragger.dragEnterOrLeave(data)
@@ -148,16 +151,19 @@ export class InteractionBase implements IInteraction {
148
151
  }
149
152
 
150
153
  public pointerUp(data?: IPointerEvent): void {
151
- if (!data) data = this.downData
152
- if (!this.downData) return
154
+ const { downData } = this
155
+ if (!data) data = downData
156
+ if (!downData) return
157
+
153
158
  PointerButton.defaultLeft(data)
159
+ this.downData = null // must before pointer.up event
154
160
 
155
161
  this.findPath(data)
162
+ data.path.addList(downData.path.list) // downPath必须触发
163
+ this.checkPath(data)
156
164
 
157
165
  this.emit(PointerEvent.BEFORE_UP, data)
158
166
  this.emit(PointerEvent.UP, data)
159
- if (this.oldDownData) this.emit(PointerEvent.UP, this.oldDownData, undefined, data.path) // oldDownPath必须触发up
160
- this.emit(PointerEvent.UP, this.downData, undefined, data.path) // downPath必须触发up
161
167
 
162
168
  this.touchLeave(data)
163
169
 
@@ -166,8 +172,6 @@ export class InteractionBase implements IInteraction {
166
172
 
167
173
  this.dragger.dragEnd(data)
168
174
 
169
- this.downData = this.oldDownData = null
170
-
171
175
  this.updateCursor(data)
172
176
  }
173
177
 
@@ -222,7 +226,10 @@ export class InteractionBase implements IInteraction {
222
226
  Keyboard.setDownCode(code)
223
227
 
224
228
  this.emit(KeyEvent.HOLD, data, this.defaultPath)
225
- if (this.moveMode) this.updateCursor()
229
+ if (this.moveMode) {
230
+ this.cancelHover()
231
+ this.updateCursor()
232
+ }
226
233
  }
227
234
  this.emit(KeyEvent.DOWN, data, this.defaultPath)
228
235
  }
@@ -238,30 +245,39 @@ export class InteractionBase implements IInteraction {
238
245
 
239
246
 
240
247
  // helper
241
- protected pointerOverOrOut(data: IPointerEvent): void {
242
- if (this.dragger.moving) return
243
- if (this.dragging && !this.config.pointer.dragHover) return
248
+ protected pointerHover(data: IPointerEvent): void {
249
+ this.pointerOverOrOut(data)
250
+ this.pointerEnterOrLeave(data)
251
+ }
244
252
 
253
+ protected pointerOverOrOut(data: IPointerEvent): void {
245
254
  const { path } = data
246
- if (this.overPath) {
247
- if (path.indexAt(0) !== this.overPath.indexAt(0)) {
248
- this.emit(PointerEvent.OUT, data, this.overPath)
255
+ const { overPath } = this
256
+ this.overPath = path
257
+
258
+ if (overPath) {
259
+ if (path.indexAt(0) !== overPath.indexAt(0)) {
260
+ this.emit(PointerEvent.OUT, data, overPath)
249
261
  this.emit(PointerEvent.OVER, data, path)
250
262
  }
251
263
  } else {
252
264
  this.emit(PointerEvent.OVER, data, path)
253
265
  }
254
- this.overPath = path
255
266
  }
256
267
 
257
268
  protected pointerEnterOrLeave(data: IPointerEvent): void {
258
- if (this.dragger.moving) return
259
- if (this.dragging && !this.config.pointer.dragHover) return
269
+ let { path } = data
260
270
 
261
- const { path } = data
262
- this.emit(PointerEvent.LEAVE, data, this.enterPath, path)
263
- this.emit(PointerEvent.ENTER, data, path, this.enterPath)
271
+ if (this.downData && !this.moveMode) {
272
+ path = path.clone()
273
+ this.downData.path.forEach(leaf => path.add(leaf))
274
+ }
275
+
276
+ const { enterPath } = this
264
277
  this.enterPath = path
278
+
279
+ this.emit(PointerEvent.LEAVE, data, enterPath, path)
280
+ this.emit(PointerEvent.ENTER, data, path, enterPath)
265
281
  }
266
282
 
267
283
  protected touchLeave(data: IPointerEvent): void {
@@ -321,16 +337,51 @@ export class InteractionBase implements IInteraction {
321
337
  return find.path
322
338
  }
323
339
 
340
+ public isRootPath(data: IPointerEvent): boolean {
341
+ return data && (data.path.list[0] as ILeaf).isLeafer
342
+ }
343
+
344
+ protected checkPath(data: IPointerEvent, useDefaultPath?: boolean): void {
345
+ if (useDefaultPath || this.canMove(data)) data.path = this.defaultPath
346
+ }
347
+
348
+ public canMove(data: IPointerEvent): boolean { // moveMode and path can move
349
+ return this.moveMode && data && data.path.list.every(item => !item.isOutside)
350
+ }
351
+
352
+
324
353
  public isDrag(leaf: ILeaf): boolean {
325
354
  return this.dragger.getList().has(leaf)
326
355
  }
327
356
 
328
- public updateDownData(data?: IPointerEvent, options?: IPickOptions): void {
357
+ public isPress(leaf: ILeaf): boolean {
358
+ return this.downData && this.downData.path.has(leaf)
359
+ }
360
+
361
+ public isHover(leaf: ILeaf): boolean {
362
+ return this.enterPath && this.enterPath.has(leaf)
363
+ }
364
+
365
+ public isFocus(leaf: ILeaf): boolean {
366
+ return this.focusData === leaf
367
+ }
368
+
369
+
370
+ public cancelHover(): void {
371
+ const { hoverData } = this
372
+ if (hoverData) {
373
+ hoverData.path = this.defaultPath
374
+ this.pointerHover(hoverData)
375
+ }
376
+ }
377
+
378
+
379
+ public updateDownData(data?: IPointerEvent, options?: IPickOptions, merge?: boolean): void {
329
380
  const { downData } = this
330
- if (!data && downData) data = { ...downData }
381
+ if (!data && downData) data = downData
331
382
  if (!data) return
332
- this.oldDownData = downData
333
383
  this.findPath(data, options)
384
+ if (merge && downData) data.path.addList(downData.path.list)
334
385
  this.downData = data
335
386
  }
336
387
 
@@ -351,12 +402,11 @@ export class InteractionBase implements IInteraction {
351
402
 
352
403
  if (this.dragger.moving) {
353
404
  return this.setCursor('grabbing')
354
- } else if (this.moveMode) {
405
+ } else if (this.canMove(data)) {
355
406
  return this.setCursor(this.downData ? 'grabbing' : 'grab')
356
407
  } else if (!data) return
357
408
 
358
- let leaf: ILeaf
359
- let cursor: ICursorType | ICursorType[]
409
+ let leaf: ILeaf, cursor: ICursorType | ICursorType[]
360
410
 
361
411
  const { path } = data
362
412
  for (let i = 0, len = path.length; i < len; i++) {
@@ -372,6 +422,7 @@ export class InteractionBase implements IInteraction {
372
422
  this.cursor = cursor
373
423
  }
374
424
 
425
+
375
426
  protected emitTap(data: IPointerEvent) {
376
427
  this.emit(PointerEvent.TAP, data)
377
428
  this.emit(PointerEvent.CLICK, data)
@@ -23,6 +23,7 @@ export class Transformer {
23
23
  const { path } = interaction.selector.getByPoint(data, interaction.hitRadius)
24
24
  data.path = path
25
25
  this.moveData = { ...data, moveX: 0, moveY: 0 }
26
+ interaction.cancelHover()
26
27
  interaction.emit(MoveEvent.START, this.moveData)
27
28
  }
28
29
 
@@ -40,6 +41,7 @@ export class Transformer {
40
41
  const { path } = interaction.selector.getByPoint(data, interaction.hitRadius)
41
42
  data.path = path
42
43
  this.zoomData = { ...data, scale: 1 }
44
+ interaction.cancelHover()
43
45
  interaction.emit(ZoomEvent.START, this.zoomData)
44
46
  }
45
47
 
@@ -57,6 +59,7 @@ export class Transformer {
57
59
  const { path } = interaction.selector.getByPoint(data, interaction.hitRadius)
58
60
  data.path = path
59
61
  this.rotateData = { ...data, rotation: 0 }
62
+ interaction.cancelHover()
60
63
  interaction.emit(RotateEvent.START, this.rotateData)
61
64
  }
62
65
 
package/src/config.ts CHANGED
@@ -2,7 +2,6 @@ import { IInteractionConfig } from '@leafer/interface'
2
2
 
3
3
  export const config: IInteractionConfig = {
4
4
  wheel: {
5
- zoomMode: false,
6
5
  zoomSpeed: 0.5,
7
6
  moveSpeed: 0.5,
8
7
  rotateSpeed: 0.5,
@@ -11,14 +10,12 @@ export const config: IInteractionConfig = {
11
10
  },
12
11
  pointer: {
13
12
  hitRadius: 5,
14
- through: false,
15
13
  tapTime: 120,
16
14
  longPressTime: 800,
17
15
  transformTime: 500,
18
16
  dragHover: true,
19
17
  dragDistance: 2,
20
18
  swipeDistance: 20,
21
- ignoreMove: false,
22
19
  preventDefaultMenu: true
23
20
  },
24
21
  cursor: {}
package/src/emit.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { IUIEvent, ILeaf, ILeafList } from '@leafer/interface'
2
2
  import { EventCreator, Debug } from '@leafer/core'
3
+ import { State } from '@leafer-ui/draw'
4
+
3
5
 
4
6
  const debug = Debug.get('emit')
5
7
 
@@ -50,11 +52,16 @@ function emitAppChildren(leaf: ILeaf, type: string, data: IUIEvent, capture?: bo
50
52
 
51
53
  function emitEvent(leaf: ILeaf, type: string, data: IUIEvent, capture?: boolean, excludePath?: ILeafList): boolean {
52
54
  if (leaf.destroyed) return true
53
- if (leaf.__.hitSelf && leaf.hasEvent(type, capture) && !exclude(leaf, excludePath)) {
54
- data.phase = capture ? 1 : ((leaf === data.target) ? 2 : 3)
55
- const event = EventCreator.get(type, data)
56
- leaf.emitEvent(event, capture)
57
- if (event.isStop) return true
55
+ if (leaf.__.hitSelf && !exclude(leaf, excludePath)) {
56
+
57
+ if (State.updateEventStyle) State.updateEventStyle(leaf, type) // hoverStyle / pressStyle
58
+
59
+ if (leaf.hasEvent(type, capture)) {
60
+ data.phase = capture ? 1 : ((leaf === data.target) ? 2 : 3)
61
+ const event = EventCreator.get(type, data)
62
+ leaf.emitEvent(event, capture)
63
+ if (event.isStop) return true
64
+ }
58
65
  }
59
66
  return false
60
67
  }
package/types/index.d.ts CHANGED
@@ -29,7 +29,8 @@ declare class Dragger {
29
29
  protected dragOverPath: ILeafList;
30
30
  protected dragEnterPath: ILeafList;
31
31
  protected autoMoveTimer: ITimer;
32
- protected canAnimate: boolean;
32
+ canAnimate: boolean;
33
+ canDragOut: boolean;
33
34
  protected animateWait: IFunction;
34
35
  constructor(interaction: InteractionBase);
35
36
  setDragData(data: IPointerEvent): void;
@@ -67,8 +68,8 @@ declare class InteractionBase implements IInteraction {
67
68
  get hitRadius(): number;
68
69
  shrinkCanvasBounds: IBounds;
69
70
  downData: IPointerEvent;
70
- protected oldDownData?: IPointerEvent;
71
71
  hoverData: IPointerEvent;
72
+ focusData: ILeaf;
72
73
  downTime: number;
73
74
  protected overPath: LeafList;
74
75
  protected enterPath: LeafList;
@@ -101,13 +102,21 @@ declare class InteractionBase implements IInteraction {
101
102
  transformEnd(): void;
102
103
  keyDown(data: IKeyEvent): void;
103
104
  keyUp(data: IKeyEvent): void;
105
+ protected pointerHover(data: IPointerEvent): void;
104
106
  protected pointerOverOrOut(data: IPointerEvent): void;
105
107
  protected pointerEnterOrLeave(data: IPointerEvent): void;
106
108
  protected touchLeave(data: IPointerEvent): void;
107
109
  protected tap(data: IPointerEvent): void;
108
110
  findPath(data: IPointerEvent, options?: IPickOptions): ILeafList;
111
+ isRootPath(data: IPointerEvent): boolean;
112
+ protected checkPath(data: IPointerEvent, useDefaultPath?: boolean): void;
113
+ canMove(data: IPointerEvent): boolean;
109
114
  isDrag(leaf: ILeaf): boolean;
110
- updateDownData(data?: IPointerEvent, options?: IPickOptions): void;
115
+ isPress(leaf: ILeaf): boolean;
116
+ isHover(leaf: ILeaf): boolean;
117
+ isFocus(leaf: ILeaf): boolean;
118
+ cancelHover(): void;
119
+ updateDownData(data?: IPointerEvent, options?: IPickOptions, merge?: boolean): void;
111
120
  updateHoverData(data?: IPointerEvent): void;
112
121
  updateCursor(data?: IPointerEvent): void;
113
122
  setCursor(cursor: ICursorType | ICursorType[]): void;