The large screen digital scrolling effect comes from a large screen UI diagram in the recent work. There is a module on the UI diagram that needs the effect of flipping numbers upward. The following is the final effect:

Train of thought

Before implementing this effect, let’s start with a mind map to design our implementation steps as follows:

The preliminary implementation

You can review elements and download digital background images


HTML structure

<div class="box">
  <p class="box-item">
    <span>1</span>
  </p>
</div>
Copy the code

The key of CSS

.box-item {
  position: relative;
  display: inline-block;
  width: 54px;
  height: 82px;
  /* Background image */
  background: url(./number-bg.png) no-repeat center center;
  background-size: 100% 100%;
  font-size: 62px;
  line-height: 82px;
  text-align: center;
}
Copy the code

After the above code is implemented, it should look like this:

Thinking: after the number in the background box, we now think about, the text in the background box, must be 0-9 before the number, in the premise of not disrupting the above HTML structure, how to make the number scroll up? At this point, we have reached a CSS property: writing-mode. Here is an introduction to its properties:

  • horizontal-tb: Default value for horizontal layout, from top to bottom.
  • vertical-lr: indicates vertical layout, from left to right.
  • vertical-rl: indicates vertical layout, from right to left.

It looks like this in real time:

Based on the above inspiration, we can achieve the following effect:

HTML changes:

<p class="box-item">
  <span>0123456789</span>
</p>
Copy the code

CSS changes:

.box-item {
  display: inline-block;
  width: 54px;
  height: 82px;
  background: url(./number-bg.png) no-repeat center center;
  background-size: 100% 100%;
  font-size: 62px;
  line-height: 82px;
  text-align: center;

  /* New part of the code */
  position: relative;
  writing-mode: vertical-lr;
  text-orientation: upright;
  /* overflow: hidden; * /
}
/* New part of the code */
.box-item span {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(50%);letter-spacing: 10px;
}
Copy the code

Calculate the scroll

If we want to scroll the number to 5, how much do we scroll? The answer is: scroll down -50%

What about the other numbers? Thanks to our special implementation method, there is a general formula for the rolling distance of each digit:

transform: `translate(-50%,-${number * 10}%) `
Copy the code

With the formula above, we scroll the number to 5, which looks like this:

CSS changes:

.box-item span {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translate(-50%,-50%);
  letter-spacing: 10px;
}
Copy the code

The implementation of rolling animation

Now that we know how far each number can roll, let’s design it so that the number can roll randomly:

js

setInterval((a)= > {
  let number = document.getElementById('Number')
  let random = getRandomNumber(0.10)
  number.style.transform = `translate(-50%, -${random * 10}%) `
}, 2000)
function getRandomNumber (min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min)
}

Copy the code

At this point, our digital scrolling effect has been preliminarily realized, and we will gradually improve this effect in the next section to meet business requirements.

perfect

In the previous section, we completed the initial rolling effect. In this section, we will design a common Vue business component based on the initial mind map

Accept parameters

This component accepts only one numeric parameter, which we put in the props of the Vue component:

props: {
  number: {
    type: Number.default: 0}}Copy the code

Fill a

Because our business requires that our maximum number of digits be 8 digits, we define a constant:

const MAX_LEN = 8
Copy the code

If the number of bits passed is less than 8, we need to add 0 to it. After completing the operation, we also need to convert it into the amount format

Because this part of the code is relatively common, in order to save space, the code will not be shown, you can write the relevant JS code.

Apply colours to a drawing

We use the above complementary strings to separate them into character arrays and render them in the page:

ComputeNumber: as a character array, such as: [‘ 0 ‘, ‘0’, ‘, ‘, ‘0’, ‘0’, ‘0’, ‘, ‘, ‘9’, ‘1’, ‘7’]

HTML part code:

<ul>
  <li
    :class="{'number-item': ! isNaN(item) }"
    v-for="(item,index) in computeNumber"
    :key="index"
  >
    <span v-if=! "" isNaN(item)">
      <i ref="numberItem">0123456789</i>
    </span>
    <span v-else>{{item}}</span>
  </li>
</ul>
Copy the code

CSS section code:

.number-item { width: 50px; background: url(./number-bg.png) no-repeat center center; background-size:100% 100%; & > span { position: relative; display: inline-block; margin-right: 10px; width: 100%; height: 100%; writing-mode: vertical-rl; text-orientation: upright; overflow: hidden; & > i { position: absolute; top: 0; left: 50%; transform: translate(-50%,0); The transition: 0.5 s ease - in-out transform; letter-spacing: 10px; }}}Copy the code

Page rendering effect:

Digital random growth, analog polling effect

Once the page has rendered, let’s scroll the numbers, designing two methods that need to be called in the increaseNumber Vue lifecycle Mounted function

// Time to grow the number
increaseNumber () {
  let self = this
  this.timer = setInterval((a)= > {
    self.newNumber = self.newNumber + getRandomNumber(1.100)
    self.setNumberTransform()
  }, 3000)},// Set the offset of each digit
setNumberTransform () {
  let numberItems = this.$refs.numberItem
  let numberArr = this.computeNumber.filter(item= > !isNaN(item))
  for (let index = 0; index < numberItems.length; index++) {
    let elem = numberItems[index]
    elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%) `}}Copy the code

Final effect: