<h1>Velocity.js <i>sequence</i></h1>
<pre>Click <b><u>popular photos</u></b> to trigger loading + sequence
<span>v1.4 &ndash; Added performance test Transit.js/Velocity.js. Check JS source for more.</span>
</pre>
<div id="btn"><i onclick="init(true);">Re-run initial</i> <i onclick="demo();">Demo loop (infinite)</i> <i onclick="window.location=window.location">Reload pen</i></div>

<div id="boxes">
   
  <div class="box">
    
    <img class="boxImage" src="https://farm8.staticflickr.com/7328/9000198669_57003f7505_n.jpg">
    <img class="buddy" src="https://farm4.staticflickr.com/3932/buddyicons/43830692@N04_r.jpg?1413100041#43830692@N04">
    
    <div class="inner">
      <h3><a href="http://www.flickr.com/photos/tommiehansen/" title="Visit photostream" target="_blank">Tommie Hansen</a></h3>
      <span>Stockholm, Sweden</span>

      <i class="fa fa-eye" title="Views"> 9841</i>
      <i class="fa fa-image" title="Number of images"> 412</i>
      
      <i class="btn openPop">Popular photos</i>
    </div>
    
    <div class="pop">
      <i class="close">&times;</i>
      <h3><i>Tommie Hansen's</i>Popular photos</h3>
        <img src="http://farm8.static.flickr.com/7390/12980175743_5cb04727f3_q.jpg">
        <img src="http://farm4.static.flickr.com/3679/12980129103_edbea2fca4_q.jpg">
        <img src="http://farm6.static.flickr.com/5497/14367491417_563fcbc6a9_q.jpg">
        <img src="http://farm3.static.flickr.com/2573/12980150413_6982593c38_q.jpg">
      <a href="http://www.flickr.com/photos/tommiehansen/" target="_blank">Visit flickr photostream</a><!-- yes, target is evil -->
    </div>
    
  </div>
  
  <div class="box">
    
    <img class="boxImage" src="https://farm8.staticflickr.com/7328/9000198669_57003f7505_n.jpg">
    <img class="buddy" src="https://farm4.staticflickr.com/3932/buddyicons/43830692@N04_r.jpg?1413100041#43830692@N04">
    
    <div class="inner">
      <h3><a href="http://www.flickr.com/photos/tommiehansen/" title="Visit photostream" target="_blank">Tommie Hansen</a></h3>
      <span>Stockholm, Sweden</span>

      <i class="fa fa-eye" title="Views"> 9841</i>
      <i class="fa fa-image" title="Number of images"> 412</i>
      
      <i class="btn openPop">Popular photos</i>
    </div>
    
    <div class="pop">
      <i class="close">&times;</i>
      <h3><i>Tommie Hansen's</i>Popular photos</h3>
        <img src="http://farm8.static.flickr.com/7390/12980175743_5cb04727f3_q.jpg">
        <img src="http://farm4.static.flickr.com/3679/12980129103_edbea2fca4_q.jpg">
        <img src="http://farm6.static.flickr.com/5497/14367491417_563fcbc6a9_q.jpg">
        <img src="http://farm3.static.flickr.com/2573/12980150413_6982593c38_q.jpg">
      <a href="http://www.flickr.com/photos/tommiehansen/" target="_blank">Visit flickr photostream</a><!-- yes, target is evil -->
    </div>
    
  </div>
  
  
  
</div><!-- /#boxes -->


<div id="loop"><p>perf test</p><i onclick="execTransit($(this));">Start Transit.js loop</i> <i onclick="execVelocity($(this));">Start Velocity.js loop</i></div>
/* + Reset.css */
/* + Open Sans @ Google Fonts */
/* + FontAwesome.css */

/* defaults */

html,body { min-height:100%; }
body { font-family:"Open Sans", helvetica,arial,sans-serif; font-size:13px; line-height: 160%; font-weight: 300; color: #444; background: #eee; }
*,*:before,*:after { box-sizing: border-box; } img { display:block; } i { font-style:normal; } em { font-style:italic; } img { display:block; }

/* Refresh, add boxes etc */
#a { position:absolute; top:20px; right:20px; display: block; background: #eee; color:#aaa; -webkit-user-select: none; user-select: none; } #a i { cursor: pointer; font-size:11px; padding:8px 10px; border:1px dotted #ccc; transition:all .12s; margin-left:-1px; }
#a .fa { font-family: "Open Sans", sans-serif; }
#a .fa:last-child { background:#d00; border-color:#d00; color:#fff; }
#a .fa:last-child:hover { background: #a00; border-color: #a00; }
b { font-weight:400; }

#btn { text-align: center; margin-top:-30px; }
#btn i, #loop i { cursor:pointer; background: hotpink; color:#fff; padding:0 14px; margin:0 2px; line-height:250%; display:inline-block; transition:all .2s ease; border-radius:2px;  }
#loop i { background: #aaa; }
#btn i:hover, #loop i:hover { background:#333; }
#loop i { display: inline-block; }
#loop i.off { background: #ccc; }
#loop i.on { background: #0c0; }
#loop { text-align:center; }
#loop p { margin: 0 0 9px; font-size:11px; text-transform:uppercase; }

/* ----- end defaults ---- */

/* Main layout */
#boxes, h1, pre { width: 660px; margin: 40px auto; text-align:center; position: relative; }
#boxes { width:auto; max-width: 850px; text-align:center; }

/*#boxes, .box  { transform: translate3d(0,0,0); }*/

/* Headers */
h1,h2 { font-size: 21px; line-height:100%; font-weight:300; }
h1 { font-size: 24px; font-weight: 700; border-bottom:1px solid #ccc; }
h1 i { font-weight: 300; }
h3 { font-size: 21px; white-space: nowrap; width: auto; overflow: hidden; text-overflow:ellipsis; display:block; color: #111; }
a { color: #111; text-decoration:none; }
a:hover { color: #111;  }

pre { display:block; margin-top:-25px; text-transform: uppercase; color:#888; font-size:11px; letter-spacing:.5px; }
pre i { cursor:help; display:inline-block; margin: 0 0 0 3px; }
pre i:hover { color:#222; }
pre span { color:#aaa; display:block; letter-spacing:0; }



/* Paddings / Margins */
h1 { padding: 20px 0; }
h3 { margin:0 0 5px; }
.box { margin: 0 15px 30px; } /* inline-block adds +4px margin */
.inner { padding:15px; margin-top:56px; }
.btn { padding:12px 0; width:100%; margin: 45px 0 0; }
.fa { margin:15px 0 0; padding:5px 8px; }

/* Boxes */
.box {
  overflow: hidden;
  width:320px;
  text-align:left;
  display:inline-block;
  position:relative;
  
  border: 1px solid #ddd;
  border-bottom: 1px solid #bbb;
  background: #fff;
  border-radius: 3px;
}

.fa { color:#999; font-family:"FontAwesome", "Open Sans", sans-serif; font-weight:100; font-size:12px; cursor:help; word-spacing:2px; }
.fa:hover { color: #666; }
.box span { display:block; color:#999; }
.inner { text-align: center; }
.boxImage { border-top-left-radius:3px; border-top-right-radius:3px; width:100%; }

.buddy {
  position:absolute; z-index:2;
  width:96px; height:96px;
  left:50%;
  margin: -48px 0 0 -48px;
  border-radius:50%;
}

.btn {
  text-transform: uppercase;
  background-color: #5677fc; color: #fff;
  text-decoration:none;
  border-radius:3px;
  border-bottom:1px solid #3b50ce;
  display:inline-block;
  cursor:default;
  transition:background-color .2s ease;
}
.btn:hover { background-color: #3b50ce; }


/* Pop photos */
.close { position:absolute; top:0; right:0; color:#999; font-size: 24px; cursor:default; padding:15px 20px; z-index:10; }
.close:hover { color:#111; }

.pop {
  position:absolute; top:0; left:0; z-index:3;
  width:100%; height:100%;
  text-align:center;
  border-radius:3px;
  background: #fff;
  border-radius:3px; padding:30px 0 0;
  padding:15px;
}

.pop h3 { margin: 0 0 30px; line-height:150%; }
.pop h3 i { font-size: 12px; text-transform: uppercase; color: #999; line-height:100%; display:block; margin: 10px 0 0; }



.pop img { width: 125px; height:125px; display:inline-block; margin:0 7px 11px; border-radius: 3px; }
.pop a { margin-top:15px; color:#999; display:block; text-decoration:none; }
.pop a:hover { color:#000; }


/* Initial display styles */
.pop { opacity:0; display: none; }
.pop img { opacity:0; }

.box, .buddy { opacity:0; }

/* Backface fix */
.box, .buddy, .pop, .pop img, .btn { backface-visibility: hidden; }
/*
  + jquery.js
  + velocity.js
  + velocity.ui.js
*/

/* -----------------------------------------------------

VELOCITY.JS SEQUENCE

Animation with sequence.

For basic usage of using Velocity sequence go to:
http://julian.com/research/velocity/#uiPack

v1.4
- Added performance test. Transit.js + Velocity.js

v1.3
- Added button pressed animation
- Added Reload pen button

v1.2
- Added demo loop sequence in order to easier measure performance, paints etc.
- Added demo loop trigger (button)

v1.1
- Added Re-run button
- Changed animation duration: 650ms > 550ms

----------------------------------------------------- */




// Define base div
var
  boxes = $('#boxes'),
  box = boxes.find('.box');



/* -----------------------------------------------------
SET SOME ANIMATION DEFAULTS
----------------------------------------------------- */

var
  aniDuration = 550,
  aniEase = [0.075, 0.82, 0.165, 1];
  //aniEase = 'easeOutCirc',
  aniEaseOut = [0.6, 0.04, 0.98, 0.335];
  //aniEaseOut = 'easeInCirc';



/* -----------------------------------------------------
REGISTER CUSTOM TRANSITIONS
----------------------------------------------------- */

// short helper str.endsWith()
if(typeof String.prototype.endsWith != 'function') { String.prototype.endsWith = function (str) { return this.slice(-str.length) == str; }; }

// personal velocity.js small helper
function newTrans(name,fx){
  var ease, dur;
  if(name.endsWith('In')) {
    ease = aniEase;
    dur = aniDuration;
    fx.opacity = [1,0]; // forcefeed opacity
  }
  else {
    dur = aniDuration/1.66;
    ease = aniEaseOut; // aniEase/Out set elsewhere
    fx.opacity = 0;
  }
  
  // fx.translateZ = 0; // add to object
  
  $.Velocity.RegisterUI(name, {
    defaultDuration: dur,
    calls: [[ fx, aniDuration/1000, { easing: ease } ]]
  });
  
} //end newTrans()

newTrans('custom.slideUpIn', { translateY: [0,100] });
newTrans('custom.slideDownIn', { translateY: [0,-100] });
newTrans('custom.slideUpOut', { translateY: -100 });
newTrans('custom.slideDownOut', { translateY: 100 });
newTrans('custom.scaleIn', { scale: [1, 0.3] });
//newTrans('custom.scaleOut', { scale: 0.3 });
//newTrans('custom.slideRightIn', { translateX: [0,330] });


function seq(el,el2){
  var vSequence = [
    { elements: el, properties: 'custom.slideUpIn' },
    { elements: el2, properties: 'custom.slideDownIn', options: { stagger: 120 } }
  ];
  $.Velocity.RunSequence(vSequence);
}


/* -----------------------------------------------------
INITIAL TRANSITION
----------------------------------------------------- */

//box.velocity('custom.slideUpIn', { display: false, delay:500, stagger: 120 }); // set display: false to not trigger layout
var buddy = box.find('.buddy');


// SEQUENCES
var seqInit = [
    { elements: box, properties: 'custom.slideUpIn', options: { display: false, delay: 300, stagger: 120 } },
    { elements: buddy, properties: 'custom.slideUpIn', options: { display: false, delay: 60, stagger: 120, sequenceQueue: false } }
];

var seqClick = [
    { elements: box, properties: 'custom.slideDownOut', options: { display: false, stagger: 120, backwards: true } },
    { elements: buddy, properties: 'fadeOut', options: { display: false, duration: 0 } }, // ugly
    { elements: box, properties: 'custom.slideUpIn', options: { display: false, delay: 300, stagger: 120 } },
    { elements: buddy, properties: 'custom.slideUpIn', options: { display: false, delay: 60, stagger: 120, sequenceQueue: false }
    }
];

var pop = $('.pop');
var open = $('.openPop');
var close = $('.close');

var demoLoop = [
    { elements: box, properties: 'custom.slideDownOut', options: { display: false, stagger: 120, backwards: true } },
    { elements: buddy, properties: 'fadeOut', options: { display: false, duration: 0 } }, // ugly
    { elements: box, properties: 'custom.slideUpIn', options: { display: false, delay: 300, stagger: 120 } },
    { elements: buddy, properties: 'custom.slideUpIn', options: { display: false, delay: 60, stagger: 120, sequenceQueue: false } },
  
    { elements: open[0], properties: { scale: 0.9 }, options: { duration: 60 } },
    { elements: open[0], properties: { scale: 1 }, options: { duration: 60 } },
    { elements: open[0], properties: 'custom.slideDownOut', options: { display:false } },
    { elements: pop[0], properties: 'custom.slideUpIn' },
    { elements: pop.first().find('img'), properties: 'custom.scaleIn', options: { stagger: 30 } },
  
    { elements: open[1], properties: { scale: 0.9 }, options: { duration: 60 } },
    { elements: open[1], properties: { scale: 1 }, options: { duration: 60 } },
    { elements: open[1], properties: 'custom.slideDownOut', options: { display:false, sequenceQueue: false } },
    { elements: pop[1], properties: 'custom.slideUpIn' },
    { elements: pop.last().find('img'), properties: 'custom.scaleIn', options: { stagger: 30 } },
  
    { elements: pop, properties: 'custom.slideDownOut', options: { delay:500, stagger:120 } },
    { elements: open, properties: 'custom.slideUpIn', options: { stagger:120 } },
    { elements: pop.find('img'), properties: 'fadeOut', options: { duration: 0, delay: 1000, display: false, complete: function(){ demo(); } } }
];

function init(rerun){
if(!rerun){
    $.Velocity.RunSequence(seqInit);
  }
else {
    $.Velocity.RunSequence(seqClick);
  }
}

init(); // run initial sequence


/* -----------------------------------------------------
REGISTER CLICK EVENTS FOR BUTTONS
----------------------------------------------------- */

boxes.on('click', '.close', function(){
  var pop = $(this).parent(),
      img = pop.find('img'),
      openPop = pop.parent().find('.openPop');
 
  
  //pop.velocity('custom.slideDownOut', function(){ img.css('opacity', 0); });
  var seq = [
    { elements: pop, properties: 'custom.slideDownOut' },
    { elements: openPop, properties: 'custom.slideUpIn' },
    { elements: img, properties: 'fadeOut', options: { duration: 0, display: false } }
  ];
  $.Velocity.RunSequence(seq);
  
})

boxes.on('click', '.openPop', function(){
  var pop = $(this).parents('.box').find('.pop');
  var img = pop.find('img');
  var t = $(this);
  var seq = [
    { elements: t, properties: { scale: 0.9 }, options: { duration: 60 } },
    { elements: t, properties: { scale: 1 }, options: { duration: 60 } },
    { elements: t, properties: 'custom.slideDownOut', options: { display:false } },
    { elements: pop, properties: 'custom.slideUpIn' },
    //{ elements: img, properties: 'custom.slideDownIn', options: { stagger: 60 } }
    { elements: img, properties: 'custom.scaleIn', options: { stagger: 30, display: false } }
  ];
  $.Velocity.RunSequence(seq);
})


function demo(){
  $.Velocity($('*'), "stop");
  $.Velocity.RunSequence(demoLoop);
}




// Perf testing
function transit(){
  box.each(function(i){
    var t = $(this);
    t
    .transition({ y: -150, opacity: 0, duration: 500, delay: 120*i, easing: 'cubic-bezier(0.6, 0.04, 0.98, 0.335)' })
    .transition({ y: 0, opacity: 1, duration: 500, delay: 0, easing: 'cubic-bezier(0.075, 0.82, 0.165, 1)' });
  })
}

function vTest(){
  box.each(function(i){
    var t = $(this);
    t
    .velocity({ translateY: -150, opacity: 0 }, { duration: 500, delay: 120*i, easing: [0.6, 0.04, 0.98, 0.335] })
    .velocity({ translateY: 0, opacity: 1 }, { duration: 500, delay: 0, easing: [0.075, 0.82, 0.165, 1] })
  })
};

var loopy;
var loopi = $('#loop').find('i');

function execTransit(e){
  loopi.addClass('off').removeClass('on');
  e.removeClass('off').addClass('on');
  clearInterval(loopy);
  loopy = setInterval(function(){
    transit();
  }, 1500)
}

function execVelocity(e){
  loopi.addClass('off').removeClass('on');
  e.removeClass('off').addClass('on');
  clearInterval(loopy);
  loopy = setInterval(function(){
    vTest();
  }, 1500)
}

External CSS

  1. https://fonts.googleapis.com/css?family=Open+Sans:400,300,700
  2. https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
  2. https://cdn.jsdelivr.net/velocity/1.1.0/velocity.min.js
  3. https://cdn.jsdelivr.net/velocity/1.1.0/velocity.ui.min.js
  4. https://ricostacruz.com/jquery.transit/jquery.transit.min.js