VueJs - Animate number changes
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://v2.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
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',
});