_.stagger

by Paulo Ávila

HTML

click me repeatedly&rarr; <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);
}());
//*/