将 Vue 与 Tween JS 一起使用会使补间有时会重置

Using Vue with Tween JS makes tween sometimes reset

我正在尝试为我用 Vue.js 制作的计数器制作动画。

值正在由 Tween.js and then formatted with Numeral js 动画化,但我遇到了问题。

我想增加一个随机数,当我增加时,将数字从当前显示的数字动画化为新的总数。

我有 num 保存计数器的最终值,displayNum 保存动画值。

问题是我当前的代码(如果您按下增量按钮)有时会从 0 开始动画数字,而不是当前总数。尤其是当你超过 1,000 时。

我怎样才能阻止这种行为?

目前,无论何时单击增量,它都会获取当前显示的数字并开始一个新的补间到目标数字。

function animate(time) {
    requestAnimationFrame(animate);
    TWEEN.update(time);
}
requestAnimationFrame(animate);

var v = new Vue({
  'el' : '#app',
  'data' : {
    num : 0,
    displayNum : 0,
    tween : false
  },
  methods:{
    increment(){
      var vm = this;
      // select a random number and add it to our target
      vm.num += Math.round(Math.random() * 300);
      // create an object that we can use tween.js to animate
      var anim = { num: vm.displayNum };
      // if we are already animating, stop the animation
      if( vm.tween ){
        vm.tween.stop();
      }
      // create a new animation from the current number
      vm.tween = new TWEEN.Tween(anim)
        // to our new target
        .to({ num : vm.num }, 3000)
        .easing(TWEEN.Easing.Quadratic.Out)
        .onUpdate(function() {
        
          // Failed attempt to debug
          if( anim.num < vm.displayNum ){
            console.log("Something isn't right");
          }
          // on update, replace the display number with a rounded, formatted 
          // version of the animating number
          vm.displayNum = numeral(Math.round(anim.num)).format('0,0');
        })
        // if the tween ever stops, set the vm's current tween to 
        // false
        .onStop(function(){
          vm.tween = false;
        })
        .start();
    }
  }
})
html, body{
  height:100%;
}
body{
  display:flex;
  align-items:center;
  justify-content:center;
}
.window{
  width:200px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/r14/Tween.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>


<div id="app">
  <div class="window has-text-centered">
    <div class="is-size-1">
      <span v-html="displayNum"></span>
    </div>
    <div>
      <button class="button" @click="increment">Increment</button>
    </div>
    <div class="is-size-7">
      <span v-html="num"></span>
    </div>
  </div>
</div>

问题是您将字符串和整数混合在一起。首先,确保 displayNum 是模型上的字符串,然后在初始化动画时确保对其进行 parseInt,同时删除超过 999 时显示的逗号。

function animate(time) {
    requestAnimationFrame(animate);
    TWEEN.update(time);
}
requestAnimationFrame(animate);

var v = new Vue({
  'el' : '#app',
  'data' : {
    num : 0,
    displayNum : "0",
    tween : false
  },
  methods:{
    increment(){
      var vm = this;
      // select a random number and add it to our target
      vm.num += Math.round(Math.random() * 300);
      // create an object that we can use tween.js to animate
      var anim = { num: parseInt(vm.displayNum.replace(",","")) };
      // if we are already animating, stop the animation
      if( vm.tween ){
        vm.tween.stop();
      }
      // create a new animation from the current number
      vm.tween = new TWEEN.Tween(anim)
        // to our new target
        .to({ num : vm.num }, 3000)
        .easing(TWEEN.Easing.Quadratic.Out)
        .onUpdate(function() {
        
          // Failed attempt to debug
          //if( anim.num < vm.displayNum ){
          //  console.log("Something isn't right", anim, vm.displayNum);
          //}
          // on update, replace the display number with a rounded, formatted 
          // version of the animating number
          vm.displayNum = numeral(Math.round(anim.num)).format('0,0');
        })
        // if the tween ever stops, set the vm's current tween to 
        // false
        .onStop(function(){
          vm.tween = false;
        })
        .start();
    }
  }
})
html, body{
  height:100%;
}
body{
  display:flex;
  align-items:center;
  justify-content:center;
}
.window{
  width:200px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.6/numeral.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/r14/Tween.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>


<div id="app">
  <div class="window has-text-centered">
    <div class="is-size-1">
      <span v-html="displayNum"></span>
    </div>
    <div>
      <button class="button" @click="increment">Increment</button>
    </div>
    <div class="is-size-7">
      <span v-html="num"></span>
    </div>
  </div>
</div>