Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJs - Animate number changes

Tags:

I'm looking to animate number changes using VueJs.

For example I have:

{{ number }} 

Then number changes from 0 to 100, I would like the element to count up to 100 rather than just jumping stright to it.

How would I do this without using any 3rd party (pure Js/VueJs) excluding VueJs?

like image 361
Ricky Barnett Avatar asked Feb 21 '16 02:02

Ricky Barnett


2 Answers

Got this working as a custom component: https://jsfiddle.net/5nobcLq0/5/

html

<body>   <input v-model="number">   <animated-number :number="number"></animated-number> </body> 

js

Vue.component('animated-number', {    template:"{{ displayNumber }}",   props: {'number': { default:0 }},    data () {     return {       displayNumber:0,       interval:false     }   },    ready () {     this.displayNumber = this.number ? this.number : 0;   },    watch: {     number () {       clearInterval(this.interval);        if(this.number == this.displayNumber) {         return;       }        this.interval = window.setInterval(() => {         if(this.displayNumber != this.number) {           var change = (this.number - this.displayNumber) / 10;           change = change >= 0 ? Math.ceil(change) : Math.floor(change);           this.displayNumber = this.displayNumber + change;         }       }, 20);     }   } })  new Vue({   el:'body', }); 
like image 189
Jeff Avatar answered Dec 15 '22 11:12

Jeff


I realize this is an older post, but I was looking for something similar and I found an example straight from the vue.js 2.0 documentation. You can find it here: https://vuejs.org/v2/guide/transitioning-state.html#Organizing-Transitions-into-Components

I've recreated it in the snippet below.

// This complex tweening logic can now be reused between  // any integers we may wish to animate in our application.  // Components also offer a clean interface for configuring  // more dynamic transitions and complex transition  // strategies.  Vue.component('animated-integer', {    template: '<span>{{ tweeningValue }}</span>',    props: {      value: {        type: Number,        required: true      }    },    data: function() {      return {        tweeningValue: 0      }    },    watch: {      value: function(newValue, oldValue) {        this.tween(oldValue, newValue)      }    },    mounted: function() {      this.tween(0, this.value)    },    methods: {      tween: function(startValue, endValue) {        var vm = this          function animate() {          if (TWEEN.update()) {            requestAnimationFrame(animate)          }        }        new TWEEN.Tween({            tweeningValue: startValue          })          .to({            tweeningValue: endValue          }, 500)          .onUpdate(function() {            vm.tweeningValue = this.tweeningValue.toFixed(0)          })          .start()        animate()      }    }  })  // All complexity has now been removed from the main Vue instance!  new Vue({    el: '#example-8',    data: {      firstNumber: 20,      secondNumber: 40    },    computed: {      result: function() {        return this.firstNumber + this.secondNumber      }    }  })
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>  <script src="https://cdn.jsdelivr.net/npm/tween.js"></script>  <div id="example-8">    <input v-model.number="firstNumber" type="number" step="20"> +    <input v-model.number="secondNumber" type="number" step="20"> = {{ result }}    <p>      <animated-integer v-bind:value="firstNumber"></animated-integer> +      <animated-integer v-bind:value="secondNumber"></animated-integer> =      <animated-integer v-bind:value="result"></animated-integer>    </p>  </div>

I hope that helps! Tim

like image 25
Tim Avatar answered Dec 15 '22 12:12

Tim