Ractive Toolbar with Animations

Use Ractive animations for a floating toolbar

by vikikamath

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.7/semantic.min.css">
<main style="background: #ccc"></main>


<script id="list" type="text/ractive">
  <div class="container" on-click="clicked">
    <div class="ui tiny vertical list">
      <div class="item">
        <button class="circular ui settings icon button">
          <i class="icon settings"></i>
        </button>
        <div class="content">
          <div class="header">Settings</div>
        </div>
      </div>
      {{#active}} {{#items: i}}
      <div class="item" intro='fade:{ delay:{{ i*200 }}, duration:{{ i*100 }} }' outro='fade:{ delay:{{ (items.length - i)*200 }}, duration:{{ (items.length - i)*100 }} }'>
        <button class="circular ui {{.}} icon button">
          <i class="icon {{.}}"></i>
        </button>
        <div class="content">
          <div class="header">{{.}}</div>
        </div>
      </div>
      {{/items}} {{/}}
    </div>

</script>

CSS

body {
  background: #fafafa;
}

.container {
  position: relative;
}

.ui.tiny.vertical.list {
  position: absolute;
  top: 1rem;
  right: 2rem;
}


/*
@keyframes expand {
  0% {
    transform: scaleY(0.5);
  }
  
  50% {
    transform: scaleY(0.95);
  }
  100% {
    transform: scaleY(1);
  }
}

@keyframes compress {
  0% {
    transform: scaleY(1);
  }
  
  50% {
    transform: scaleY(0.75);
  }
  100% {
    transform: scaleY(1);
  }
}
.vertical.list.active {
  animation: expand 1s
}

.vertical.list{
  animation: compress 1s
}
*/

Babel + JSX

var DEFAULTS = {
  delay: 0,
  duration: 300,
  easing: 'linear'
};


function fade(t, params) {
  var targetOpacity;

  params = t.processParams(params, DEFAULTS);

  if (t.isIntro) {
    targetOpacity = t.getStyle('opacity');
    t.setStyle('opacity', 0);
  } else {
    targetOpacity = 0;
  }

  t.animateStyle('opacity', targetOpacity, params).then(t.complete);
}

new Ractive({
  el: 'main',
  template: '#list',
  transitions: {
    fade
  },
  data() {
    return {
      active: false,
      items: [
        'facebook', 'twitter', 'linkedin'
      ]
    }
  },
  oninit() {

    var self = this;

    self.on('clicked', () => {
      self.set('active', !self.get('active'));
    })
  }
})