文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

用60行代码实现一个高性能的圣诞抽抽乐H5小游戏(含源码)

2024-11-30 12:17

关注

效果展示

图片

将收获

•防抖函数的应用•用css实现九宫格布局•生成n维环形坐标的算法•如何实现环形随机轨道运动函数•实现加速度动画•性能分析与优化

设计思路

图片

具体实现

由于目前已有很多方案可以实现九宫格抽奖动画,比如使用动态active实现边框动画,用随机算法和定时器设置在何处停止等等. 为了进一步提高性能,本文介绍的方法,将使用坐标法,将操作dom的成本降低,完全由js实现滑块的路径的计算,滑块元素采用绝对定位,让其脱离文档流,避免其他元素的重绘等等,最后点击按钮我们会使用防抖函数来避免频繁执行函数,造成不必要的性能损失.

1. 九宫格布局实现

为了让大家更加熟悉dom结构,这里我就不用js动态生成了.如下html结构:

圣诞抽抽乐
我爱你
你爱我
我不爱你
你爱我
开始
你爱我
再见
谢谢惠顾
你爱我

九宫格布局我们使用flex来实现,核心代码如下:

.box {
    display: flex;
    flex-wrap: wrap;
    width: 300px;
    height: 300px;
    position: relative;
    .item {
        box-sizing: border-box;
        width: 100px;
    }
    // 滑块
    .spin {
        box-sizing: border-box;
        position: absolute;
        left: 0;
        top: 0;
        display: inline-block;
        width: 100px;
        height: 100px;
        background-color: rgba(0,0,0,.2);
    }
}

由上可知容器box采用flex布局,要想让flex子元素换行,我们这里要设置flex-wrap: wrap;此时九宫格布局就实现了. 滑块采用绝对定位,至于具体如何去沿着环形轨道运动,请继续看下文介绍.

2.生成n维环形坐标的算法

图片

由上图我们可以知道,一个九宫格的4条边,可以用以上8个坐标收尾连接起来,那么我们可以基于这个规律.来生成环形坐标集合.代码如下:


function generateCirclePath(n, cell) {
  let arr = []
  for(let i=0; i< n; i++) {
      arr.push([i*cell, 0])
  }
  for(let i=0; i< n-1; i++) {
      arr.push([(n-1)*cell, (i+1)*cell])
  }
  for(let i=0; i< n-1; i++) {
      arr.push([(n-i-2)*cell, (n-1)*cell])
  }
  for(let i=0; i< n-2; i++) {
      arr.push([0, (n-i-2)*cell])
  }
  return arr
}

如果是单位坐标,那么cell为1,cell设计的目的就位为了和现实的元素相结合,我们可以手动设置单元格的宽度来实现不同大小的n维环形坐标集.

3.实现环形随机轨道运动函数

由抽奖动画分析可知,我们滑块运动的轨迹,其实就是环形坐标集合,所以我们只要让滑块的顶点(默认左上角)沿着环形坐标集合一步步变化就好了.

function run(el, path, n = 1, i = 0, len = path.length) {
    setTimeout(() => {
        if(n > 0) {
          if(len <= i) {
              i = n === 1 ? len : 0
              n--
          }
          el.css('transform', `translate(${path[i][0]}px, ${path[i][1]}px)`)
          run(el, path, n, ++i, len)
        }
    }, 300)   
}

这样就能实现我们的滑块按照九宫格边框运动的动画了,当然以上函数只是基本的动画, 还没有实现在随机位置停止, 以及滑块的加速度运动,这块需要一定的技巧和js基础知识比如闭包.

3.1 加速度运动

加速度运动其实很简单,比如每转过一圈将setTimeout的延迟时间改变即可.代码如下:

function run(el, path, n = 1, speed = 60, i = 0, len = path.length) {
    setTimeout(() => {
        if(n > 0) {
          if(len <= i) {
              i = n === 1 ? len : 0
              n--
              speed += (300 - speed) / n
          }
          el.css('transform', `translate(${path[i][0]}px, ${path[i][1]}px)`)
          run(el, path, n, speed, ++i, len)
        }
    }, speed)   
}

3.2 随机停止实现

随机停止这块主要是用了Math.random这个API, 我们在最后一圈的时候, 根据随机返回的数值来决定何时停止,这里我们在函数内部实现随机数值,完整代码如下:


function run(el, path, n = 1, speed = 60, i = 0, len = path.length, random = Math.floor(Math.random() * len)) {
    setTimeout(() => {
        if(n > 0) {
          // 如果n为1,则设置中奖数值
          if(n === 1) {
            len = random
          }
          if(len <= i) {
              i = n === 1 ? len : 0
              n--
              speed += (300 - speed) / n
          }
          el.css('transform', `translate(${path[i][0]}px, ${path[i][1]}px)`)
          run(el, path, n, speed, ++i, len, random)
        }
    }, speed)   
}

4.实现点击开始的防抖函数以及应用

防抖函数实现:

// 防抖函数,避免频繁点击执行多次函数
function debounce(fn, interval = 300) {
  let timeout = null
  return function () {
      clearTimeout(timeout)
      timeout = setTimeout(() => {
          fn.apply(this, arguments)
      }, interval)
  }
}

那么我们点击时,代码应该长这样:

// 点击开始按钮,开始抽奖
$('.start').on('click',debounce(() => { run($('.spin'), generateCirclePath(3, 100), 3) }))

总结

该实现方式的好处是支持n维环形坐标的抽奖,基于坐标法的应用还有很多,尤其是游戏和图形领域,在实现过程中一定要考虑性能和可扩展性,这样我们就可以在不同场景使用同一套方法论,岂不乐哉?

最后

如果想了解更多H5游戏, webpack,node,gulp,css3,javascript,nodeJS,canvas数据可视化等前端知识和实战,关注《趣谈前端》加入我们一起学习讨论,共同探索前端的边界。

来源:趣谈前端内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯