Как добавить анимацию подсчета внутри компонента?


Как добавить анимацию подсчета внутри компонента?

10.11.2020 12:30:54 Просмотров 48 Источник

У меня есть проект Vue2 с простым компонентом, отображающим результаты двух команд. Этот компонент способен принимать текущий счет и счет из последней игры в качестве реквизита (оба числа всегда будут положительными целыми числами). Таким образом, легко вычислить предыдущие баллы. Вместо того чтобы напрямую отображать текущий счет, я хотел бы добавить анимацию подсчета.

Это то, что у меня есть до сих пор

<template>
  <div>{{ firstTeamCounterValue }} - {{ secondTeamCounterValue }}</div>
</template>

<script>
export default {
  props: {
    firstTeamCurrentScore: {
      type: Number,
      default: 0,
    },
    secondTeamCurrentScore: {
      type: Number,
      default: 0,
    },
    firstTeamMapScore: {
      type: Number,
      default: 0,
    },
    secondTeamMapScore: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      firstTeamCounterValue: 0,
      secondTeamCounterValue: 0,
    };
  },
  created() { // do this for the first run
    this.countUpScores();
  },
  updated() { // do this whenever the props change (score changed)
    this.countUpScores();
  },
  methods: {
    countUpScores() {
      this.firstTeamCounterValue = this.firstTeamPreviousScore;
      this.secondTeamCounterValue = this.secondTeamPreviousScore;

      const countUpInterval = setInterval(() => {
        const firstTeamCurrentScoreReached = this.firstTeamCounterValue === this.firstTeamCurrentScore;
        const secondTeamCurrentScoreReached = this.secondTeamCounterValue === this.secondTeamCurrentScore;

        if (firstTeamCurrentScoreReached && secondTeamCurrentScoreReached) {
          // stop
          clearInterval(countUpInterval);
        } else {
          if (!firstTeamCurrentScoreReached) {
            this.firstTeamCounterValue += 1;
          }

          if (!secondTeamCurrentScoreReached) {
            this.secondTeamCounterValue += 1;
          }
        }
      }, 200);
    },
  },
  computed: {
    firstTeamPreviousScore() {
      return this.firstTeamCurrentScore - this.firstTeamMapScore;
    },
    secondTeamPreviousScore() {
      return this.secondTeamCurrentScore - this.secondTeamMapScore;
    },
  },
};
</script>

При запуске приложения я сдаю начальные баллы. Позже реквизит меняется. К сожалению, просто ничего не происходит. Нет никакой анимации подсчета.

У кого-нибудь есть идея, как заставить его работать?

Я немного разбираюсь в CSS. Если вы думаете, что я не должен использовать код для этого, пожалуйста, дайте мне знать! Но я не знаю, как бы я запускал CSS-анимацию и передавал необходимые значения всякий раз, когда срабатывал крючок обновления.

У вопроса есть решение - Посмотреть?

Ответы - Как добавить анимацию подсчета внутри компонента? / How to add a count up animation inside a component?

Является ответом!
lepak

12.11.2020 01:23:42

Вы могли бы наблюдать за своим реквизитом и иметь непрерывный интервал, который увеличивает значения вашего счетчика только тогда, когда это необходимо.

<template>
  <div>{{ firstTeamCounterValue }} - {{ secondTeamCounterValue }}</div>
</template>
 
<script>
export default {
  props: {
    firstTeamCurrentScore: {
      type: Number,
      default: 0,
    },
    secondTeamCurrentScore: {
      type: Number,
      default: 0,
    },
    firstTeamMapScore: {
      type: Number,
      default: 0,
    },
    secondTeamMapScore: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      firstTeamCounterValue: 0,
      secondTeamCounterValue: 0,
      firstValueToReach: 0,
      secondValueToReach: 0,
      countInterval: null,
    };
  },
  mounted() {
    this.firstValueToReach = this.firstTeamCurrentScore;
    this.secondValueToReach = this.secondTeamCurrentScore;
    this.countInterval = setInterval(() => {
      if (this.firstValueToReach > this.firstTeamCounterValue) {
        this.firstTeamCounterValue += 1;
      }
      if (this.secondValueToReach > this.secondTeamCounterValue) {
        this.secondTeamCounterValue += 1;
      }
    }, 50);
  },
  unmounted() {
    clearInterval(this.countInterval);
  },
  watch: {
    firstTeamCurrentScore: function (val) {
      this.firstValueToReach = val;
    },
    secondTeamCurrentScore: function (val) {
      this.secondValueToReach = val;
    },
  },
};
</script>
Nino Filiu

13.11.2020 12:02:53

Вот что вам нужно:

  • Свойство данных displayedCount, которое "следует" за опорой count
  • Это метод change...
    • ... инкремент или декремент displayedCount в зависимости от того, находится ли count выше или ниже его
    • ... называет себя рекурсивно
    • ...не вызывает себя, когда displayedCount достиг count
  • Вызов метода change при создании элемента
  • Вызов change методов всякий раз, когда count опора обновление

Вы можете найти способы заставить его работать с setInterval, но я нахожу, что рекурсивный setTimeout здесь лучше.

Вот какой-то рабочий код. Обновите числовое значение во входных данных и наблюдайте за числом, отображаемым count0, сделайте анимацию подсчета:

count1
count2

В своем вопросе вы просили, чтобы один компонент отслеживал два балла. Я нахожу более элегантным иметь один компонент count0, отслеживающий один балл, и, возможно, другой компонент count4, отслеживающий два балла, используя два компонента count0 внутри. Эта часть тривиальна и поэтому я позволю вам сделать это ;)

Помочь в развитии проекта:
Закрыть X