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

需求描述

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

实现思路

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

  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>

效果演示

相关推荐
高级程序源24 分钟前
django大学生创新创业项目管理系统94923-计算机课程设计、毕业设计
javascript·vue.js·spring boot·后端·python·django·课程设计
泡海椒30 分钟前
规则引擎对比:JQuick-Java vs Drools 轻量场景选型对比
java·开发语言
八荒启·交互动画36 分钟前
# Web特效020—让 Web 特效真正动起来:时间循环应该怎么接
前端·webgl·网页特效·八荒启-交互动画·八荒启
动恰客流统计37 分钟前
线下零售数字化浪潮下,客流统计的3个核心发展趋势
大数据·前端·人工智能
泡泡鱼(敲代码中)1 小时前
Python 容器类型学习笔记:列表、元组、字典、集合
开发语言·笔记·python·pycharm
lizz22761 小时前
Babel插件手册
javascript
2501_933670791 小时前
平台招商运营校招能力模型:数据分析、SQL与增长场景拆解
开发语言
用户938515635071 小时前
从小米前端面试题,彻底搞懂闭包、作用域链与 useState 惰性初始化
前端·面试
菜鸟~noob2332 小时前
【Bonjour】华为Peerium架构深度解析:从冯·诺依曼到百万处理器“一台计算机”,附MATLAB性能仿真【含matlab代码,可直接运行】
开发语言·matlab·华为·peerium
粥里有勺糖2 小时前
视野修炼第133期 | Native 回春了?
前端·github·agent