ko-jquery-visualstate.js DEMO

Knockout で逐次実行 visual effect を実装。 Visual State Binding と Sequencer を考案・利用。

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<script src="http://sukobuto.com/files/ko-jquery-visualstate.js"></script>
<h1>ko-jquery-visualstate.js DEMO</h1>
<h2>Sequencer と<br/>Visual State Binding で<br/>逐次 jQuery アニメーション</h2>
<p><a href="http://slide.sukobuto.com/article/ko-effect#/8/1" target="_blank">Visual State Binding</a> で逐次アニメーションをバインドするデモです。</p>
<p><a href="https://github.com/sukobuto/ko-jQueryVisualState" target="_blank">Github: ko-jquery-visualstate.js</a></p>
<label>
    <input type="checkbox" data-bind="checked: opened"/>
    Open/Close
</label>

<div class="wrapper" id="a" data-bind="visualState: { opened: opened }">
    <div class="container" id="b">
        <div class="item" id="c"></div>
        <div class="item" id="d"></div>
        <div class="item" id="e"></div>
    </div>
</div>

CSS

body {
    background: #578;
    color: #ccc;
}

.wrapper {
    padding: 20px;
    background: #79a;
    overflow: hidden;
    border-radius: 10px;
}

.container {
    padding: 20px;
    background: #9bc;
    overflow: hidden;
}

.item {
    background: #cef;
    width: 160px;
    height: 40px;
    margin: 20px;
}

JavaScript

//////////////// Viaual Effects ///////////////////
var $a = $('#a')
  , $b = $('#b')
  , $c = $('#c')
  , $d = $('#d')
  , $e = $('#e')
  , base_duration = 'fast'
  , wrapper_style = {
      shown: {
        width: 240,
        height: 240,
        padding: 20
      },
      hidden: {
        width: 0,
        height: 0,
        padding: 0
      }
    }
  , seq_open = new ko.jqvs.Sequencer([ // オープン用のアニメーションシーケンス
      function(next) { $a.stop().animate(wrapper_style.shown, {complete: next}) },
      function(next) { $b.stop().slideDown(base_duration, next) },
      function(next) { $c.stop().fadeIn(base_duration, next) },
      function(next) { $d.stop().animate({ height: 40 }, {complete: next}) },
      function(next) { $d.animate({ width: 160 }, {complete: next}) },
      function(next) { $e.stop().slideDown(base_duration, next) },
      function(next) { $c.animate({ borderRadius: 20 }, {complete: next}) },
      function(next) { $d.animate({ borderRadius: 20 }, {complete: next}) },
      function(next) { $e.animate({ borderRadius: 20 }, {complete: next}) },
      function(next) { $b.animate({ borderRadius: 120 }, {complete: next}) }
  ], 'seq_group_a')
  , seq_close = new ko.jqvs.Sequencer([ // クローズ用のアニメーションシーケンス
      function(next) { $b.stop().animate({ borderRadius: 0 }, {complete: next}) },
      function(next) { $c.stop().animate({ borderRadius: 0 }, {complete: next}) },
      function(next) { $d.stop().animate({ borderRadius: 0 }, {complete: next}) },
      function(next) { $e.stop().animate({ borderRadius: 0 }, {complete: next}) },
      function(next) { $e.slideUp(base_duration, next) },
      function(next) { $d.animate({ width: 0 }, next) },
      function(next) { $d.animate({ height: 0 }, next) },
      function(next) { $c.fadeOut(base_duration, next) },
      function(next) { $b.slideUp(base_duration, next) },
      function(next) { $a.stop().animate(wrapper_style.hidden, {complete: next}) }
  ], 'seq_group_a')
  ;
$('.wrapper')
   ...