如何写一个数字老虎机滚轮

需求描述

写一个数字滚轮,实现类似老虎机的效果,可以指定数字

实现思路

这个数字滚动组件的核心实现思路可以概括为:

  1. 视觉原理
  • 每个数字位用一个固定高度的容器,通过 overflow: hidden 只显示一个数字
  • 容器内部包含完整的 0-9 序列,通过上下平移显示不同数字
  • 重复放置首尾数字(0)实现无缝滚动效果
  1. 动画实现
  • 使用 CSS animation 实现两个关键动画:
    • 滚动中:无限循环向上平移实现滚动效果
    • 停止时:精确平移到目标数字的位置
  1. 控制逻辑
  • Vue 管理组件状态(rolling)控制动画切换
  • 通过 CSS 变量(--num)动态计算每个数字的最终停止位置
  • 使用 setTimeout 控制滚动持续时间

实现细节

页面结构

每一位数字都是这么个结构

滚动效果的实现

所谓的滚动其实就是那一长溜的数字不断重复从上到下或者从下到上这个操作,所以外层realtive,内层absolute,加上动画

那一长溜的数字最终的停止位置是需要根据这一位上的显示数字来确定的,因此需要动态算出来,在这个组件里面是下面标黄的来算

javascript 复制代码
<div
              :class="['TigerNumbers', rolling ? 'rolling' : 'stop']"
              :style="{ '--num': ((n || 10) - 10) * 1.5 + 'em' }"
      >

动画分为两种:

  • 滚动的动画。translateY从0到-100%,不断循环
css 复制代码
@keyframes NumberRoll {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-100%);
  }
}
  • 最终的停止动画。就是translateY从0到算出来的要停下来的位置
css 复制代码
@keyframes NumberStop {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(calc(var(--num)));
  }
}

数据设计

  • 用一个数组来存要显示的数字
  • 用一个rolling变量来标记现在是滚动状态还是停止滚动状态

组件代码

vue 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <script src="./js/vue.min.js"></script>
    <title>Title</title>
  </head>
  <body>
    <div id="vue_root">
      <div class="Tiger">
        <div v-for="(n, index) in numbers" :key="index" class="TigerItem">
          <div
            :class="['TigerNumbers', rolling ? 'rolling' : 'stop']"
            :style="{ '--num': ((n || 10) - 10) * 1.5 + 'em' }"
            >
            <div>0</div>
            <div>9</div>
            <div>8</div>
            <div>7</div>
            <div>6</div>
            <div>5</div>
            <div>4</div>
            <div>3</div>
            <div>2</div>
            <div>1</div>
            <div>0</div>
          </div>
        </div>
      </div>
    </div>
  </body>
  <script>
    let vm = new Vue({
      el: "#vue_root",
      data() {
        return {
          rolling: true,
          numbers: [5, 3, 8], // 你可以根据需要修改数字数组
          delaySec: 2, // 你可以根据需要修改 delaySec 的默认值
        };
      },
      mounted() {
        setTimeout(() => {
          this.rolling = false;
        }, this.delaySec * 1000);
      },
    })
  </script>
  <style>
    .Tiger {
      display: flex;
    }

    .TigerItem {
      width: 1em;
      height: 1.5em;
      position: relative;
      overflow: hidden;
      background-color: lightgreen;
      margin-right: 0.5em;
    }

    .TigerNumbers {
      position: absolute;
      width: 100%;
      text-align: center;
    }

    .TigerNumbers > div {
      line-height: 1.5em;
      height: 1.5em;
    }

    .TigerNumbers.rolling {
      animation: NumberRoll 0.3s infinite linear;
    }

    .TigerNumbers.stop {
      animation: NumberStop 0.6s forwards;
    }

    @keyframes NumberRoll {
      0% {
        transform: translateY(0);
      }
      100% {
        transform: translateY(-100%);
      }
    }

    @keyframes NumberStop {
      0% {
        transform: translateY(0);
      }
      100% {
        transform: translateY(calc(var(--num)));
      }
    }
  </style>
</html>

效果演示

相关推荐
Eiceblue1 小时前
【免费.NET方案】CSV到PDF与DataTable的快速转换
开发语言·pdf·c#·.net
m0_555762901 小时前
Matlab 频谱分析 (Spectral Analysis)
开发语言·matlab
像风一样自由20201 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem2 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊2 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
why技术2 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
GISer_Jing2 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止3 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall3 小时前
npm install安装的node_modules是什么
前端·npm·node.js
烛阴3 小时前
简单入门Python装饰器
前端·python