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?
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', });
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With