What I want to get: enter image description here

Picture for visualization. The task is to link the blocks (dynamically stretch the arrow from one block to another) and at the end get the structure for further work. For example:

a link to b

b link to c

Also one block can have several links. Please suggest a direction on how to make connections.

drag and drop done like this:

<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jQuery UI Draggable - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <link rel="stylesheet" href="/resources/demos/style.css"> <style> #draggable { width: 50px; height: 50px; padding: 0.5em; } #draggable1 { width: 50px; height: 50px; padding: 0.5em; } </style> <script> $(function() { $( "#draggable" ).draggable(); }); $(function() { $( "#draggable1" ).draggable(); }); </script> </head> <body> <div id="draggable" class="ui-widget-content"> <p>Drag me</p> </div> <div id="draggable1" class="ui-widget-content"> <p>Drag me</p> </div> </body> </html> 

1 answer 1

The working version, but the code is not at its best. Link to plunker.

 "use strict"; var can = $("#can").get(0), ctx = can.getContext('2d'); var boxes = []; function get_box(x, y) { for (var box of boxes) { if (x >= box.x && x < box.x + box.w && y >= box.y && y < box.y + box.h) { return box; } } return null; } function getxy(e) { return {x:e.clientX, y:e.clientY}; } class Box { constructor(x, y, w, h) { this.x = x; this.y = y; this.w = w; this.h = h; this.drag = null; this.name = String.fromCharCode("A".charCodeAt() + boxes.length); boxes.push(this); } on_mouse_down(e) { this.drag = { oldx: this.x, oldy: this.y, // old position of box msx: e.clientX, msy: e.clientY // mouse start x, y }; } on_mouse_move(e) { if (!this.drag) return; var dx = e.clientX - this.drag.msx, dy = e.clientY - this.drag.msy; this.x = this.drag.oldx + dx; this.y = this.drag.oldy + dy; draw_boxes(); } on_mouse_up(e) { this.drag = null; } draw() { ctx.save(); ctx.fillRect(this.x, this.y, this.w, this.h); ctx.font = "30px Georgia"; ctx.fillStyle = "white"; ctx.fillText(this.name, this.x + 10, this.y + 30); ctx.restore(); } center() { return {x: this.x + Math.floor(this.w/2), y: this.y + Math.floor(this.h/2) }; } } var link = null, links = []; function on_mouse_event(method_name) { return function (e) { for (var box of boxes) box[method_name](e); } } $("#can").mousedown(function (e) { var p = getxy(e), b = get_box(px, py); if (e.shiftKey) { new Box(px, py, 50, 50); draw_all(); return; } if (!b) return; if (e.ctrlKey) { link = {b}; return; } get_box(px, py).on_mouse_down(e); }); $("#can").mousemove((e) => { if (link) { link.t = getxy(e); } else { for (var box of boxes) box.on_mouse_move(e); } draw_all(); }); $("#can").mouseup((e) => { var x = e.clientX, y = e.clientY, b = get_box(x, y); if (link) { if (link.b == b || !b) { link = null; return; } links.push({from:link.b, to:b}); } else { for (var box of boxes) box.on_mouse_up(e); } link = null; }); $("#getlinks").click((e) => { var msg = ""; for (var l of links) { msg += `Box "${l.from.name}" свзяан с Box "${l.to.name}"<br>`; } $("#res").html(msg); }); new Box(10, 10, 50, 50); new Box(150, 150, 50, 50); function draw_boxes() { for (var box of boxes) { box.draw(); } } function draw_links() { for (var l of links) { var bc1 = l.from.center(), bc2 = l.to.center(); ctx.beginPath(); ctx.moveTo(bc1.x, bc1.y); ctx.lineTo(bc2.x, bc2.y); ctx.stroke(); } } function draw_link() { var bc = link.b.center(); ctx.beginPath(); ctx.moveTo(bc.x, bc.y); ctx.lineTo(link.tx, link.ty); ctx.stroke(); } function draw_all() { ctx.clearRect(0, 0, can.width, can.height); draw_links(); draw_boxes(); if (link) draw_link(); } draw_all(); 
 html, body { margin: 0; padding: 0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <canvas id="can" width="300" height="300"> This text is displayed if your browser does not support HTML5 Canvas. </canvas> </div> <hr>MouseMove -- ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ€ΠΎΠ±ΠΎΠΊ. <br>Shift + Click -- Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΡ€ΠΎΠ±ΠΊΡƒ. <br>Ctrl (Π½Π° ΠΊΠΎΡ€ΠΎΠ±ΠΊΠ΅) + MouseMove -- провСсти линию. <br> <hr> <button id="getlinks">ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ всС связи</button> <p id="res"></p> 

  • And in what way can you get a list of what is connected with what? Something like, and connected with b, b connected with c, c connected with a. - santer
  • @santer, all links are in the links array. Each link is an object of the form {from: box1, to: box2} . You can give all the box'Π°ΠΌ names and then all the links can be obtained as follows: for (var link of links) console.log(link.from.name, link.to.name); - pank
  • @santer, explain why you need it. - pank
  • This is necessary for the frontend, that is, the user draws a certain scheme, then actions are made on the basis of these connections on the backend - santer
  • @santer, added a button to get all the links. I hope I helped you. - pank