_.stagger
by Paulo Ávila
HTML
click me repeatedly→ <button id="stagger">Call Staggered Function</button>
<select>
<option value="500">0.5s</option>
<option value="1000">1s</option>
<option value="1200">1.2s</option>
<option value="rand()">rand( )</option>
</select>
<div id="timeline">
<span class="tick" data-wait="550" data-offset="0" style="transition-duration:550ms; transition-delay:0ms;"></span>
<span class="tick" data-wait="900" data-offset="550" style="transition-duration:900ms; transition-delay:550ms;"></span>
<span class="tick" data-wait="250" data-offset="1450" style="transition-duration:250ms; transition-delay:1450ms;"></span>
<span class="tick" data-wait="1600" data-offset="1700" style="transition-duration:1600ms; transition-delay:1700ms;"></span>
</div>
CSS
body {
font-family: monospace;
font-size: 10px;
}
#timeline {
position: relative;
height: 20px;
padding: 10px 0 2px 0;
border: 1px solid black;
}
.tick {
position: relative;
float: left;
margin: 1px;
width: 40px;
height: 100%;
font-family: monospace;
font-size: 9px;
background-color: lightgray;
/*transform: scaleY(1.0);
transform-origin: 0% 100%;*/
transform-origin: right;
transition-delay: calc(attr(data-wait) + attr(data-offset));
transition-duration: attr(data-offset) 'ms';
transition-property: all;
transition-timing-function: linear;
}
.tick::after {
content: attr(data-offset) 'ms';
position: absolute;
right: 2px;
bottom: -12px;
margin-right: -2px;
padding-right: 1px;
border-right: 1px solid black;
font-weight: bold;
}
.tick::before {
content: attr(data-wait) 'ms';
display: block;
position: relative;
top: -10px;
left: 1px;
}
.tick:hover,
.tick.close {
transform: scaleX(0);
/*width: 0;*/
}
.tick:hover::after,
.tick.close::after {
color: blue;
}
JavaScript
//$('.tick').addClass('close');
var OFFSET = 0;
$([0,0,0,0]).each(function (){
var $tick = $('<span class="tick">');
var min = 500;
var max = 2000;
var rand = Math.floor(Math.random() * (max - min + 1)) + min;
var ratio = (rand / max);
$tick.attr('data-wait', rand);
$tick.css('height', (ratio * 100)+'%');
$tick.css('transition-duration', rand+'ms');
$tick.attr('data-offset', OFFSET);
$tick.css('transition-delay', OFFSET+'ms');
//*
$tick.on('transitionend', function () {
console.log('done');
});
//*/
$('#timeline').append($tick);
OFFSET += rand;
});
/*
var PERCENT = $('#timeline').height();
var $current = $('.tick:nth-of-type(1)');
$current.on('transitionend', function () {
$current = $(this).next();
});
(function updatedWait() {
var progress = parseInt($current.css('height')) / PERCENT;
var wait = $current.attr('data-wait');
var updateTo = parseInt(wait * progress);
$current.attr('data-wait', updateTo);
console.log(progress, wait, updateTo);
if (wait > 0) requestAnimationFrame(updatedWait);
}());
//*/
/*
(function updatedWaits() {
var wait = $('.tick').attr('data-wait');
$('.tick').attr('data-wait', --wait);
if (wait > 0) requestAnimationFrame(updatedWaits);
}());
//*/