JSFiddle - React, Tailwind, and code Playground
by john_s
HTML
<div id="diagram">
<img id="clientIcon" src="https://cdn3.iconfinder.com/data/icons/streamline-icon-set-free-pack/48/Streamline-04-48.png"/>
<img id="networkIcon" src="https://cdn1.iconfinder.com/data/icons/ecqlipse2/NETWORK%20-%20LAN.png" />
<img id="serverIcon" src="https://cdn3.iconfinder.com/data/icons/streamline-icon-set-free-pack/48/Streamline-04-48.png" />
<div id="laneContainer">
</div>
</div>
<div>
Speed (ms):
<input type="number" id="speed" value="500" /><br />
Packets:
<input type="number" id="packets" value="1" /><br />
<button type="button" id="apply">Apply!</button>
</div>
CSS
#diagram {
position: relative;
margin: 10px;
width: 600px;
}
#clientIcon {
position: absolute;
left: 0px;
width: 50px;
height: 50px;
}
#networkIcon {
position: absolute;
left: 275px;
width: 50px;
height: 50px;
}
#serverIcon {
position: absolute;
left: 550px;
width: 50px;
height: 50px;
}
#laneContainer {
position: absolute;
left: 55px;
width: 490px;
}
.lane {
position: absolute;
width: 100%;
height: 20px;
border: 1px dashed gray;
opacity: 0.5;
z-index: -1;
}
.data {
position: absolute;
width: 20px;
height: 20px;
left: 5px;
text-align: center;
vertical-align: middle;
background-color: lightgreen;
}
JavaScript
var $diagram = $('#diagram'),
$laneContainer = $('#laneContainer'),
$dataContainer = $('#dataContainer');
function udpateLanes(count) {
$laneContainer.empty();
for (var i = 0; i < count; i++) {
var $lane = $('<div class="lane"></div>').css({ top: (20 * i) + 'px' });
$laneContainer.append($lane);
}
$diagram.animate({ height: (count * 20 + 20) + 'px' }, 'fast');
}
$('#apply').click(function() {
var $button = $(this),
speed = parseInt($("#speed").val(), 10),
dataCount = parseInt($("#packets").val(), 10),
downDuration = (speed/4) * dataCount;
$button.prop('disabled', true);
udpateLanes(dataCount * 2);
var $datas = $();
for (var i = 0; i < dataCount; i++) {
$datas = $datas.add($('<div class="data"><span>' + (i + 1) + '</span></div>').css({ top: (20 * i) + 'px' }));
}
$datas.hide().appendTo($laneContainer);
$datas.fadeIn();
$datas.animate({ left: '+=230px' }, speed);
$datas.animate({ left: '+=230px' }, speed);
$datas.queue(function(next) {
$(this).children().fadeOut((downDuration / 2), function() {
$(this).text(function(i, text) { return 'a' + text; });
}).fadeIn((downDuration / 2));
next();
});
$datas.animate({ top: '+=' + (20 * dataCount) + 'px', backgroundColor: '#f09090' }, downDuration);
$datas.animate({ left: '-=230px' }, speed);
$datas.animate({ left: '-=230px' }, speed);
$datas.fadeOut();
$datas.promise().done(function() {
$("#packets").val(dataCount * 2);
udpateLanes(dataCount * 4);
$button.prop('disabled', false);
});
});
udpateLanes(2);