前言

标题解释:
数字滚动: 数字 0 变为 5,显示该数字的元素向上滚动最后显示 5
最短滚动: 数字 9 变为 1,向下滚动依次显示 9 - 0 - 1
如果这是你需要的‘组件’,那就继续吧!

需求


存在两个数字 start、end,需要实现一个类似滚轮滚动的效果,由 start 滚动到 end,其中,每次滚动都需要以尽量少的次数滚动
例如:
9 - 1 ==> 9 - 0 - 1;
2 - 0 ==> 2 - 1 - 0;

实现

首先,一步步的来,我们先实现滚动效果,暂不考虑 最短滚动
先来一个窗口用来观察滚轮

<div class="scroller-window"><div class="single-window"><p>0</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p></div>
</div>
.scroller-window {...height: 3em;overflow: hidden;
}
.single-scroller {transition: transform ease-in;
}

接下来只需要将 scroller-window 下的 p元素高度设为 100%,然后,根据 end的值,将 single-scroller 滚动(translateY)即可

const scroller= document.getElementByClassName('single-scroller')[0]// end 是滚轮的目的数字 0 - 9
const end = genRandomNum() // 0-9 随机数
const step = 10 // scroller里10个数字,每个占 10%
scroller.style.transform = `translateY(-${end * step}%)`

这样就实现了一个最简单的 滚轮

但是从 9 - 1,它会向上滚 9 - 8 -...- 1
我们需要让它按最短路径滚动,我们可以把 start 到 to 的正向路径与反向路径都计算出来进行比较,然后选择较短的那部分用来计算 tanslateY
同时,我们还需要把滚轮中的数字扩充,以供滚动滚出默认区,这样上面的 step 属性就变成了 100/20 = 5

<p>5</p><p>6</p><p>7</p><p>8</p><p>9</p>
<p>0</p><p>1</p><p>2</p><p>3</p><p>4</p>
<p>5</p><p>6</p><p>7</p><p>8</p><p>9</p>
<p>0</p><p>1</p><p>2</p><p>3</p><p>4</p>

计算最短滚动:例如从 0 到 3

向上滚动3-0 = 3 次 向下滚动10 - (3 - 0) = 7 次
|--------------|-----------------------------|
|____|____|____|____|____|____|____|____|____|
0    1    2    3    4    5    6    7    8    9
function getFastestTranslation(start, end) {let direction = 1; // -1 -> scroll up | 1 -> scroll downlet steps = 0;let startTansition = getNormalTranslation(start)if (start > end) {// start - end 为 start 向 end 递减的次数setDirectionAndSteps(Math.abs(start - end), Math.abs(10 - start + end));} else if (start < end) {// end - start 为 start 向 end 递减的次数setDirectionAndSteps(Math.abs(10 - end + start), Math.abs(end - start));}startTansition += direction * steps * step/*** 比较上下方向,设置最短步数* @param {*} dstep 向下滚动的步数* @param {*} ustep 向上滚动的步数*/function setDirectionAndSteps(dstep, ustep) {const isUpperFaster = dstep > ustepdirection = isUpperFaster ? -1 : 1steps = isUpperFaster ? ustep : dstep}return `translateY(${startTansition}%)`;
}function getNormalTranslation(num) {// 每个 p 元素占比为 5%, 第一个 0 在 25% 处出现return -(25 + num * 5)
}

滚动之后,还需要将其重置一下,如果滚轮落在了 上半区或下半区,那么下一次滚动可能会不正常
例如:
5 6 7 8 9 0 1 (2)...由 2 滚到 8 5 6 7 (8) 9 0 1 2...
由 8 滚到 4 (空) 5 6 7 8 9 0 1 2...
因此每次超出中间区就执行一次没有过渡的 translateY 将滚轮恢复到中间区

scroller.addEventListener('transitionend', ({ target }) => {reposition(target, end)
})function reposition({ style }, num) {const { transitionDuration } = styleconst normalTranslation = `translateY(${getNormalTranslation(num)}%)`if (style.transform !== normalTranslation) {style.transitionDuration = '0s'style.transform = normalTranslationrequestAnimationFrame(requestAnimationFrame.bind(null, () => {style.transitionDuration = transitionDuration}))}
}

接下来,修改 end 之前,执行 start = end 然后准备滚动

let step = 5
let start = 0
let end = genRandomNum()window.onload = ()  => {const scroller = document.getElementsByClassName('single-scroller')[0]// 最开始时滚轮将会显示 5,将其置为 0scroller.style.transitionDuration = '0s'scroller.style.transform = `translateY(${getNormalTranslation(start)}%)`setTimeout(() => {start = endend = genRandomNum()scroller.style.transitionDuration = '1s'}, 0)setTimeout(() => {start = endend = genRandomNum()scroller.style.transform = getFastestTranslation(start, end)}, 1000)scroller.addEventListener('transitionend', ({ target }) => {reposition(target, end)})}

滚轮完成!项目链接

js实现数字滚动显示(最短滚动版)相关推荐

  1. vue 实现数据滚动显示_vue 滚动加载数据

    table数据多的时候打开页面会加载一会才显示数据,这样体验不好,所以要做滚动加载数据 {{eventMap[scope.row.eventId] == null ? '--': eventMap[s ...

  2. ToolStripStatusRollingLabel——滚动显示状态栏标签

    前    注: 这是自己平时根据自己需要写的一些小代码,未必对各看官有用.另外,这是根据个人想法而写,未必严谨和符合设计原则,若有任何不妥之处,还请不吝赐教. 说    明: 本文描述一个可滚动显示文 ...

  3. 前端:JS/29/实例:控制div显示_滚动的图片

    实例:控制div显示_滚动的图片 <!DOCTYPE html> <html lang="en"><head><meta charset= ...

  4. 动态数码管(显示两位数字 以及左、右滚动显示)

    什么是动态数码管? 所谓的动态数码管不过是利用人的视觉残留效果,在多位显示数字. 20ms内在另一位数码管上显示数字,视觉上就像是同时点亮了两个数码管.而间隔时间过短则会造成亮度变暗.一般情况下为几m ...

  5. 【Proteus仿真】8×8LED点阵屏仿电梯数字滚动显示

    [Proteus仿真]8×8LED点阵屏仿电梯数字滚动显示 Proteus仿真演示 8X8点阵取模工具和取模方式(随源码打包) 示例代码 //名称:8×8LED点阵屏仿电梯数字滚动显示 //说明:本例 ...

  6. 8只数码管滚动显示单个数字

    /* 名称:8只数码管滚动显示单个数字 说明:数码管从左到右依次滚动显示0~7,程序通过每次仅循环选通一只数码管 */ #include<reg51.h> #include<intr ...

  7. js简单文字滚动显示

    js简单文字滚动显示 1. html内容 <!DOCTYPE html> <html><head><meta charset="utf-8" ...

  8. 8*8led矩阵的滚动广告幕的c语言程序,8*8LED矩阵滚动显示数字和字符

    //------------------------------------------- //8*8矩阵循环显示字符和数字 //显示字符串在数组disstr[]中申明 //------------- ...

  9. html数字滚动选择,js实现数字滚动特效

    本文实例为大家分享了js实现数字滚动展示的具体代码,供大家参考,具体内容如下 效果图 html代码 Title #t,#tt{ border: #ccc thin solid; width: 250p ...

最新文章

  1. java固定资产管理系统代码_Java 固定资产管理系统(课程设计)
  2. (深入理解)强化学习中的policy-based和value-based区别是什么?
  3. string修饰的梦修改吗_Java String 对象,你真的了解了吗?
  4. 22-while循环
  5. 伪静态php配置,PHP开启伪静态配置
  6. 工业级光纤收发器的单多模光纤?单多光模块及其用法?
  7. C语言int的字节数跟什么有关,C语言中int型字长和什么有关
  8. HBase 1.3(NOSQL) 发布,性能大幅提升
  9. 软件测试就业必备知识点自学软件测试-Dotest-2019
  10. 传奇世界凤凰登陆器格式说明
  11. 小窗终曲说策划(有空就看看吧,可能对设计想法有所帮助,不仅仅是游戏方面
  12. 谈谈如何解决win7/win10/win11右键转圈卡顿问题
  13. Java消息队列--ActiveMQ 实战
  14. 自主证件采集录入系统-嵌入式护照阅读器
  15. DEDECMS织梦后台更新网站栏目无反应一键更新无响应的解决方法
  16. 第十三周 项目2第11章习题9
  17. 详谈室内定位技术方案
  18. 【C++Python】C++调用Python(二):Python脚本调用
  19. PointGet的一生
  20. go实现NSQ消息队列的集群部署

热门文章

  1. 【REST 】REST 介绍
  2. master公式(主方法)
  3. 关于最近爆火的chatGPT大型语言模型人工智能介绍
  4. 合并两个有序表--顺序表
  5. oracle ogg巡检,述说OGG检查点
  6. SPSS软件使用教程(2),SPSS统计分析软件 27中文版下载安装
  7. php strpos 区分大小写么?,php查找字符串strpos(), stripos(),strrpos(), strripos()的区别
  8. 每日一题之买卖股票的最佳时机
  9. 记录一个子串在整串种出现的次数(JAVA)
  10. 国内php排行,国内最好的cms系统排行榜