欢迎访问宙启技术站
智能推送

vue实现数字动态翻牌的效果(开箱即用)

发布时间:2023-05-14 15:08:14

数字动态翻牌效果是一种常见的UI展示效果,它可以使页面更加生动、有趣。本文将介绍如何使用Vue来实现数字动态翻牌效果,并提供一个开箱即用的代码实现。

一、效果预览

下面是本文实现的数字动态翻牌效果的预览,你可以通过点击“开始”按钮,观察数字翻牌的效果。

![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dea9faee09684d9a9b29d8d7dfad6a14~tplv-k3u1fbpfcp-zoom-1.image)

二、实现思路

数字动态翻牌效果的实现思路并不复杂,主要可以分为以下几个步骤。

1. 将数字转化为字符串,并将字符串按位拆分成数组。

2. 通过计算出需要翻牌的数字,得出每一位数字需要翻多少次才能达到目标数字。

3. 通过设置CSS动画,让每个数字位按照翻转次数逐渐翻转到目标数字。

以上就是实现思路的大致框架,接下来我们就可以开始具体的代码实现了。

三、代码实现

为了便于大家使用,将代码实现封装成了一个Vue组件,直接引入即可使用。

1. 先来看一下组件的HTML代码实现。

<template>
  <div class="flip-number">
    <a class="flip-item" v-for="(digit, index) in digits" :key="index" :class="getClass(index)">
      <span :class="[getNumberClass(digit), { down: isDown(index) }]"></span>
    </a>
  </div>
</template>

这里我们使用了Flexbox布局,将每个数字位(即一个翻牌单元)用a标签包裹,把每个位数的数字都拆分成了单独的span标签,为了实现数字的翻牌效果。

2. 接下来是CSS部分的代码实现。

.flip-number {
  display: flex;
}

.flip-item {
  position: relative;
  width: 40px;
  height: 60px;
  margin: 0 5px;
  border-radius: 5px;
  box-shadow: 0 5px 10px rgba(0, 0, 0, .1);
  background-color: #fff;
}

.flip-item span {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  color: #000;
  text-align: center;
  font-size: 40px;
  line-height: 60px;
  transform-style: preserve-3d;
  transition: transform .5s;
}

.flip-item span.up {
  transform: rotateX(180deg);
}

.flip-item span.down {
  transform: rotateX(-180deg);
}

.flip-item span.one {
  transform-origin: 50% 0;
}

.flip-item span.two {
  transform-origin: 50% 100%;
}

.flip-item span.three {
  transform-origin: 100% 0;
}

.flip-item span.four {
  transform-origin: 0 0;
}

这里设置了每个数字位和数字的样式,其中豆腐数字旋转的部分用到了transform-style: preserve-3dtransform: rotateX()这两个CSS属性。还需要注意的是,在设置上下数字翻转效果时,应该把锚点设置在数字的底部和顶部,这样才能保证数字翻转时底部和顶部不变形。

3. 最后是Vue组件的JavaScript代码实现。

<script>
const getDigits = number => {
  let str = number.toString();
  return str.split("");
};

export default {
  name: "FlipNumber",
  props: {
    number: {
      required: true,
      type: Number
    },
    length: {
      type: Number,
      default: 4
    }
  },
  data() {
    return {
      digits: [],
      target: [],
      count: []
    }
  },
  mounted() {
    this.digits = getDigits(this.number).reverse();
    this.target = new Array(this.length).fill(0);
    this.count = new Array(this.length).fill(0);
  },
  watch: {
    number() {
      let newDigits = getDigits(this.number).reverse();
      for (let i = 0; i < this.length; i++) {
        if (newDigits[i] !== this.digits[i]) {
          this.count[i] = 10;
        }
      }
      this.digits = newDigits;
      this.target = new Array(this.length).fill(0);
    }
  },
  computed: {
    getClass() {
      return index => {
        return {
          'flip-item-up': this.isUp(index),
          'flip-item-down': this.isDown(index)
        }
      }
    }
  },
  methods: {
    isUp(index) {
      return this.count[index] % 2 === 1;
    },
    isDown(index) {
      return this.count[index] % 2 === 0 && this.count[index] !== 0;
    },
    getNumberClass(digit) {
      return flip-digit flip-${digit};
    }
  },
  updated() {
    for (let i = 0; i < this.length; i++) {
      if (this.count[i] > 0) {
        this.count[i]--;
        this.target[i] = this.target[i] === 9 ? 0 : this.target[i] + 1;
      }
    }
  }
};
</script>

这里定义了一个FlipNumber组件,包括一个number属性和一个length属性。number属性是需要展示的数字,length属性是组件显示的数字位数,默认为4位。在组件mounted钩子中,通过调用getDigits方法将number属性拆分成位数放入digits数组中,将target数组初始化为了长度为length的全0数组。count数组用来表示每个数字需要翻转的次数,在mounted钩子中初始化为了全0数组。

在watch钩子中,当number属性改变时,需要比较新的数字和原来的数字有哪些位数不同。如果有位数不同,则把该数字位的count值设置为10,表示需要翻转10次才能达到目标数字。然后更新digits数组和target数组。在updated钩子中,通过循环count数组,如果count[i] > 0,则表示第i个数字位需要翻转,将count[i]减1,target[i]加1(此处需要注意的是,如果target[i]到达9,则需要变回0)。

四、使用方法

使用FlipNumber组件非常方便,只需要在父组件中引入FlipNumber组件,然后在模板中使用即可。如下所示:

<template>
  <div>
    <h2>数字翻牌效果</h2>
    <FlipNumber :number="number" />
    <button @click="start">开始</button>
  </div>
</template>

<script>
import FlipNumber from './components/FlipNumber.vue';

export default {
  name: 'App',
  components: {
    FlipNumber
  },
  data() {
    return {
      number: 1234
    }
  },
  methods: {
    start() {
      let timer = setInterval(() => {
        this.number = Math.floor(Math.random() * 10000);
      }, 1000);
    }
  }
}
</script>

在使用FlipNumber组件时,通过在模板中引入FlipNumber组件,并将需要展示的数字通过number属性传递给FlipNumber组件即可。上面的示例中,在按钮点击事件中通过Math.floor(Math.random() * 10000)这个方法不断地随机生成一个数,并将其赋值给number属性,实现了数字翻牌的动态效果。

五、总结

通过本篇文章的介绍,我们已经学习了如何使用Vue实现数字翻牌效果。我们使用了Vue的计算属性、watch和生命周期