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

需求描述

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

实现思路

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

  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>

效果演示

相关推荐
摸鱼了14 分钟前
🚀 从零开始搭建 Vue 3+Vite+TypeScript+Pinia+Vue Router+SCSS+StyleLint+CommitLint+...项目
前端·vue.js
程序员shen16161125 分钟前
抖音短视频saas矩阵源码系统开发所需掌握的技术
java·前端·数据库·python·算法
小老鼠不吃猫28 分钟前
力学笃行(二)Qt 示例程序运行
开发语言·qt
长潇若雪29 分钟前
《类和对象:基础原理全解析(上篇)》
开发语言·c++·经验分享·类和对象
Ling_suu1 小时前
SpringBoot3——Web开发
java·服务器·前端
Yvemil71 小时前
《开启微服务之旅:Spring Boot Web开发》(二)
前端·spring boot·微服务
hanglove_lucky1 小时前
本地摄像头视频流在html中打开
前端·后端·html
维李设论1 小时前
Node.js的Web服务在Nacos中的实践
前端·spring cloud·微服务·eureka·nacos·node.js·express
2401_857600951 小时前
基于 SSM 框架 Vue 电脑测评系统:赋能电脑品质鉴定
前端·javascript·vue.js
天之涯上上1 小时前
Pinia 是一个专为 Vue.js 3 设计的状态管理库
前端·javascript·vue.js