滚动条还能这么玩

简介: 滚动条作为网页开发中常见的元素,承担了重要的作用,使连续的文本、图片或任何其他内容可以在计算机显示器、窗口或视窗上按预定的方向(上、下、左或右)滚动,以便所有内容都可以查看。

前言

滚动条作为网页开发中常见的元素,承担了重要的作用,使连续的文本、图片或任何其他内容可以在计算机显示器、窗口或视窗上按预定的方向(上、下、左或右)滚动,以便所有内容都可以查看。

滚动条的作用不容小觑,那么除此之外它还能实现哪些好玩的事情呢?用它做一个小游戏怎么样。

先来看看成品吧:
代码片段

原理

用户使用某种直接操作的方法与滚动条元素交互,滚动条将操作转换为滚动命令,用户通过滚动条元素和滚动内容的可视化更新接收反馈。那么我们就可以尝试将滚动条的变化体现在元素上,比如使用滚动条控制元素移动。就像这样:

动画.gif

当文档内容的宽高大于可视区域时,在该区域中就会出现滚动条,例如:

<style>
  .control {
    position: absolute;
    bottom: 0px;
    left: 0px;
    width: 100px;
    overflow-x: scroll;
    overflow-y: hidden;
  }

  .control div {
    width: 1000px;
    height: 1px;
  }
</style>
    
    
<div class="control"><div></div></div>

在用户与滚动条做交互时会触发 onscroll 事件,在事件中使用元素的 transform 属性改变目标的位置就可以打到上面图示上的不停的拖动滚动条来改变元素位置的效果了。

代码示例:

    <script>
      const player = document.getElementsByClassName('player')[0]
      const control = document.getElementsByClassName('control')[0]

      let position = 0
      control.onscroll = function () {
        position += 1

        if (position > 100) {
          player.style.transform = `translate(${200 - position}px, 0px)`
        } else {
          player.style.transform = `translate(${position}px, 0px)`
        }

        position === 200 ? (position = 0) : null
      }
    </script>

完整的示例可以在码上掘金上查看:
代码片段

实现

image.png
运动员的实现,运动员由三个部分组成,头部,胳膊,以及水花组成。头部与身体部分,块级元素相对较少,利用元素的伪元素,进行布局即可实现。由图可见,水花部分由多个div组成,每个div的位置与大小都不同,需要一一设置,这里使用 div:nth-of-type(1) 进行元素选取。

单个运动员有些无聊了,不妨多加几个,然后为他们分别设置一个能力值,当然是随机的,然后让他们的游泳速度跟能力值成正比,看他们谁游的快。

每隔3s中重新初始化运动员的能力,毕竟有的人前期猛后面就不行了,有的人是潜力股。

为运动员分配随机值

    const polePosition = document.getElementById('polePosition')
    const world = document.getElementById('world')
    const players = document.getElementsByClassName('player')
    console.log([...players])

    let position = 0
    let frame = null
    let playersAblility = [] // 运动员的能力
    let timer = null // 计时器

    function random(min, max) {
      return Math.floor(Math.random() * (max - min)) + min
    }

    // 初始化运动员能力
    function setPlayerAbility() {
      playersAblility = []
      for (let player of players) {
        const offset = random(1, 100)
        playersAblility.push(offset)
      }
    }
    setPlayerAbility()
    
    // 计时器
    function setTimer() {
      if (!timer) {
        timer = setInterval(() => {
          // 分配运动员体力
          setPlayerAbility()
        }, 3000)
      }
    }
    setTimer()

传入位置,控制运动员运动。

    // 游泳
    function setPlayerSwim(position) {
      const list = [...players]
      list.forEach((player, index) => {
        const offset = playersAblility[index]
        const translate = `translate(${position + offset}px,0)`
        player.style.transform = translate
        player.setAttribute('data-position', position + offset)
      })
    }

使用 requestAnimationFrame api 使页面动起来。在这个方法中,需要使赛道跟随运动员动起来。

    // 谁是第一
    function whoIsFirst() {
      const list = [...players]
        .map(v => {
          return v.getAttribute('data-position')
        })
        .sort((a, b) => b - a)
      return list[0]
    }
    
    // loop
    function loop() {
      const firstPosition = whoIsFirst() || 25
      console.log(firstPosition)

      if (firstPosition > 2430 - 25) {
        timer = null
        return
      }

      position += 1
      setPlayerSwim(position)

      polePosition.style.transform = `translate(${firstPosition}px, 0px)` // 第一的位置
      world.style.transform = `translate(-${position}px, 0px)`

      frame = window.requestAnimationFrame(loop)
    }

    // 开始按钮
    const startBtn = document.getElementById('startBtn')
    startBtn.onclick = () => {
      if (!frame) {
        loop()
      }
    }

总结

学习需要尝试一些新的东西,多做尝试,在平常不起眼的元素中发掘不一样的玩法。

目录
相关文章
|
分布式计算 大数据 Java
大数据-87 Spark 集群 案例学习 Spark Scala 案例 手写计算圆周率、计算共同好友
大数据-87 Spark 集群 案例学习 Spark Scala 案例 手写计算圆周率、计算共同好友
177 5
|
10月前
|
机器学习/深度学习 编解码 人工智能
超越Transformer,全面升级!MIT等华人团队发布通用时序TimeMixer++架构,8项任务全面领先
一支由麻省理工学院、香港科技大学(广州)、浙江大学和格里菲斯大学的华人研究团队,开发了名为TimeMixer++的时间序列分析模型。该模型在8项任务中超越现有技术,通过多尺度时间图像转换、双轴注意力机制和多尺度多分辨率混合等技术,实现了性能的显著提升。论文已发布于arXiv。
723 84
Java系类 之 生成随机数(random()和Random类)
这篇文章介绍了Java中生成随机数的两种方法:使用`Math.random()`方法和`Random`类的实例方法,并提供了示例代码展示如何使用这些方法生成特定范围或特定条件下的随机数。
|
Java UED 开发者
JVM逃逸分析原理解析:优化Java程序性能和内存利用效率
JVM逃逸分析原理解析:优化Java程序性能和内存利用效率
|
JavaScript 前端开发 搜索推荐
JavaScript 延迟加载的艺术:按需加载的最佳实践
JavaScript 延迟加载的艺术:按需加载的最佳实践
JavaScript 延迟加载的艺术:按需加载的最佳实践
|
机器学习/深度学习 人工智能 移动开发
递推算法-五种典型的递推关系
递推算法-五种典型的递推关系
664 0
|
安全 算法 Linux
Cobalt Strike <=4.7 xss复现和NTLM V2窃取(不会RCE)
Cobalt Strike <=4.7 xss复现和NTLM V2窃取(不会RCE)
319 0
|
弹性计算 Linux 数据安全/隐私保护
如何在Alinux 3系统搭建FTP站点
本文为第一期「实战派」有奖征文优秀作品。
470 0
如何在Alinux 3系统搭建FTP站点
|
弹性计算 Oracle 固态存储
阿里云服务器系统盘ESSD云盘性能级别PL怎么选择?
阿里云服务器ESSD云盘性能级别PL怎么选择?里云服务器ESSD云盘性能级别PL0、PL1、PL2和PL3怎么选择?不同性能级别对应的单盘IOPS性能上限、IO和吞吐量都不同,ESSD云盘容量越大可选择的PL级别越高,性能级别PL越高价格也越贵
666 0
阿里云服务器系统盘ESSD云盘性能级别PL怎么选择?
|
测试技术 uml
【UML建模】(4) UML建模之时序图
时序图是按照时间顺序显示对象交互的图。它显示了参与交互的对象和所交互信息的先后顺序,用来表示用例图中的行为,用例图是一种交互图
461 0
【UML建模】(4) UML建模之时序图