2016-02-21 23 views
9

Sto cercando di animare le modifiche ai numeri usando VueJs.VueJs - Cambia numero di animazioni

Per esempio io ho:

{{ number }} 

Poi number cambia da 0 a 100, vorrei l'elemento di contare a 100 piuttosto che saltare dritto ad esso.

Come faccio a fare questo senza utilizzare terze parti (Js/VueJ puri) escluso VueJs?

+0

Ho iniziato a rispondere ma sono diretto verso la notte. Ecco a cosa stavo lavorando: https://jsfiddle.net/5nobcLq0/1/ Fondamentalmente, l'idea è di mantenere il numero separato dal numero visualizzato, e se sono diversi incrementano il numero di visualizzazione verso il numero reale. Penso che idealmente questo sarebbe un componente a sé stante, o una direttiva come 'v-animate'. Lo guarderò più domani – Jeff

+0

Ho dato un'occhiata a v-animate ma non ho trovato nulla che potesse aiutarmi – user3662307

risposta

16

ottenuto questo lavoro come un componente personalizzato: 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: function(){ 

    return { 

     displayNumber:0, 
     interval:false 

    } 

    }, 

    ready:function(){ 

    this.displayNumber = this.number ? this.number : 0; 

    }, 

    watch:{ 

    number: function(){ 

     clearInterval(this.interval); 

     if(this.number == this.displayNumber){ 
      return; 
     } 

     this.interval = window.setInterval(function(){ 

      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; 

      } 

     }.bind(this), 20); 

    } 

    } 
}) 

new Vue({ 

    el:'body', 

}); 
+0

Grazie, questo era esattamente quello che stavo cercando! – user3662307

+0

saresti in grado di aggiustarlo per supportare i decimali? Attualmente se il numero non è intero sfarfalla e salta su e giù – user3662307

+0

la riga 'change = change> = 0? Math.ceil (modifica): Math.floor (modifica); 'utilizza' Math.floor' e 'Math.ceil' per arrotondare il cambiamento. Basta rimuovere quella linea e dovrebbe funzionare. Puoi invece arrotondare a un determinato numero di decimali. – Jeff

3

Mi rendo conto che questo è un posto più vecchio, ma ero alla ricerca di qualcosa di simile e ho trovato un esempio direttamente dalla documentazione di vue.js 2.0. Puoi trovarlo qui: https://vuejs.org/v2/guide/transitioning-state.html#Organizing-Transitions-into-Components

L'ho ricreato nello snippet qui sotto.

// 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>

Mi auguro che aiuta! Tim

+0

Si potrebbe voler considerare l'utilizzo di questo. $ NextTick piuttosto che requestAnimationFrame, poiché è integrato nel processo di aggiornamento dom di VueJs. – BenjaminEllis

+0

Ciao @ BenjaminEllis, ho appena copiato l'esempio dai documenti vue.js 2.x. Quindi forse c'è un motivo per usare requestAnimationFrame, altrimenti assumerei che lo avrebbero usato nell'esempio? – Tim