Skip to content

Instantly share code, notes, and snippets.

@ppazos
Last active February 8, 2024 22:51
Show Gist options
  • Save ppazos/04e613ba31c7982e18b68de27135dd75 to your computer and use it in GitHub Desktop.
Save ppazos/04e613ba31c7982e18b68de27135dd75 to your computer and use it in GitHub Desktop.
Connect DOM boxes
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