JSFiddle - React, Tailwind, and code Playground

by Atinux

HTML

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]"></script>

<div id="app">
  <transition-group tag="ul" name="bounce" appear>
    <li v-for="(item, index) in list" class="goal" :key="index">
      <img :src="`http://lorempixel.com/100/150/abstract/?_=`+index">
      <h3>{{ item.name }}</h3>
      <animated-line :item="item"></animated-line>
    </li>
  </transition-group>
</div>

CSS

.goal {
  list-style-type: none;
  border: 1px #ddd solid;
  background: white;
  padding: 20px;
  float: left;
}
img {
  width: 100px;
  height: 150px;
}
.line {
  width: 100%;
  height: 5px;
}
.line-percent {
  background: #1c90f3;
  height: 100%;
}
.bounce-enter-active {
  animation: bounce-in .5s;
}
.bounce-leave-active {
  animation: bounce-out .5s;
}
@keyframes bounce-in {
  0% {
    transform: scale(0.5);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes bounce-out {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(0);
  }
}

JavaScript

Vue.component('animated-line', {
	template: `<div class="line">
  	<div class="line-percent" :style="{ 'width' : animatedWidth }"></div>
  </div>`,
  props: ['item'],
  data: function () {
  	return { animatedWidth: 0 };
  },
  mounted: function () {
    var vm = this
    var widthTo = (vm.item.badge_progress /  vm.item.badge_goal) * 100;
    function animate (time) {
      requestAnimationFrame(animate)
      TWEEN.update(time)
    }
    setTimeout(function () {
      new TWEEN.Tween({ tweeningNumber: vm.animatedWidth })
      .easing(TWEEN.Easing.Quadratic.Out)
      .to({ tweeningNumber: widthTo }, 1000)
      .onUpdate(function () {
        vm.animatedWidth = this.tweeningNumber.toFixed(0) + '%'
        console.log(vm.animatedWidth);
      })
    	.start()
		 	animate();
    }, 500);
  }
})

new Vue({
  el: '#app',
  data: {
		list: [{
    	name: 'Name #1',
      badge_progress: 30,
      badge_goal: 100
    }, {
    	name: 'Name #2',
      badge_progress: 50,
      badge_goal: 100
    }, {
    	name: 'Name #3',
      badge_progress: 90,
      badge_goal: 100
    }]
  }
})