Packet Tracer
by David Joseph Guzsik
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.6/interact.min.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/draggabilly.pkgd.js"></script>
<canvas id="lines"></canvas>
<ul id="devices">
<li class="device" style="top:34px;left:66px" id="Router0">
<img src="https://upload.wikimedia.org/wikipedia/commons/5/5c/Router.svg">
<div class="meta">
<span class="name">1841</span>
<span class="name">Router0</span>
</div>
</li>
<li class="device" style="top:34px;left:200px" id="Router1">
<img src="https://upload.wikimedia.org/wikipedia/commons/5/5c/Router.svg">
<div class="meta">
<span class="name">1841</span>
<span class="name">Router1</span>
</div>
</li>
<li class="device" style="top:100px;left:50px" id="Switch0">
<img src="http://www.clker.com/cliparts/b/0/c/c/1343841796926375646Switch%20Final.svg">
<div class="meta">
<span class="name">2950-24</span>
<span class="name">Switch0</span>
</div>
</li>
<li class="device" style="top:180px;left:80px" id="PC0">
<img src="http://www.clker.com/cliparts/A/A/2/P/j/7/computer-pc.svg">
<div class="meta">
<span class="name">PC</span>
<span class="name">PC0</span>
</div>
</li>
</ul>
CSS
html, body {
margin: 0;
overflow: hidden;
height: 100%;
width: 100%;
}
#lines, #devices {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
user-select: none;
}
#lines { background: #fff }
#devices {
list-style: none;
margin: 0;
padding: 0;
opacity: 1;
}
#devices img {
width: 50px;
height: 34px;
}
#devices > .device {
position: relative;
display: inline-block;
text-align: center;
}
#devices > .device.selected img,
#devices > .device:active img {
filter: brightness(150%);
}
#devices > .device > .meta {
position: absolute;
top: 34px;
left: 0;
width: 100%;
cursor: default;
pointer-events: none;
}
#devices > .device > .meta > * {
display: block;
white-space: nowrap;
line-hieght: 1em;
font-size: 8pt;
font-family: verdana;
text-shadow:
0 0 1px white,
0 0 2px white,
0 0 3px white,
0 0 4px white,
0 0 5px white,
0 0 6px white,
0 0 7px white,
0 0 10px white;
}
JavaScript
$.fn.getCenter = function(){
var $this = $(this),
offset = $this.offset(),
width = $this.width(),
height = $this.height();
return {
x: offset.left + width / 2,
y: offset.top + height / 2,
};
}
function circle(ctx, centerX, centerY, radius, fill){
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = fill;
ctx.fill();
ctx.closePath();
}
function calcDists(el1c, el2c, rev){
var distX = el2c.x - el1c.x,
distY = el2c.y - el1c.y,
distance = Math.sqrt(Math.pow(distX, 2)+Math.pow(distY, 2));
distX /= distance;
distY /= distance;
return {
distX: distX,
distY: distY,
mag: distance,
}
}
// http://stackoverflow.com/a/9947720/1344955
var curveOffest = 0.3;
$(function(){
$('.device').draggabilly({
containment: '#devices',
handle: 'img',
}).on('dragStart',function(event,pointer){
$('.selected').removeClass('selected');
$(this).addClass('selected');
}).on('dragMove',function(){
redrawConnections();
});
$('#devices').on('mousedown','.device',function(e){
e.stopPropagation();
$('.selected').removeClass('selected');
$(this).addClass('selected');
});
$('body').on('mousedown',function(){
$('.selected').removeClass('selected');
});
var ConnectionTypes = {
console: 0,
straightThrough: 1,
crossOver: 2,
};
var connections = [
{
type: ConnectionTypes.crossOver,
devices: ['Router0','Router1'],
},
{
type: ConnectionTypes.straightThrough,
devices: ['Router0','Switch0'],
},
{
type: ConnectionTypes.straightThrough,
devices: ['PC0','Switch0'],
},
{
type: ConnectionTypes.console,
devices: ['PC0','Switch0'],
},
],
canvas = $('#lines').get(0),
ctx = canvas.getContext("2d"),
connDotDist = 35;
function redrawConnections(){
ctx.canvas.width = window.innerWidth;
ctx.canvas.height =...