前端切图学习-动画递增式计数看板

Incrementing Counter

Posted by R1NG on August 25, 2021 Viewed Times

动画递增式计数看板 Incrementing-Counter

1. 概述

项目本体为展示社交平台订阅数的看板. 在每次加载时订阅数会在 $1$ 秒内从 $0$ 递增到实际值.

本项目中涉及的知识点:

  1. JavaScript 中变量自增语法为 x = +x.
  2. JavaScript 中向上取整函数为 Math.ceil().

效果:

20210826215223.png


2. 结构和切图

网页的基本结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body>
    
    <div class="counter-container">
        <i class="fab fa-twitter fa-3x"></i>
        <div class="counter" data-target="12000"></div>
        <span>Twitter Followers</span>
    </div>


    <div class="counter-container">
        <i class="fab fa-youtube fa-3x"></i>
        <div class="counter" data-target="5000"></div>
        <span>Youtube Subscribers</span>
    </div>


    <div class="counter-container">
        <i class="fab fa-facebook fa-3x"></i>
        <div class="counter" data-target="7500"></div>
        <span>Facebook Fans</span>
    </div>

</body>

三个 div 容器承载图标, 订阅数字和描述文字, 共同组成网页的可视部分.


3. 编写 CSS 样式

首先定义容器样式:

1
2
3
4
5
6
7
8
9
10
11
.counter-container{
    display: flex;
    flex-direction: column;
    justify-content: center;
    text-align: center;
    margin: 30px 50px;
}
.counter {
    font-size: 60px;
    margin-top: 10px;
}

注意我们在调用 fontawesome 字体中的对应社交平台图标时已经指定了其大小.

随后简单规定 body 的排版方式和背景颜色:

1
2
3
4
5
6
7
8
9
10
11
body {
    background-color: #660099;
    color: #FFCC33;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
}

完整的 CSS 样式表如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
* {
    box-sizing: border-box;
}
body {
    background-color: #660099;
    color: #FFCC33;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
}
.counter-container{
    display: flex;
    flex-direction: column;
    justify-content: center;
    text-align: center;
    margin: 30px 50px;
}
.counter {
    font-size: 60px;
    margin-top: 10px;
}

@media (max-width: 680px) {
    body {
        flex-direction: column;
    }
}

注意在样式表的最后我们还简单设计了响应式布局: 在页面宽度小于 $680\text{px}$ 时将容器排布方式从横向改为纵向.


4. JavaScript

最后编写 JavaScript 函数, 注意高级循环 forEach 中匿名函数的定义方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const counters = document.querySelectorAll('.counter');

counters.forEach(counter => {
    counter.innerText = '0';

    const updateCounter = () => {
        const target = +counter.getAttribute('data-target');
        const c = +counter.innerText;

        const increment = target / 200;

        if (c<target) {
            counter.innerText = `${Math.ceil(c + increment)}`;
            setTimeout(updateCounter, 1);
        } else {
            counter.innerText = target;
        }
    }

    updateCounter();
})

最后, 完整的网页演示可见 此处