Last active
February 8, 2024 22:51
-
-
Save ppazos/04e613ba31c7982e18b68de27135dd75 to your computer and use it in GitHub Desktop.
Connect DOM boxes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sample https://jsfiddle.net/ppazos/Lngbx0t9/5/ | |
Reference to the drawing API https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath | |
Better library https://github.com/anseki/leader-line | |
# HTML | |
<canvas id="canvas" width=300 height=300></canvas> | |
<div style="margin-left: 30px"> | |
<div> | |
<div id="0" class="draggable">0</div> | |
<br/> | |
<br/> | |
<div id="1" class="draggable">1</div> | |
<br/> | |
<div id="2" class="draggable">2</div> | |
</div> | |
<div id="wrap2"> | |
<div id="0r" class="draggable right">0</div> | |
<br/> | |
<div id="1r" class="draggable right">1</div> | |
<br/> | |
<br/> | |
<div id="2r" class="draggable right">2</div> | |
</div> | |
</div> | |
# JS | |
var canvas = document.getElementById("canvas"); | |
var ctx = canvas.getContext("2d"); | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
ctx.lineWidth = 3; | |
var $canvas = $("#canvas"); | |
var canvasOffset = $canvas.offset(); | |
var offsetX = canvasOffset.left; | |
var offsetY = canvasOffset.top; | |
var $0 = $("#0"); | |
var $1 = $("#1"); | |
var $2 = $("#2"); | |
var $0r = $("#0r"); | |
var $1r = $("#1r"); | |
var $2r = $("#2r"); | |
var connectors = []; | |
connectors.push({ | |
from: $0, | |
to: $1r | |
}); | |
connectors.push({ | |
from: $1, | |
to: $0r | |
}); | |
connectors.push({ | |
from: $2, | |
to: $2r | |
}); | |
connect(); | |
$(".draggable").draggable({ | |
// event handlers | |
start: noop, | |
drag: connect, | |
stop: noop | |
}); | |
function noop() {} | |
function connect() { | |
const gutter = 1; // correction based on the border size of the boxes, since the border 1 is calculated outside the box width and height | |
const styles = ['blue', 'green', 'red']; | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
for (var i = 0; i < connectors.length; i++) { | |
var c = connectors[i]; | |
var eFrom = c.from; | |
var eTo = c.to; | |
var pos1 = eFrom.offset(); | |
var pos2 = eTo.offset(); | |
var size1 = eFrom.size(); | |
var size2 = eTo.size(); | |
ctx.strokeStyle = styles[i%styles.length]; | |
ctx.beginPath(); | |
// line from right-middle of initial box | |
ctx.moveTo(pos1.left + eFrom.width() + gutter, pos1.top + eFrom.height() / 2); | |
// to the right, ends in the middle of the two boxes | |
ctx.lineTo(pos1.left + (pos2.left - pos1.left + eFrom.width())/2, pos1.top + eFrom.height() / 2); | |
// goes down to the middle of the destination box | |
ctx.lineTo(pos1.left + (pos2.left - pos1.left + eFrom.width())/2, pos2.top + eTo.height() / 2); | |
// goes right to the middle-left of the second box, closing the connection | |
ctx.lineTo(pos2.left - gutter, pos2.top + eTo.height() / 2); | |
ctx.stroke(); | |
} | |
} | |
# CSS | |
body { | |
background-color: ivory; | |
margin:0; | |
padding:0; | |
} | |
#canvas { | |
position:absolute; | |
border:1px solid red; | |
width:100%; | |
height:100%; | |
} | |
.draggable { | |
width:50px; | |
height:30px; | |
background:skyblue; | |
border:1px solid green; | |
} | |
.right { | |
margin-left:100px; | |
background:salmon; | |
} | |
#wrap2 { | |
margin-top:-95px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment