w-flow-vue 1.0.21 → 1.0.23

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.
@@ -121,6 +121,7 @@
121
121
  :snap-grid-size="snapToGrid ? snapGridSize : null"
122
122
  :settings-enabled="nodesSettingsEnabled"
123
123
  :settings-excludes="nodesSettingsExcludes"
124
+ @drag-prepare="onNodeDragPrepare"
124
125
  @drag-start="onNodeDragStart"
125
126
  @node-click="onNodeClick"
126
127
  @node-double-click="onNodeDoubleClick"
@@ -424,6 +425,7 @@ export default {
424
425
  document.addEventListener('keyup', this.onKeyUp)
425
426
  document.addEventListener('mousemove', this.onDocMouseMove)
426
427
  document.addEventListener('mouseup', this.onDocMouseUp)
428
+ window.addEventListener('blur', this.onWindowBlur)
427
429
  },
428
430
  beforeDestroy() {
429
431
  if (this._panAnimId) {
@@ -434,6 +436,7 @@ export default {
434
436
  document.removeEventListener('keyup', this.onKeyUp)
435
437
  document.removeEventListener('mousemove', this.onDocMouseMove)
436
438
  document.removeEventListener('mouseup', this.onDocMouseUp)
439
+ window.removeEventListener('blur', this.onWindowBlur)
437
440
  },
438
441
  computed: {
439
442
  widthInp() {
@@ -813,6 +816,8 @@ export default {
813
816
  },
814
817
  onCanvasWheel(event) {
815
818
  if (!this.zoomOnScroll) return
819
+ //滾輪縮放亦為viewport寫入者, 先取消程式動畫避免二者互相覆寫
820
+ this.cancelViewportAnimation()
816
821
  const delta = -event.deltaY * 0.001
817
822
  const currentZoom = this.viewport.zoom
818
823
  // fitView may set zoom below zoomMin; use the current level as the
@@ -836,6 +841,14 @@ export default {
836
841
 
837
842
  // --- Document-level mouse ---
838
843
  onDocMouseMove(event) {
844
+ //按鍵已放開卻仍處於進行中狀態: 代表收尾事件未送達(於瀏覽器視窗外放開/視窗失焦/手勢被原生拖曳接管),
845
+ //此時須主動走既有收尾路徑清除狀態; 只return不清狀態無效, 旗標續留為真下次移動仍會誤判
846
+ if ((event.buttons & 1) === 0) {
847
+ if (this.isPanning || this.isDraggingNode || this.isConnecting || this.isSelecting) {
848
+ this.onDocMouseUp(event)
849
+ }
850
+ return
851
+ }
839
852
  if (this.isPanning) {
840
853
  this.doPan(event)
841
854
  }
@@ -849,6 +862,19 @@ export default {
849
862
  this.doSelection(event)
850
863
  }
851
864
  },
865
+ onWindowBlur(event) {
866
+ //視窗失焦後不會再收到mouseup與keyup, 於此統一收尾避免狀態黏住
867
+ if (this.isPanning) {
868
+ this.endPan()
869
+ }
870
+ //節點拖曳同樣須收尾: 否則isDraggingNode殘留為true, 回到視窗後在觸發mousemove守衛前
871
+ //點擊其他節點, 該次node-click會被onNodeClick之拖曳守衛以過期狀態誤擋
872
+ //event為blur事件(非MouseEvent), endDrag不讀取座標僅原樣轉交node-drag-stop, 故不偽造mouseup
873
+ if (this.isDraggingNode) {
874
+ this.endDrag(event)
875
+ }
876
+ this.keysPressed = {}
877
+ },
852
878
  onDocMouseUp(event) {
853
879
  if (this.isPanning) {
854
880
  this.endPan()
@@ -866,6 +892,8 @@ export default {
866
892
 
867
893
  // --- Pan ---
868
894
  startPan(event) {
895
+ //手動平移優先於程式動畫, 否則二者同時寫viewport而互相覆寫
896
+ this.cancelViewportAnimation()
869
897
  this.isPanning = true
870
898
  this.panStartPos = { x: event.clientX, y: event.clientY }
871
899
  },
@@ -893,16 +921,20 @@ export default {
893
921
  },
894
922
 
895
923
  // --- Node drag ---
896
- onNodeDragStart({ node, event }) {
924
+ //於節點mousedown當下先行選取(拖曳本身延後至跨越位移門檻才由onNodeDragStart啟動)。
925
+ //守衛與選取條件皆與修正前之onNodeDragStart一致, 故選取時機不因拖曳延後而改變。
926
+ onNodeDragPrepare({ node }) {
897
927
  if (this.locked || !this.nodesDraggable) return
898
- this.isDraggingNode = true
899
- this.draggingNodeId = node.id
900
- this.dragStartPos = { x: event.clientX, y: event.clientY }
901
-
902
928
  if (this.selectNodesOnDrag && !this.isMultiSelectPressed) {
903
929
  this.setSelectedNodes([node.id])
904
930
  this.setSelectedConns([])
905
931
  }
932
+ },
933
+ onNodeDragStart({ node, event, moveEvent }) {
934
+ if (this.locked || !this.nodesDraggable) return
935
+ this.isDraggingNode = true
936
+ this.draggingNodeId = node.id
937
+ this.dragStartPos = { x: event.clientX, y: event.clientY }
906
938
 
907
939
  // Cache start positions for drag
908
940
  const starts = {}
@@ -925,6 +957,12 @@ export default {
925
957
  }
926
958
 
927
959
  this.$emit('node-drag-start', { node, event })
960
+
961
+ //立即套用跨門檻的這一次mousemove: document層之onDocMouseMove於本輪事件已先看過
962
+ //(當時isDraggingNode仍為false而返回), 不補這一次則跨門檻後立刻放開將完全沒有位移
963
+ if (moveEvent && this.isDraggingNode) {
964
+ this.doDrag(moveEvent)
965
+ }
928
966
  },
929
967
  doDrag(event) {
930
968
  const zoom = this.viewport.zoom
@@ -1061,6 +1099,10 @@ export default {
1061
1099
 
1062
1100
  // --- Selection ---
1063
1101
  onNodeClick({ node, event }) {
1102
+ //本次手勢已被接受為拖曳者不再視為點擊: NodeWrapper之@mouseup綁在節點元素上,
1103
+ //必先於document層之onDocMouseUp→endDrag觸發, 故此刻isDraggingNode仍為true即代表拖曳成立。
1104
+ //(涵蓋「跨門檻拖出後又移回原點放開」之情形——該情形最終位移為0, 僅靠距離判準無法辨識)
1105
+ if (this.isDraggingNode) return
1064
1106
  if (!this.elementsSelectable) return
1065
1107
  if (this.isMultiSelectPressed) {
1066
1108
  const idx = this.selectedNodes.indexOf(node.id)
@@ -1299,6 +1341,19 @@ export default {
1299
1341
  emitViewportChange() {
1300
1342
  this.$emit('viewport-change', { ...this.viewport })
1301
1343
  },
1344
+ getViewport() {
1345
+ //即時視口: viewport-change僅於手勢結束才發出, 平移途中呼叫端需要當下值時走此方法
1346
+ //(呼叫端若以viewport-change快取之值為基準回寫setViewport, 會於平移途中以過期值覆寫使用者正在進行的平移)
1347
+ let vp = this.viewport
1348
+ return { x: vp.x, y: vp.y, zoom: vp.zoom }
1349
+ },
1350
+ cancelViewportAnimation() {
1351
+ //取消進行中之視口動畫(panToNode), 否則動畫與手動手勢會同時寫入同一個viewport
1352
+ if (this._panAnimId) {
1353
+ cancelAnimationFrame(this._panAnimId)
1354
+ this._panAnimId = null
1355
+ }
1356
+ },
1302
1357
  emitSelectionChange() {
1303
1358
  this.$emit('selection-change', this.getSelectedElements())
1304
1359
  },
@@ -1449,7 +1504,7 @@ export default {
1449
1504
  <br class="clear">
1450
1505
 
1451
1506
  <footer>
1452
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 22 2026 22:01:02 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1507
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 23 2026 15:03:25 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1453
1508
  </footer>
1454
1509
 
1455
1510
  <script>prettyPrint();</script>
@@ -265,7 +265,7 @@ export default {
265
265
  <br class="clear">
266
266
 
267
267
  <footer>
268
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 22 2026 22:01:02 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
268
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 23 2026 15:03:25 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
269
269
  </footer>
270
270
 
271
271
  <script>prettyPrint();</script>
@@ -36,7 +36,7 @@
36
36
 
37
37
 
38
38
  <!-- app -->
39
- <script src="app.umd.js?1787407269095"></script>
39
+ <script src="app.umd.js?1787468611978"></script>
40
40
 
41
41
  </head>
42
42
  <body style="font-family:'Microsoft JhengHei','Avenir','Helvetica'; padding:0px; margin:0px;">