power-link 0.0.5 → 0.0.7

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/README.md CHANGED
@@ -1,16 +1,16 @@
1
1
  # power-link
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/node-link-utils.svg)](https://www.npmjs.com/package/node-link-utils)
4
- [![license](https://img.shields.io/npm/l/node-link-utils.svg)](https://github.com/your-username/node-link-utils/blob/main/LICENSE)
3
+ [![npm version](https://img.shields.io/npm/v/power-link.svg)](https://www.npmjs.com/package/power-link)
4
+ [![license](https://img.shields.io/npm/l/power-link.svg)](https://github.com/Tem-man/power-link/blob/main)
5
5
 
6
6
  A pure JavaScript visual node connector for creating draggable connections between nodes. Framework-agnostic and easy to use.
7
7
 
8
- ![Node Link Connector Demo](https://github.com/Tem-man/node-link-utils/blob/main/packages/images/screen-shot.png)
8
+ ![Node Link Connector Demo](https://github.com/Tem-man/power-link/blob/main/public/images/screen-shot.png)
9
9
 
10
10
  ### 📹 Demo Video
11
11
 
12
12
  <video width="100%" controls>
13
- <source src="https://github.com/Tem-man/node-link-utils/raw/main/packages/images/video.mp4" type="video/mp4">
13
+ <source src="https://github.com/Tem-man/power-link/blob/main/public/images/video.mp4" type="video/mp4">
14
14
  Your browser does not support the video tag.
15
15
  </video>
16
16
 
@@ -74,7 +74,7 @@ const connector = new Connector({
74
74
 
75
75
  onDisconnect: (connection) => {
76
76
  console.log("Connection removed:", connection);
77
- },
77
+ }
78
78
  });
79
79
 
80
80
  // 3. Register nodes
@@ -82,20 +82,33 @@ const node1 = document.getElementById("node1");
82
82
  const node2 = document.getElementById("node2");
83
83
 
84
84
  connector.registerNode("node1", node1, {
85
- dotPositions: ["right"], // Only right connection dot
85
+ dotPositions: ["right"] // Only right connection dot
86
86
  });
87
87
 
88
88
  connector.registerNode("node2", node2, {
89
- dotPositions: ["left", "right"], // Both left and right dots
89
+ dotPositions: ["left", "right"] // Both left and right dots
90
90
  });
91
91
  ```
92
92
 
93
93
  ### HTML Structure
94
94
 
95
95
  ```html
96
- <div id="connector-container" style="position: relative; height: 600px;">
97
- <div id="node1" style="position: absolute; left: 100px; top: 100px;">Node 1</div>
98
- <div id="node2" style="position: absolute; left: 400px; top: 100px;">Node 2</div>
96
+ <div
97
+ id="connector-container"
98
+ style="position: relative; height: 600px;"
99
+ >
100
+ <div
101
+ id="node1"
102
+ style="position: absolute; left: 100px; top: 100px;"
103
+ >
104
+ Node 1
105
+ </div>
106
+ <div
107
+ id="node2"
108
+ style="position: absolute; left: 400px; top: 100px;"
109
+ >
110
+ Node 2
111
+ </div>
99
112
  </div>
100
113
  ```
101
114
 
@@ -114,6 +127,11 @@ connector.registerNode("node2", node2, {
114
127
  | `enableNodeDrag` | Boolean | `true` | Enable node dragging |
115
128
  | `enableSnap` | Boolean | `true` | Enable connection snapping |
116
129
  | `snapDistance` | Number | `20` | Snap distance in pixels |
130
+ | `enableZoom` | Boolean | `true` | Enable zoom functionality |
131
+ | `enablePan` | Boolean | `true` | Enable pan functionality |
132
+ | `minZoom` | Number | `0.1` | Minimum zoom level (10%) |
133
+ | `maxZoom` | Number | `4` | Maximum zoom level (400%) |
134
+ | `zoomStep` | Number | `0.1` | Zoom step size (10%) |
117
135
  | `onConnect` | Function | `() => {}` | Callback when connection is created |
118
136
  | `onDisconnect` | Function | `() => {}` | Callback when connection is removed |
119
137
 
@@ -133,6 +151,7 @@ Register a node for connection.
133
151
  - `['left', 'right']`: Array format, both sides
134
152
  - `['left']`: Only left dot
135
153
  - `['right']`: Only right dot
154
+ - `info` (Object): Node extraneous information
136
155
 
137
156
  **Returns:** Node object
138
157
 
@@ -141,6 +160,11 @@ Register a node for connection.
141
160
  ```javascript
142
161
  connector.registerNode("myNode", element, {
143
162
  dotPositions: ["right"],
163
+ info: {
164
+ id: "123",
165
+ name: "apple",
166
+ desc: "this is a red apple"
167
+ }
144
168
  });
145
169
  ```
146
170
 
@@ -221,15 +245,49 @@ Destroy the connector and clean up all resources.
221
245
  connector.destroy();
222
246
  ```
223
247
 
248
+ #### `setViewState(scale,translateX,translateY)`
249
+
250
+ Set the initial view state
251
+
252
+ **Parameters:**
253
+
254
+ - `scale` (Number): set initial view scale
255
+ - `translateX` (Number): set initial view x-axis translation
256
+ - `translateY` (Number): set initial view y-axis translation
257
+
258
+ **Example:**
259
+
260
+ ````javascript
261
+ connector.setViewState({
262
+ scale: 0.8,
263
+ translateX: 50,
264
+ translateY: 30
265
+ })
266
+ ```
267
+
268
+
224
269
  ## 🎨 Usage Examples
225
270
 
226
271
  ### Vue 3
227
272
 
228
273
  ```vue
229
274
  <template>
230
- <div class="container" ref="containerRef">
231
- <div class="node" ref="node1Ref">Node 1</div>
232
- <div class="node" ref="node2Ref">Node 2</div>
275
+ <div
276
+ class="container"
277
+ ref="containerRef"
278
+ >
279
+ <div
280
+ class="node"
281
+ ref="node1Ref"
282
+ >
283
+ Node 1
284
+ </div>
285
+ <div
286
+ class="node"
287
+ ref="node2Ref"
288
+ >
289
+ Node 2
290
+ </div>
233
291
  </div>
234
292
  </template>
235
293
 
@@ -251,15 +309,25 @@ connector.destroy();
251
309
  },
252
310
  onDisconnect: (connection) => {
253
311
  console.log("Connection removed:", connection);
254
- },
312
+ }
255
313
  });
256
314
 
257
315
  connector.registerNode("node1", node1Ref.value, {
258
316
  dotPositions: ["right"],
317
+ info: {
318
+ id: "123",
319
+ name: "apple",
320
+ desc: "this is a red apple"
321
+ }
259
322
  });
260
323
 
261
324
  connector.registerNode("node2", node2Ref.value, {
262
325
  dotPositions: ["left"],
326
+ info: {
327
+ id: "456",
328
+ name: "pear",
329
+ desc: "this is a yellow pear"
330
+ }
263
331
  });
264
332
  });
265
333
 
@@ -286,7 +354,7 @@ connector.destroy();
286
354
  cursor: move;
287
355
  }
288
356
  </style>
289
- ```
357
+ ````
290
358
 
291
359
  ### React
292
360
 
@@ -310,15 +378,25 @@ function App() {
310
378
  },
311
379
  onDisconnect: (connection) => {
312
380
  console.log("Connection removed:", connection);
313
- },
381
+ }
314
382
  });
315
383
 
316
384
  connectorRef.current.registerNode("node1", node1Ref.current, {
317
385
  dotPositions: ["right"],
386
+ info: {
387
+ id: "123",
388
+ name: "apple",
389
+ desc: "this is a red apple"
390
+ }
318
391
  });
319
392
 
320
393
  connectorRef.current.registerNode("node2", node2Ref.current, {
321
394
  dotPositions: ["left"],
395
+ info: {
396
+ id: "456",
397
+ name: "pear",
398
+ desc: "this is a yellow pear"
399
+ }
322
400
  });
323
401
 
324
402
  return () => {
@@ -329,11 +407,20 @@ function App() {
329
407
  }, []);
330
408
 
331
409
  return (
332
- <div ref={containerRef} style={{ position: "relative", height: "600px" }}>
333
- <div ref={node1Ref} style={{ position: "absolute", left: "100px", top: "100px" }}>
410
+ <div
411
+ ref={containerRef}
412
+ style={{ position: "relative", height: "600px" }}
413
+ >
414
+ <div
415
+ ref={node1Ref}
416
+ style={{ position: "absolute", left: "100px", top: "100px" }}
417
+ >
334
418
  Node 1
335
419
  </div>
336
- <div ref={node2Ref} style={{ position: "absolute", left: "400px", top: "100px" }}>
420
+ <div
421
+ ref={node2Ref}
422
+ style={{ position: "absolute", left: "400px", top: "100px" }}
423
+ >
337
424
  Node 2
338
425
  </div>
339
426
  </div>
@@ -365,8 +452,20 @@ function App() {
365
452
  </head>
366
453
  <body>
367
454
  <div id="container">
368
- <div id="node1" class="node" style="left: 100px; top: 100px;">Node 1</div>
369
- <div id="node2" class="node" style="left: 400px; top: 100px;">Node 2</div>
455
+ <div
456
+ id="node1"
457
+ class="node"
458
+ style="left: 100px; top: 100px;"
459
+ >
460
+ Node 1
461
+ </div>
462
+ <div
463
+ id="node2"
464
+ class="node"
465
+ style="left: 400px; top: 100px;"
466
+ >
467
+ Node 2
468
+ </div>
370
469
  </div>
371
470
 
372
471
  <script type="module">
@@ -376,15 +475,25 @@ function App() {
376
475
  container: document.getElementById("container"),
377
476
  onConnect: (connection) => {
378
477
  console.log("Connection created:", connection);
379
- },
478
+ }
380
479
  });
381
480
 
382
481
  connector.registerNode("node1", document.getElementById("node1"), {
383
482
  dotPositions: ["right"],
483
+ info: {
484
+ id: "123",
485
+ name: "apple",
486
+ desc: "this is a red apple"
487
+ }
384
488
  });
385
489
 
386
490
  connector.registerNode("node2", document.getElementById("node2"), {
387
491
  dotPositions: ["left"],
492
+ info: {
493
+ id: "456",
494
+ name: "pear",
495
+ desc: "this is a yellow pear"
496
+ }
388
497
  });
389
498
  </script>
390
499
  </body>
@@ -398,17 +507,22 @@ function App() {
398
507
  ```javascript
399
508
  // Node with both left and right connection points
400
509
  connector.registerNode("centerNode", element, {
401
- dotPositions: ["left", "right"],
510
+ dotPositions: ["left", "right"]
402
511
  });
403
512
 
404
513
  // Node with only left connection point
405
514
  connector.registerNode("endNode", element, {
406
515
  dotPositions: ["left"],
516
+ info: {
517
+ id: "456",
518
+ name: "pear",
519
+ desc: "this is a yellow pear"
520
+ }
407
521
  });
408
522
 
409
523
  // Node with only right connection point
410
524
  connector.registerNode("startNode", element, {
411
- dotPositions: ["right"],
525
+ dotPositions: ["right"]
412
526
  });
413
527
  ```
414
528
 
@@ -421,7 +535,7 @@ const connector = new Connector({
421
535
  lineWidth: 3, // Thicker lines
422
536
  dotSize: 16, // Larger dots
423
537
  dotColor: "#4ECDC4", // Teal dots
424
- deleteButtonSize: 24, // Larger delete button
538
+ deleteButtonSize: 24 // Larger delete button
425
539
  });
426
540
  ```
427
541
 
@@ -444,7 +558,7 @@ const connector = new Connector({
444
558
 
445
559
  // Update database, state, etc.
446
560
  removeConnection(connection);
447
- },
561
+ }
448
562
  });
449
563
  ```
450
564
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! node-link v0.0.4 | MIT License */
2
- function t(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=Array(e);n<e;n++)o[n]=t[n];return o}function e(t,e,n){return e&&function(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,a(o.key),o)}}(t.prototype,e),Object.defineProperty(t,"prototype",{writable:!1}),t}function n(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=l(t))||e){n&&(t=n);var o=0,i=function(){};return{s:i,n:function(){return o>=t.length?{done:!0}:{done:!1,value:t[o++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,r=!0,a=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return r=t.done,t},e:function(t){a=!0,s=t},f:function(){try{r||null==n.return||n.return()}finally{if(a)throw s}}}}function o(t,e,n){return(e=a(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,o)}return n}function s(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?i(Object(n),!0).forEach(function(e){o(t,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))})}return t}function r(e){return function(e){if(Array.isArray(e))return t(e)}(e)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(e)||l(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var o=n.call(t,e);if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t,"string");return"symbol"==typeof e?e:e+""}function l(e,n){if(e){if("string"==typeof e)return t(e,n);var o={}.toString.call(e).slice(8,-1);return"Object"===o&&e.constructor&&(o=e.constructor.name),"Map"===o||"Set"===o?Array.from(e):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?t(e,n):void 0}}var c=function(){return e(function t(){var e=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),o(this,"handleNodeDragMove",function(t){if(e.isDraggingNode&&e.draggedNode){var n=e.contentWrapper.getBoundingClientRect(),o=t.clientX-n.left-e.dragOffset.x,i=t.clientY-n.top-e.dragOffset.y;e.draggedNode.element.style.left="".concat(o,"px"),e.draggedNode.element.style.top="".concat(i,"px"),e.updateNodeConnections(e.draggedNode.id)}}),o(this,"handleNodeDragEnd",function(){e.isDraggingNode=!1,e.draggedNode=null,document.removeEventListener("mousemove",e.handleNodeDragMove),document.removeEventListener("mouseup",e.handleNodeDragEnd)}),o(this,"handleMouseMove",function(t){e.isDragging&&e.updateTempLine(t)}),o(this,"handleMouseUp",function(t){if(e.isDragging){e.isDragging=!1;var n=e.isSnapped?e.snapTarget:e.getNodeAtPosition(t.clientX,t.clientY),o=e.isSnapped?e.snapTargetDot:null;n&&n.id!==e.startNode.id&&e.createConnection(e.startNode,n,e.startDot,o),e.clearSnapHighlight(),e.snapTarget=null,e.snapTargetDot=null,e.isSnapped=!1,e.startDot=null,e.tempLine&&(e.svg.removeChild(e.tempLine),e.tempLine=null),document.removeEventListener("mousemove",e.handleMouseMove),document.removeEventListener("mouseup",e.handleMouseUp)}}),this.container=n.container,this.nodes=[],this.connections=[],this.isDragging=!1,this.isDraggingNode=!1,this.tempLine=null,this.draggedNode=null,this.dragOffset={x:0,y:0},this.onConnect=n.onConnect||function(){},this.onDisconnect=n.onDisconnect||function(){},this.onViewChange=n.onViewChange||function(){},this.config=s({lineColor:n.lineColor||"#155BD4",lineWidth:n.lineWidth||2,dotSize:n.dotSize||12,dotColor:n.dotColor||"#155BD4",deleteButtonSize:n.deleteButtonSize||20,enableNodeDrag:!1!==n.enableNodeDrag,snapDistance:n.snapDistance||20,enableSnap:!1!==n.enableSnap,enableZoom:!1!==n.enableZoom,enablePan:!1!==n.enablePan,minZoom:n.minZoom||.1,maxZoom:n.maxZoom||4,zoomStep:n.zoomStep||.1},n.config),this.snapTarget=null,this.isSnapped=!1,this.viewState={scale:1,translateX:0,translateY:0},this.isPanning=!1,this.panStart={x:0,y:0},this.spacePressed=!1,this.contentWrapper=null,this.init()},[{key:"init",value:function(){var t=this;if(!this.container)throw new Error("Container element is required");"static"===window.getComputedStyle(this.container).position&&(this.container.style.position="relative"),this.container.style.overflow="hidden",this.contentWrapper=document.createElement("div"),this.contentWrapper.className="connector-content-wrapper",this.contentWrapper.style.cssText="\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n transform-origin: 0 0;\n transition: none;\n ",Array.from(this.container.children).forEach(function(e){t.contentWrapper.appendChild(e)}),this.container.appendChild(this.contentWrapper),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0",this.svg.style.left="0",this.svg.style.width="100%",this.svg.style.height="100%",this.svg.style.pointerEvents="none",this.svg.style.zIndex="1",this.contentWrapper.appendChild(this.svg),this.config.enableZoom&&this.bindZoomEvents(),this.config.enablePan&&this.bindPanEvents(),this.bindResizeEvents(),this.updateTransform()}},{key:"updateTransform",value:function(){if(this.contentWrapper){var t=this.viewState,e=t.scale,n=t.translateX,o=t.translateY;this.contentWrapper.style.transform="translate(".concat(n,"px, ").concat(o,"px) scale(").concat(e,")"),this.onViewChange({scale:e,translateX:n,translateY:o})}}},{key:"bindZoomEvents",value:function(){var t=this;this.handleWheel=function(e){if(e.ctrlKey||e.metaKey){e.preventDefault();var n=t.container.getBoundingClientRect(),o=e.clientX-n.left,i=e.clientY-n.top,s=e.deltaY<0?t.config.zoomStep:-t.config.zoomStep,r=Math.max(t.config.minZoom,Math.min(t.config.maxZoom,t.viewState.scale+s));t.zoomAtPoint(r,o,i)}},this.container.addEventListener("wheel",this.handleWheel,{passive:!1})}},{key:"bindPanEvents",value:function(){var t=this;this.handleKeyDown=function(e){"Space"!==e.code||t.spacePressed||t.isDragging||t.isDraggingNode||(e.preventDefault(),t.spacePressed=!0,t.container.style.cursor="grab")},this.handleKeyUp=function(e){"Space"===e.code&&(t.spacePressed=!1,t.container.style.cursor="",t.isPanning&&t.stopPan())},this.handlePanStart=function(e){!t.spacePressed||t.isDragging||t.isDraggingNode||(e.preventDefault(),e.stopPropagation(),t.isPanning=!0,t.panStart={x:e.clientX-t.viewState.translateX,y:e.clientY-t.viewState.translateY},t.container.style.cursor="grabbing")},this.handlePanMove=function(e){t.isPanning&&(e.preventDefault(),t.viewState.translateX=e.clientX-t.panStart.x,t.viewState.translateY=e.clientY-t.panStart.y,t.updateTransform())},this.handlePanEnd=function(){t.isPanning&&t.stopPan()},document.addEventListener("keydown",this.handleKeyDown),document.addEventListener("keyup",this.handleKeyUp),this.container.addEventListener("mousedown",this.handlePanStart),document.addEventListener("mousemove",this.handlePanMove),document.addEventListener("mouseup",this.handlePanEnd)}},{key:"stopPan",value:function(){this.isPanning=!1,this.container.style.cursor=this.spacePressed?"grab":""}},{key:"bindResizeEvents",value:function(){var t=this,e=null;this.handleResize=function(){e&&clearTimeout(e),e=setTimeout(function(){t.updateAllConnections()},100)},window.addEventListener("resize",this.handleResize),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(function(){e&&clearTimeout(e),e=setTimeout(function(){t.updateAllConnections()},100)}),this.resizeObserver.observe(this.container))}},{key:"zoomAtPoint",value:function(t,e,n){var o=this.viewState.scale,i=(e-this.viewState.translateX)/o,s=(n-this.viewState.translateY)/o;this.viewState.scale=t,this.viewState.translateX=e-i*t,this.viewState.translateY=n-s*t,this.updateTransform()}},{key:"setZoom",value:function(t){var e=this.container.getBoundingClientRect(),n=e.width/2,o=e.height/2;this.zoomAtPoint(t,n,o)}},{key:"getZoom",value:function(){return this.viewState.scale}},{key:"resetView",value:function(){this.viewState.scale=1,this.viewState.translateX=0,this.viewState.translateY=0,this.updateTransform()}},{key:"zoomIn",value:function(){var t=Math.min(this.config.maxZoom,this.viewState.scale+this.config.zoomStep);this.setZoom(t)}},{key:"zoomOut",value:function(){var t=Math.max(this.config.minZoom,this.viewState.scale-this.config.zoomStep);this.setZoom(t)}},{key:"getViewState",value:function(){return s({},this.viewState)}},{key:"registerNode",value:function(t,e){var n=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!this.nodes.find(function(e){return e.id===t})){var i=[];i="both"===o.dotPositions?["left","right"]:Array.isArray(o.dotPositions)?o.dotPositions.filter(function(t){return"left"===t||"right"===t}):[0===this.nodes.length?"right":"left"],i=r(new Set(i)).slice(0,2);var s={};i.forEach(function(t){var o=n.createDot(t);e.appendChild(o),s[t]={element:o,position:t}});var a={id:t,element:e,info:null==o?void 0:o.info,dots:s,dotPositions:i,connections:[]};return this.nodes.push(a),Object.values(s).forEach(function(t){n.bindDotEvents(a,t)}),this.config.enableNodeDrag&&this.bindNodeDragEvents(a),a}console.warn("节点 ".concat(t," 已存在"))}},{key:"createDot",value:function(t){var e=document.createElement("div");e.className="connector-dot";var n="right"===t?"right: -".concat(this.config.dotSize/2,"px;"):"left: -".concat(this.config.dotSize/2,"px;");return e.style.cssText="\n position: absolute;\n width: ".concat(this.config.dotSize,"px;\n height: ").concat(this.config.dotSize,"px;\n background-color: ").concat(this.config.dotColor,";\n border: 2px solid white;\n border-radius: 50%;\n cursor: pointer;\n ").concat(n,"\n top: 50%;\n transform: translateY(-50%);\n z-index: 10;\n transition: transform 0.2s;\n "),e.dataset.baseTransform="translateY(-50%)",e.addEventListener("mouseenter",function(){e.style.transform="translateY(-50%) scale(1.2)"}),e.addEventListener("mouseleave",function(){e.style.transform="translateY(-50%) scale(1)"}),e}},{key:"bindDotEvents",value:function(t,e){var n=this;e.element.addEventListener("mousedown",function(o){o.preventDefault(),o.stopPropagation(),n.isDragging=!0,n.startNode=t,n.startDot=e,n.tempLine=n.createLine(),n.svg.appendChild(n.tempLine),n.updateTempLine(o),document.addEventListener("mousemove",n.handleMouseMove),document.addEventListener("mouseup",n.handleMouseUp)})}},{key:"bindNodeDragEvents",value:function(t){var e=this,n=t.element;n.addEventListener("mousedown",function(o){if(!o.target.classList.contains("connector-dot")&&!e.spacePressed){o.preventDefault(),o.stopPropagation(),e.isDraggingNode=!0,e.draggedNode=t;var i=n.getBoundingClientRect(),s=e.contentWrapper.getBoundingClientRect();e.dragOffset={x:o.clientX-i.left,y:o.clientY-i.top};var r=i.left-s.left,a=i.top-s.top;n.style.left="".concat(r,"px"),n.style.top="".concat(a,"px"),n.style.right="",n.style.bottom="",document.addEventListener("mousemove",e.handleNodeDragMove),document.addEventListener("mouseup",e.handleNodeDragEnd)}})}},{key:"updateTempLine",value:function(t){if(this.tempLine&&this.startNode&&this.startDot){var e=this.getDotPosition(this.startNode.element,this.startDot.position),n=this.container.getBoundingClientRect(),o=t.clientX-n.left,i=t.clientY-n.top,s=this.viewState,r=s.scale,a={x:(o-s.translateX)/r,y:(i-s.translateY)/r};if(this.config.enableSnap){var l=this.checkSnap(a,this.startNode);l?(a=l.position,this.snapTarget=l.node,this.snapTargetDot=l.dot,this.isSnapped=!0,this.highlightSnapTarget(l.node,l.dot)):(this.isSnapped=!1,this.clearSnapHighlight(),this.snapTarget=null,this.snapTargetDot=null)}this.updateLine(this.tempLine,e,a,this.startDot.position)}}},{key:"createConnection",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};if(!n&&t.dots&&(n=t.dots.right||t.dots.left||Object.values(t.dots)[0]),!o&&e.dots&&(o=e.dots.left||e.dots.right||Object.values(e.dots)[0]),!this.connections.find(function(i){return i.fromNode.id===t.id&&i.toNode.id===e.id&&i.fromDot.position===n.position&&i.toDot.position===o.position||i.fromNode.id===e.id&&i.toNode.id===t.id&&i.fromDot.position===o.position&&i.toDot.position===n.position})){var s=this.createLine();this.svg.appendChild(s);var r=this.createDeleteButton(),a={id:"".concat(t.id,"-").concat(e.id,"-").concat(n.position,"-").concat(o.position,"-").concat(Date.now()),fromNode:t,toNode:e,fromDot:n,toDot:o,line:s,deleteButton:r};return this.connections.push(a),t.connections.push(a),e.connections.push(a),this.updateConnection(a),this.bindConnectionEvents(a),i.silent||this.onConnect({from:t.id,fromInfo:t.info,to:e.id,toInfo:e.info,fromDot:n.position,toDot:o.position}),a}console.warn("该连接已存在")}},{key:"updateConnection",value:function(t){if(t&&t.line){var e=this.getDotPosition(t.fromNode.element,t.fromDot.position),n=this.getDotPosition(t.toNode.element,t.toDot.position);if(this.updateLine(t.line,e,n,t.fromDot.position,t.toDot.position),t.hoverPath&&this.updateLine(t.hoverPath,e,n,t.fromDot.position,t.toDot.position),t.deleteButton){var o=this.getBezierMidPoint(e,n,t.fromDot.position,t.toDot.position);t.deleteButton.style.left="".concat(o.x-this.config.deleteButtonSize/2,"px"),t.deleteButton.style.top="".concat(o.y-this.config.deleteButtonSize/2,"px")}}}},{key:"updateNodeConnections",value:function(t){var e=this;this.connections.filter(function(e){return e.fromNode.id===t||e.toNode.id===t}).forEach(function(t){return e.updateConnection(t)})}},{key:"updateAllConnections",value:function(){var t=this;this.connections.forEach(function(e){return t.updateConnection(e)})}},{key:"createLine",value:function(){var t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("stroke",this.config.lineColor),t.setAttribute("stroke-width",this.config.lineWidth),t.setAttribute("fill","none"),t}},{key:"updateLine",value:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"right",i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"left",s=n.x-e.x,r=n.y-e.y,a=Math.sqrt(s*s+r*r),l=Math.min(.5*a,150),c="right"===o?e.x+l:e.x-l,d="right"===i?n.x+l:n.x-l,h="M ".concat(e.x," ").concat(e.y," C ").concat(c," ").concat(e.y,", ").concat(d," ").concat(n.y,", ").concat(n.x," ").concat(n.y);t.setAttribute("d",h)}},{key:"getBezierMidPoint",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"right",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"left",i=e.x-t.x,s=e.y-t.y,r=Math.sqrt(i*i+s*s),a=Math.min(.5*r,150),l="right"===n?t.x+a:t.x-a,c=t.y,d="right"===o?e.x+a:e.x-a,h=e.y,u=.5,f=u*u,p=f*u;return{x:.125*t.x+.375*l+.375*d+p*e.x,y:.125*t.y+.375*c+.375*h+p*e.y}}},{key:"createDeleteButton",value:function(){var t=document.createElement("div");return t.className="connector-delete-btn",t.innerHTML="×",t.style.cssText="\n position: absolute;\n width: ".concat(this.config.deleteButtonSize,"px;\n height: ").concat(this.config.deleteButtonSize,"px;\n background-color: #ff4d4f;\n color: white;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 16px;\n font-weight: bold;\n z-index: 100;\n opacity: 0;\n transition: opacity 0.2s, transform 0.2s;\n pointer-events: none;\n "),this.contentWrapper.appendChild(t),t.addEventListener("mouseenter",function(){t.style.transform="scale(1.2)"}),t.addEventListener("mouseleave",function(){t.style.transform="scale(1)",t.style.opacity="0",t.style.pointerEvents="none"}),t}},{key:"bindConnectionEvents",value:function(t){var e=this,n=t.line,o=t.deleteButton;n.style.pointerEvents="stroke",n.style.cursor="pointer";var i=document.createElementNS("http://www.w3.org/2000/svg","path");i.setAttribute("stroke","transparent"),i.setAttribute("stroke-width","20"),i.setAttribute("fill","none"),i.style.pointerEvents="stroke",i.style.cursor="pointer",i.setAttribute("d",n.getAttribute("d")),this.svg.insertBefore(i,n),t.hoverPath=i;var s=function(){o.style.opacity="1",o.style.pointerEvents="auto"},r=function(){setTimeout(function(){o.matches(":hover")||(o.style.opacity="0",o.style.pointerEvents="none")},100)};i.addEventListener("mouseenter",s),i.addEventListener("mouseleave",r),n.addEventListener("mouseenter",s),n.addEventListener("mouseleave",r),o.addEventListener("click",function(){e.disconnect(t.id)})}},{key:"disconnect",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(t){var o=this.connections.findIndex(function(e){return e.id===t});if(-1===o)return;var i=this.connections[o],s={from:i.fromNode.id,fromInfo:i.fromNode.info,to:i.toNode.id,toInfo:i.toNode.info,fromDot:i.fromDot.position,toDot:i.toDot.position};i.line&&i.line.parentNode&&this.svg.removeChild(i.line),i.hoverPath&&i.hoverPath.parentNode&&this.svg.removeChild(i.hoverPath),i.deleteButton&&i.deleteButton.parentNode&&i.deleteButton.parentNode.removeChild(i.deleteButton),i.fromNode.connections=i.fromNode.connections.filter(function(e){return e.id!==t}),i.toNode.connections=i.toNode.connections.filter(function(e){return e.id!==t}),this.connections.splice(o,1),n.silent||this.onDisconnect(s)}else{r(this.connections).forEach(function(t){return e.disconnect(t.id,n)})}}},{key:"getElementCenter",value:function(t){var e=t.getBoundingClientRect(),n=this.container.getBoundingClientRect(),o=e.left+e.width/2-n.left,i=e.top+e.height/2-n.top,s=this.viewState,r=s.scale;return{x:(o-s.translateX)/r,y:(i-s.translateY)/r}}},{key:"getDotPosition",value:function(t,e){var n=t.getBoundingClientRect(),o=this.container.getBoundingClientRect(),i="right"===e?n.right-o.left:n.left-o.left,s=n.top+n.height/2-o.top,r=this.viewState,a=r.scale;return{x:(i-r.translateX)/a,y:(s-r.translateY)/a}}},{key:"getNodeAtPosition",value:function(t,e){var o,i=n(this.nodes);try{for(i.s();!(o=i.n()).done;){var s=o.value,r=s.element.getBoundingClientRect();if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)return s}}catch(t){i.e(t)}finally{i.f()}return null}},{key:"checkSnap",value:function(t,e){var o=this;if(!this.config.enableSnap)return null;var i,s=null,r=null,a=1/0,l=n(this.nodes);try{var c=function(){var n=i.value;if(n.id===e.id)return 1;n.dots&&Object.values(n.dots).forEach(function(e){var i=o.getDotPosition(n.element,e.position),l=t.x-i.x,c=t.y-i.y,d=Math.sqrt(l*l+c*c);d<o.config.snapDistance&&d<a&&(a=d,s=n,r=e)})};for(l.s();!(i=l.n()).done;)c()}catch(t){l.e(t)}finally{l.f()}return s&&r?{node:s,dot:r,position:this.getDotPosition(s.element,r.position)}:null}},{key:"highlightSnapTarget",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(t&&t.element&&(this.clearSnapHighlight(),t.element.style.boxShadow="0 0 0 3px rgba(21, 91, 212, 0.3)",t.element.style.transform="scale(1.05)",t.element.dataset.snapped="true",e&&e.element)){var n=e.element.dataset.baseTransform||"translateY(-50%)";e.element.style.transform="".concat(n," scale(1.5)"),e.element.style.boxShadow="0 0 10px rgba(21, 91, 212, 0.6)",e.element.dataset.highlighted="true"}}},{key:"clearSnapHighlight",value:function(){this.nodes.forEach(function(t){"true"===t.element.dataset.snapped&&(t.element.style.boxShadow="",t.element.style.transform="",delete t.element.dataset.snapped,t.dots&&Object.values(t.dots).forEach(function(t){if("true"===t.element.dataset.highlighted){var e=t.element.dataset.baseTransform||"translateY(-50%)";t.element.style.transform=e,t.element.style.boxShadow="",delete t.element.dataset.highlighted}}))})}},{key:"updateNodePosition",value:function(t){var e=this,n=this.nodes.find(function(e){return e.id===t});n&&(n.dots&&Object.values(n.dots).forEach(function(t){t.coords=e.getDotPosition(n.element,t.position)}),this.updateNodeConnections(t))}},{key:"destroy",value:function(){this.disconnect(null,{silent:!0}),this.nodes.forEach(function(t){t.dots&&Object.values(t.dots).forEach(function(t){t.element&&t.element.parentNode&&t.element.parentNode.removeChild(t.element)})}),this.svg&&this.svg.parentNode&&this.svg.parentNode.removeChild(this.svg),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),document.removeEventListener("mousemove",this.handleNodeDragMove),document.removeEventListener("mouseup",this.handleNodeDragEnd),this.handleWheel&&this.container.removeEventListener("wheel",this.handleWheel),this.handleKeyDown&&document.removeEventListener("keydown",this.handleKeyDown),this.handleKeyUp&&document.removeEventListener("keyup",this.handleKeyUp),this.handlePanStart&&this.container.removeEventListener("mousedown",this.handlePanStart),this.handlePanMove&&document.removeEventListener("mousemove",this.handlePanMove),this.handlePanEnd&&document.removeEventListener("mouseup",this.handlePanEnd),this.handleResize&&window.removeEventListener("resize",this.handleResize),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.nodes=[],this.connections=[]}},{key:"getConnections",value:function(){return this.connections.map(function(t){return{id:t.id,from:t.fromNode.id,to:t.toNode.id,fromDot:t.fromDot.position,toDot:t.toDot.position}})}},{key:"getNodeConnections",value:function(t){return this.connections.filter(function(e){return e.fromNode.id===t||e.toNode.id===t}).map(function(t){return{id:t.id,from:t.fromNode.id,to:t.toNode.id,fromDot:t.fromDot.position,toDot:t.toDot.position}})}}])}();export{c as Connector,c as default};
1
+ /*! node-link v0.0.7 | MIT License */
2
+ function t(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=Array(e);n<e;n++)o[n]=t[n];return o}function e(t,e,n){return e&&function(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,a(o.key),o)}}(t.prototype,e),Object.defineProperty(t,"prototype",{writable:!1}),t}function n(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=l(t))||e){n&&(t=n);var o=0,i=function(){};return{s:i,n:function(){return o>=t.length?{done:!0}:{done:!1,value:t[o++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var r,s=!0,a=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return s=t.done,t},e:function(t){a=!0,r=t},f:function(){try{s||null==n.return||n.return()}finally{if(a)throw r}}}}function o(t,e,n){return(e=a(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),n.push.apply(n,o)}return n}function r(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?i(Object(n),!0).forEach(function(e){o(t,e,n[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))})}return t}function s(e){return function(e){if(Array.isArray(e))return t(e)}(e)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(e)||l(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var o=n.call(t,e);if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t,"string");return"symbol"==typeof e?e:e+""}function l(e,n){if(e){if("string"==typeof e)return t(e,n);var o={}.toString.call(e).slice(8,-1);return"Object"===o&&e.constructor&&(o=e.constructor.name),"Map"===o||"Set"===o?Array.from(e):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?t(e,n):void 0}}var c=function(){return e(function t(){var e=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),o(this,"handleNodeDragMove",function(t){if(e.isDraggingNode&&e.draggedNode){var n=e.contentWrapper.getBoundingClientRect(),o=e.viewState.scale,i=(t.clientX-n.left)/o-e.dragOffset.x,r=(t.clientY-n.top)/o-e.dragOffset.y;e.draggedNode.element.style.left="".concat(i,"px"),e.draggedNode.element.style.top="".concat(r,"px"),e.updateNodeConnections(e.draggedNode.id)}}),o(this,"handleNodeDragEnd",function(){e.isDraggingNode=!1,e.draggedNode=null,document.removeEventListener("mousemove",e.handleNodeDragMove),document.removeEventListener("mouseup",e.handleNodeDragEnd)}),o(this,"handleMouseMove",function(t){e.isDragging&&e.updateTempLine(t)}),o(this,"handleMouseUp",function(t){if(e.isDragging){e.isDragging=!1;var n=e.isSnapped?e.snapTarget:e.getNodeAtPosition(t.clientX,t.clientY),o=e.isSnapped?e.snapTargetDot:null;n&&n.id!==e.startNode.id&&e.createConnection(e.startNode,n,e.startDot,o),e.clearSnapHighlight(),e.snapTarget=null,e.snapTargetDot=null,e.isSnapped=!1,e.startDot=null,e.tempLine&&(e.svg.removeChild(e.tempLine),e.tempLine=null),document.removeEventListener("mousemove",e.handleMouseMove),document.removeEventListener("mouseup",e.handleMouseUp)}}),this.container=n.container,this.nodes=[],this.connections=[],this.isDragging=!1,this.isDraggingNode=!1,this.tempLine=null,this.draggedNode=null,this.dragOffset={x:0,y:0},this.onConnect=n.onConnect||function(){},this.onDisconnect=n.onDisconnect||function(){},this.onViewChange=n.onViewChange||function(){},this.config=r({lineColor:n.lineColor||"#155BD4",lineWidth:n.lineWidth||2,dotSize:n.dotSize||12,dotColor:n.dotColor||"#155BD4",deleteButtonSize:n.deleteButtonSize||20,enableNodeDrag:!1!==n.enableNodeDrag,snapDistance:n.snapDistance||20,enableSnap:!1!==n.enableSnap,enableZoom:!1!==n.enableZoom,enablePan:!1!==n.enablePan,minZoom:n.minZoom||.1,maxZoom:n.maxZoom||4,zoomStep:n.zoomStep||.1},n.config),this.snapTarget=null,this.isSnapped=!1,this.viewState={scale:1,translateX:0,translateY:0},this.isPanning=!1,this.panStart={x:0,y:0},this.contentWrapper=null,this.init()},[{key:"init",value:function(){var t=this;if(!this.container)throw new Error("Container element is required");"static"===window.getComputedStyle(this.container).position&&(this.container.style.position="relative"),this.container.style.overflow="hidden",this.contentWrapper=document.createElement("div"),this.contentWrapper.className="connector-content-wrapper",this.contentWrapper.style.cssText="\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n transform-origin: 0 0;\n transition: none;\n ",Array.from(this.container.children).forEach(function(e){t.contentWrapper.appendChild(e)}),this.container.appendChild(this.contentWrapper),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.position="absolute",this.svg.style.top="0",this.svg.style.left="0",this.svg.style.width="100%",this.svg.style.height="100%",this.svg.style.pointerEvents="none",this.svg.style.zIndex="1",this.contentWrapper.appendChild(this.svg),this.config.enableZoom&&this.bindZoomEvents(),this.config.enablePan&&this.bindPanEvents(),this.bindResizeEvents(),this.updateTransform()}},{key:"updateTransform",value:function(){if(this.contentWrapper){var t=this.viewState,e=t.scale,n=t.translateX,o=t.translateY;this.contentWrapper.style.transform="translate(".concat(n,"px, ").concat(o,"px) scale(").concat(e,")"),this.onViewChange({scale:e,translateX:n,translateY:o})}}},{key:"bindZoomEvents",value:function(){var t=this;this.handleWheel=function(e){e.preventDefault();var n=t.container.getBoundingClientRect(),o=e.clientX-n.left,i=e.clientY-n.top,r=e.deltaY<0?t.config.zoomStep:-t.config.zoomStep,s=Math.max(t.config.minZoom,Math.min(t.config.maxZoom,t.viewState.scale+r));t.zoomAtPoint(s,o,i)},this.container.addEventListener("wheel",this.handleWheel,{passive:!1})}},{key:"bindPanEvents",value:function(){var t=this;this.container.style.cursor="grab",this.handlePanStart=function(e){e.target.classList.contains("connector-dot")||t.isDragging||t.isDraggingNode||(t.getNodeAtPosition(e.clientX,e.clientY)&&t.config.enableNodeDrag||(e.preventDefault(),e.stopPropagation(),t.isPanning=!0,t.panStart={x:e.clientX-t.viewState.translateX,y:e.clientY-t.viewState.translateY},t.container.style.cursor="grabbing"))},this.handlePanMove=function(e){t.isPanning&&(e.preventDefault(),t.viewState.translateX=e.clientX-t.panStart.x,t.viewState.translateY=e.clientY-t.panStart.y,t.updateTransform())},this.handlePanEnd=function(){t.isPanning&&t.stopPan()},this.container.addEventListener("mousedown",this.handlePanStart),document.addEventListener("mousemove",this.handlePanMove),document.addEventListener("mouseup",this.handlePanEnd)}},{key:"stopPan",value:function(){this.isPanning=!1,this.container.style.cursor="grab"}},{key:"bindResizeEvents",value:function(){var t=this,e=null;this.handleResize=function(){e&&clearTimeout(e),e=setTimeout(function(){t.updateAllConnections()},100)},window.addEventListener("resize",this.handleResize),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(function(){e&&clearTimeout(e),e=setTimeout(function(){t.updateAllConnections()},100)}),this.resizeObserver.observe(this.container))}},{key:"zoomAtPoint",value:function(t,e,n){var o=this.viewState.scale,i=(e-this.viewState.translateX)/o,r=(n-this.viewState.translateY)/o;this.viewState.scale=t,this.viewState.translateX=e-i*t,this.viewState.translateY=n-r*t,this.updateTransform()}},{key:"setZoom",value:function(t){var e=this.container.getBoundingClientRect(),n=e.width/2,o=e.height/2;this.zoomAtPoint(t,n,o)}},{key:"getZoom",value:function(){return this.viewState.scale}},{key:"resetView",value:function(){this.viewState.scale=1,this.viewState.translateX=0,this.viewState.translateY=0,this.updateTransform()}},{key:"zoomIn",value:function(){var t=Math.min(this.config.maxZoom,this.viewState.scale+this.config.zoomStep);this.setZoom(t)}},{key:"zoomOut",value:function(){var t=Math.max(this.config.minZoom,this.viewState.scale-this.config.zoomStep);this.setZoom(t)}},{key:"getViewState",value:function(){return r({},this.viewState)}},{key:"setViewState",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"number"==typeof t.scale&&(this.viewState.scale=Math.max(this.config.minZoom,Math.min(this.config.maxZoom,t.scale))),"number"==typeof t.translateX&&(this.viewState.translateX=t.translateX),"number"==typeof t.translateY&&(this.viewState.translateY=t.translateY),this.updateTransform()}},{key:"registerNode",value:function(t,e){var n=this,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!this.nodes.find(function(e){return e.id===t})){var i=[];i="both"===o.dotPositions?["left","right"]:Array.isArray(o.dotPositions)?o.dotPositions.filter(function(t){return"left"===t||"right"===t}):[0===this.nodes.length?"right":"left"],i=s(new Set(i)).slice(0,2);var r={};i.forEach(function(t){var o=n.createDot(t);e.appendChild(o),r[t]={element:o,position:t}});var a={id:t,element:e,info:null==o?void 0:o.info,dots:r,dotPositions:i,connections:[]};return this.nodes.push(a),Object.values(r).forEach(function(t){n.bindDotEvents(a,t)}),this.config.enableNodeDrag&&this.bindNodeDragEvents(a),a}console.warn("节点 ".concat(t," 已存在"))}},{key:"createDot",value:function(t){var e=document.createElement("div");e.className="connector-dot";var n="right"===t?"right: -".concat(this.config.dotSize/2,"px;"):"left: -".concat(this.config.dotSize/2,"px;");return e.style.cssText="\n position: absolute;\n width: ".concat(this.config.dotSize,"px;\n height: ").concat(this.config.dotSize,"px;\n background-color: ").concat(this.config.dotColor,";\n border: 2px solid white;\n border-radius: 50%;\n cursor: pointer;\n ").concat(n,"\n top: 50%;\n transform: translateY(-50%);\n z-index: 10;\n transition: transform 0.2s;\n "),e.dataset.baseTransform="translateY(-50%)",e.addEventListener("mouseenter",function(){e.style.transform="translateY(-50%) scale(1.2)"}),e.addEventListener("mouseleave",function(){e.style.transform="translateY(-50%) scale(1)"}),e}},{key:"bindDotEvents",value:function(t,e){var n=this;e.element.addEventListener("mousedown",function(o){o.preventDefault(),o.stopPropagation(),n.isDragging=!0,n.startNode=t,n.startDot=e,n.tempLine=n.createLine(),n.svg.appendChild(n.tempLine),n.updateTempLine(o),document.addEventListener("mousemove",n.handleMouseMove),document.addEventListener("mouseup",n.handleMouseUp)})}},{key:"bindNodeDragEvents",value:function(t){var e=this,n=t.element;n.addEventListener("mousedown",function(o){if(!o.target.classList.contains("connector-dot")){o.preventDefault(),o.stopPropagation(),e.isDraggingNode=!0,e.draggedNode=t;var i=n.getBoundingClientRect(),r=e.contentWrapper.getBoundingClientRect(),s=e.viewState.scale;e.dragOffset={x:(o.clientX-i.left)/s,y:(o.clientY-i.top)/s};var a=(i.left-r.left)/s,l=(i.top-r.top)/s;n.style.left="".concat(a,"px"),n.style.top="".concat(l,"px"),n.style.right="",n.style.bottom="",document.addEventListener("mousemove",e.handleNodeDragMove),document.addEventListener("mouseup",e.handleNodeDragEnd)}})}},{key:"updateTempLine",value:function(t){if(this.tempLine&&this.startNode&&this.startDot){var e=this.getDotPosition(this.startNode.element,this.startDot.position),n=this.container.getBoundingClientRect(),o=t.clientX-n.left,i=t.clientY-n.top,r=this.viewState,s=r.scale,a={x:(o-r.translateX)/s,y:(i-r.translateY)/s};if(this.config.enableSnap){var l=this.checkSnap(a,this.startNode);l?(a=l.position,this.snapTarget=l.node,this.snapTargetDot=l.dot,this.isSnapped=!0,this.highlightSnapTarget(l.node,l.dot)):(this.isSnapped=!1,this.clearSnapHighlight(),this.snapTarget=null,this.snapTargetDot=null)}this.updateLine(this.tempLine,e,a,this.startDot.position)}}},{key:"createConnection",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};if(!n&&t.dots&&(n=t.dots.right||t.dots.left||Object.values(t.dots)[0]),!o&&e.dots&&(o=e.dots.left||e.dots.right||Object.values(e.dots)[0]),!this.connections.find(function(i){return i.fromNode.id===t.id&&i.toNode.id===e.id&&i.fromDot.position===n.position&&i.toDot.position===o.position||i.fromNode.id===e.id&&i.toNode.id===t.id&&i.fromDot.position===o.position&&i.toDot.position===n.position})){var r=this.createLine();this.svg.appendChild(r);var s=this.createDeleteButton(),a={id:"".concat(t.id,"-").concat(e.id,"-").concat(n.position,"-").concat(o.position,"-").concat(Date.now()),fromNode:t,toNode:e,fromDot:n,toDot:o,line:r,deleteButton:s};return this.connections.push(a),t.connections.push(a),e.connections.push(a),this.updateConnection(a),this.bindConnectionEvents(a),i.silent||this.onConnect({from:t.id,fromInfo:t.info,to:e.id,toInfo:e.info,fromDot:n.position,toDot:o.position}),a}console.warn("该连接已存在")}},{key:"updateConnection",value:function(t){if(t&&t.line){var e=this.getDotPosition(t.fromNode.element,t.fromDot.position),n=this.getDotPosition(t.toNode.element,t.toDot.position);if(this.updateLine(t.line,e,n,t.fromDot.position,t.toDot.position),t.hoverPath&&this.updateLine(t.hoverPath,e,n,t.fromDot.position,t.toDot.position),t.deleteButton){var o=this.getBezierMidPoint(e,n,t.fromDot.position,t.toDot.position);t.deleteButton.style.left="".concat(o.x-this.config.deleteButtonSize/2,"px"),t.deleteButton.style.top="".concat(o.y-this.config.deleteButtonSize/2,"px")}}}},{key:"updateNodeConnections",value:function(t){var e=this;this.connections.filter(function(e){return e.fromNode.id===t||e.toNode.id===t}).forEach(function(t){return e.updateConnection(t)})}},{key:"updateAllConnections",value:function(){var t=this;this.connections.forEach(function(e){return t.updateConnection(e)})}},{key:"createLine",value:function(){var t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("stroke",this.config.lineColor),t.setAttribute("stroke-width",this.config.lineWidth),t.setAttribute("fill","none"),t}},{key:"updateLine",value:function(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"right",i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"left",r=n.x-e.x,s=n.y-e.y,a=Math.sqrt(r*r+s*s),l=Math.min(.5*a,150),c="right"===o?e.x+l:e.x-l,d="right"===i?n.x+l:n.x-l,u="M ".concat(e.x," ").concat(e.y," C ").concat(c," ").concat(e.y,", ").concat(d," ").concat(n.y,", ").concat(n.x," ").concat(n.y);t.setAttribute("d",u)}},{key:"getBezierMidPoint",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"right",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"left",i=e.x-t.x,r=e.y-t.y,s=Math.sqrt(i*i+r*r),a=Math.min(.5*s,150),l="right"===n?t.x+a:t.x-a,c=t.y,d="right"===o?e.x+a:e.x-a,u=e.y,h=.5,f=h*h,v=f*h;return{x:.125*t.x+.375*l+.375*d+v*e.x,y:.125*t.y+.375*c+.375*u+v*e.y}}},{key:"createDeleteButton",value:function(){var t=document.createElement("div");return t.className="connector-delete-btn",t.innerHTML="×",t.style.cssText="\n position: absolute;\n width: ".concat(this.config.deleteButtonSize,"px;\n height: ").concat(this.config.deleteButtonSize,"px;\n background-color: #ff4d4f;\n color: white;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 16px;\n font-weight: bold;\n z-index: 100;\n opacity: 0;\n transition: opacity 0.2s, transform 0.2s;\n pointer-events: none;\n "),this.contentWrapper.appendChild(t),t.addEventListener("mouseenter",function(){t.style.transform="scale(1.2)"}),t.addEventListener("mouseleave",function(){t.style.transform="scale(1)",t.style.opacity="0",t.style.pointerEvents="none"}),t}},{key:"bindConnectionEvents",value:function(t){var e=this,n=t.line,o=t.deleteButton;n.style.pointerEvents="stroke",n.style.cursor="pointer";var i=document.createElementNS("http://www.w3.org/2000/svg","path");i.setAttribute("stroke","transparent"),i.setAttribute("stroke-width","20"),i.setAttribute("fill","none"),i.style.pointerEvents="stroke",i.style.cursor="pointer",i.setAttribute("d",n.getAttribute("d")),this.svg.insertBefore(i,n),t.hoverPath=i;var r=function(){o.style.opacity="1",o.style.pointerEvents="auto"},s=function(){setTimeout(function(){o.matches(":hover")||(o.style.opacity="0",o.style.pointerEvents="none")},100)};i.addEventListener("mouseenter",r),i.addEventListener("mouseleave",s),n.addEventListener("mouseenter",r),n.addEventListener("mouseleave",s),o.addEventListener("click",function(){e.disconnect(t.id)})}},{key:"disconnect",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(t){var o=this.connections.findIndex(function(e){return e.id===t});if(-1===o)return;var i=this.connections[o],r={from:i.fromNode.id,fromInfo:i.fromNode.info,to:i.toNode.id,toInfo:i.toNode.info,fromDot:i.fromDot.position,toDot:i.toDot.position};i.line&&i.line.parentNode&&this.svg.removeChild(i.line),i.hoverPath&&i.hoverPath.parentNode&&this.svg.removeChild(i.hoverPath),i.deleteButton&&i.deleteButton.parentNode&&i.deleteButton.parentNode.removeChild(i.deleteButton),i.fromNode.connections=i.fromNode.connections.filter(function(e){return e.id!==t}),i.toNode.connections=i.toNode.connections.filter(function(e){return e.id!==t}),this.connections.splice(o,1),n.silent||this.onDisconnect(r)}else{s(this.connections).forEach(function(t){return e.disconnect(t.id,n)})}}},{key:"getElementCenter",value:function(t){var e=t.getBoundingClientRect(),n=this.container.getBoundingClientRect(),o=e.left+e.width/2-n.left,i=e.top+e.height/2-n.top,r=this.viewState,s=r.scale;return{x:(o-r.translateX)/s,y:(i-r.translateY)/s}}},{key:"getDotPosition",value:function(t,e){var n=t.getBoundingClientRect(),o=this.container.getBoundingClientRect(),i="right"===e?n.right-o.left:n.left-o.left,r=n.top+n.height/2-o.top,s=this.viewState,a=s.scale;return{x:(i-s.translateX)/a,y:(r-s.translateY)/a}}},{key:"getNodeAtPosition",value:function(t,e){var o,i=n(this.nodes);try{for(i.s();!(o=i.n()).done;){var r=o.value,s=r.element.getBoundingClientRect();if(t>=s.left&&t<=s.right&&e>=s.top&&e<=s.bottom)return r}}catch(t){i.e(t)}finally{i.f()}return null}},{key:"checkSnap",value:function(t,e){var o=this;if(!this.config.enableSnap)return null;var i,r=null,s=null,a=1/0,l=n(this.nodes);try{var c=function(){var n=i.value;if(n.id===e.id)return 1;n.dots&&Object.values(n.dots).forEach(function(e){var i=o.getDotPosition(n.element,e.position),l=t.x-i.x,c=t.y-i.y,d=Math.sqrt(l*l+c*c);d<o.config.snapDistance&&d<a&&(a=d,r=n,s=e)})};for(l.s();!(i=l.n()).done;)c()}catch(t){l.e(t)}finally{l.f()}return r&&s?{node:r,dot:s,position:this.getDotPosition(r.element,s.position)}:null}},{key:"highlightSnapTarget",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(t&&t.element&&(this.clearSnapHighlight(),t.element.style.boxShadow="0 0 0 3px rgba(21, 91, 212, 0.3)",t.element.style.transform="scale(1.05)",t.element.dataset.snapped="true",e&&e.element)){var n=e.element.dataset.baseTransform||"translateY(-50%)";e.element.style.transform="".concat(n," scale(1.5)"),e.element.style.boxShadow="0 0 10px rgba(21, 91, 212, 0.6)",e.element.dataset.highlighted="true"}}},{key:"clearSnapHighlight",value:function(){this.nodes.forEach(function(t){"true"===t.element.dataset.snapped&&(t.element.style.boxShadow="",t.element.style.transform="",delete t.element.dataset.snapped,t.dots&&Object.values(t.dots).forEach(function(t){if("true"===t.element.dataset.highlighted){var e=t.element.dataset.baseTransform||"translateY(-50%)";t.element.style.transform=e,t.element.style.boxShadow="",delete t.element.dataset.highlighted}}))})}},{key:"updateNodePosition",value:function(t){var e=this,n=this.nodes.find(function(e){return e.id===t});n&&(n.dots&&Object.values(n.dots).forEach(function(t){t.coords=e.getDotPosition(n.element,t.position)}),this.updateNodeConnections(t))}},{key:"destroy",value:function(){this.disconnect(null,{silent:!0}),this.nodes.forEach(function(t){t.dots&&Object.values(t.dots).forEach(function(t){t.element&&t.element.parentNode&&t.element.parentNode.removeChild(t.element)})}),this.svg&&this.svg.parentNode&&this.svg.parentNode.removeChild(this.svg),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),document.removeEventListener("mousemove",this.handleNodeDragMove),document.removeEventListener("mouseup",this.handleNodeDragEnd),this.handleWheel&&this.container.removeEventListener("wheel",this.handleWheel),this.handlePanStart&&this.container.removeEventListener("mousedown",this.handlePanStart),this.handlePanMove&&document.removeEventListener("mousemove",this.handlePanMove),this.handlePanEnd&&document.removeEventListener("mouseup",this.handlePanEnd),this.handleResize&&window.removeEventListener("resize",this.handleResize),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.nodes=[],this.connections=[]}},{key:"getConnections",value:function(){return this.connections.map(function(t){return{id:t.id,from:t.fromNode.id,to:t.toNode.id,fromDot:t.fromDot.position,toDot:t.toDot.position}})}},{key:"getNodeConnections",value:function(t){return this.connections.filter(function(e){return e.fromNode.id===t||e.toNode.id===t}).map(function(t){return{id:t.id,from:t.fromNode.id,to:t.toNode.id,fromDot:t.fromDot.position,toDot:t.toDot.position}})}}])}();export{c as Connector,c as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "power-link",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "A pure JavaScript visual node connector for creating draggable connections between nodes. Framework-agnostic and easy to use",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -12,8 +12,7 @@
12
12
  },
13
13
  "files": [
14
14
  "dist",
15
- "README.md",
16
- "images"
15
+ "README.md"
17
16
  ],
18
17
  "publishConfig": {
19
18
  "access": "public"
Binary file
package/images/video.mp4 DELETED
Binary file