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

需求描述

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

实现思路

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

  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>

效果演示

相关推荐
默海笑15 小时前
VUE后台管理系统:项目架构之搭建Layout架构解决方案与实现
前端·javascript·vue.js
咸鱼加辣15 小时前
【前端脚手架】node
前端
温宇飞15 小时前
WebGL 的渲染管道和编程接口
前端·webgl
csdn_aspnet15 小时前
C# 电子签名及文档存储
javascript·c#
IManiy15 小时前
Java表达式引擎技术选型分析(SpEL、QLExpress)
java·开发语言
帅的被人砍xxx15 小时前
【vue演练场安装 element-plus框架】
前端
历程里程碑15 小时前
C++ 17异常处理:高效捕获与精准修复
java·c语言·开发语言·jvm·c++
雨雨雨雨雨别下啦15 小时前
ssm复习总结
java·开发语言
麦麦大数据15 小时前
F051-vue+flask企业债务舆情风险预测分析系统
前端·vue.js·人工智能·flask·知识图谱·企业信息·债务分析
1024肥宅15 小时前
现代 JavaScript 特性:ES6+ 新特性深度解析与实践
前端·javascript·面试