今天圣诞节,先预祝大家节日快乐.既然是圣诞节,那我们就来学点有意思的,用几十行代码来实现一个高性能的抽奖小游戏.也基于此,来巩固我们的javascript基础,以及前端一些基本算法的应用

效果展示

将收获

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

设计思路

具体实现

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

1. 九宫格布局实现

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

                <div class="wrap"><div class="title">圣诞抽抽乐</div><div class="box"><div class="item">我爱你</div><div class="item">你爱我</div><div class="item">我不爱你</div><div class="item">你爱我</div><div class="item start">开始</div><div class="item">你爱我</div><div class="item">再见</div><div class="item">谢谢惠顾</div><div class="item">你爱我</div><div class="spin"></div></div>
</div>

九宫格布局我们使用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个坐标收尾连接起来,那么我们可以基于这个规律.来生成环形坐标集合.代码如下:

                /*** 生成n维环形坐标* @param {number} n 维度* @param {number} cell 单位坐标长度*/
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 : 0n--}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 : 0n--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, 我们在最后一圈的时候, 根据随机返回的数值来决定何时停止,这里我们在函数内部实现随机数值,完整代码如下:

                /**
* 环形随机轨道运动函数
* @param {element} el 运动的dom元素
* @param {array} path 运动的环形坐标集合
* @param {number} speed 运动的初始速度
* @param {number} i 运动的初始位置
* @param {number} len 路径的长度
* @param {number} random 中奖坐标
*/
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 : 0n--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 = nullreturn function () {clearTimeout(timeout)timeout = setTimeout(() => {fn.apply(this, arguments)}, interval)}
}

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

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

总结

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

最后

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

更多推荐

  • 基于react/vue生态的前端集成解决方案探索与总结

  • 9012教你如何使用gulp4开发项目脚手架

  • 如何用不到200行代码写一款属于自己的js类库)

  • 让你瞬间提高工作效率的常用js函数汇总(持续更新)

  • 一张图教你快速玩转vue-cli3

  • 3分钟教你用原生js实现具有进度监听的文件上传预览组件

  • 使用Angular8和百度地图api开发《旅游清单》

  • js基本搜索算法实现与170万条数据下的性能测试

  • 《前端算法系列》如何让前端代码速度提高60倍

  • vue高级进阶系列——用typescript玩转vue和vuex

欢迎关注下方公众号,回复 lodash,将获取本人亲自翻译的lodash API中文
思维导图源文档。

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

  1. 60行python代码实现弹球小游戏(含源码)

    弹球效果预览 解析代码 弹球 Ball 类 draw负责移动Ball 碰撞检测,反弹,Ball检测Paddle 2.Paddle类 draw负责移动Paddle 碰撞检测,确定能不能继续 监听键盘事件 ...

  2. python小游戏-16行代码实现3D撞球小游戏!-源码下载

    python小游戏-16行代码实现3D撞球小游戏!-源码下载 所属网站分类: 资源下载 > python小游戏 作者:搞笑 链接: http://www.pythonheidong.com/bl ...

  3. 【Python游戏】Python实现一个Q版泡泡堂小游戏 | 附带源码

    相关文件 想学Python的小伙伴可以关注小编的公众号[Python日志] 有很多的资源可以白嫖的哈,不定时会更新一下Python的小知识的哈!! 需要源码的小伙伴可以在公众号回复泡泡堂 Python ...

  4. 用C语言easyx库来写一个简单的翻翻乐小游戏(附源码素材)

    简明目录 写在前面 easyx库 准备工作 新建项目文件 分析 素材分析 上代码吧 地图表示 开始界面 地图初始化(打乱) 游戏过程实现 主函数的实现 测试 优化 1.游戏分数 2.游戏时间 3.nu ...

  5. 【Python游戏】Python实现一个星球大战的小游戏 | 附带源码

    相关文件 想学Python的小伙伴可以关注小编的公众号[Python日志] 有很多的资源可以白嫖的哈,不定时会更新一下Python的小知识的哈!! 需要源码的小伙伴可以在公众号回复星球大战 Pytho ...

  6. 【Python游戏】基于pygame实现的一个Dino Rush 恐龙宝贝冲冲冲的小游戏 | 附源码

    前言 halo,包子们晚上好 很久没有更新啦,主要是小编这边最近有点小忙 今天给大家整一个Dino Rush 恐龙宝贝冲冲冲的小游戏 还是一个比较记经典的小游戏,还记这可谷歌浏览器上没有网也能打发时间 ...

  7. 【Python游戏】基于化学方程式的基础上,用Python实现一个消灭泡泡小游戏 | 附源码

    前言 halo,包子们下午好 今天实现的这个小游戏呀,说实话化学不太好的小伙伴可能看起来会有点懵逼 不过不用担心,咱们今天不是来学化学的,我们是来学习Python的 所以呀,不要太担心啦,大家先好好看 ...

  8. 【Python游戏】Python实现一个可以切换单人或双人对战乒乓球小游戏 | 附带源码

    相关文件 想学Python的小伙伴可以关注小编的公众号[Python日志] 有很多的资源可以白嫖的哈,不定时会更新一下Python的小知识的哈!! 需要源码的小伙伴可以在公众号回复 乒乓球 Pytho ...

  9. 【Python游戏】用Python 和 Pyglet 编写一个我的世界小游戏 | 附源码

    相关文件 想学Python的小伙伴可以关注小编的公众号[Python日志] 有很多的资源可以白嫖的哈,不定时会更新一下Python的小知识的哈!! 需要源码的小伙伴可以在公众号回复我的世界 Pytho ...

  10. 爬虫入门,带你用30行代码爬取高清美女写真,附安装包+源码

    1.准备工作 1 高清壁纸:https://www.36992.com/girls/list-1.html 2 Python环境 Python3.9新特性: 字典"并集"运算符 类 ...

最新文章

  1. python基础笔记(非系统/自用/参考小甲鱼的零基础入门学习python)下
  2. 九、Redis五大数据类型之一String
  3. windows 7 睡眠和休眠的区别
  4. android中获取时间
  5. ucenter 显示通信成功的条件
  6. Vsftp在Ubuntu的安装与配置
  7. xen虚拟化部署遇到的问题(持续更新)
  8. FLASH+XML:构建简单易更新网站
  9. 【Spring-Cached】Cached之Caffeine
  10. Pycharm安装与汉化教程
  11. 使用Mac的十大最好用神器
  12. cookie.setValue一些注意事项
  13. 9.6.5对象的常引用
  14. Lake Shore Cernox低温温度传感器之温度探头
  15. FPGA视频传输bug小记
  16. 手动挡你会开吗 八招教你开好手动挡车型
  17. Chrome 内置翻译翻译失败解决
  18. 全球与中国薄膜形成设备市场现状及未来发展趋势2022-2028
  19. electron-v8.2.1-win32-x64.zip 下载失败(npm install electron 安装失败)
  20. 二、肺癌检测-LUNA数据集下载和介绍

热门文章

  1. 记一次小白的手游脚本破解过程及难题
  2. Neo4j使用记录--APOC和GDS的安装【实践】
  3. Xbrowser远程RHEL5.5
  4. Android 自定义锁屏_开发自定义ROM提速:红米Note 6 Pro等Android Pie内核源代码上线...
  5. css3学习以及移动端开发基本概念的思考
  6. 电影《功夫熊猫1》中的管理知识
  7. Dao接口返回数组_在内存只有10M的空间中申请一块5M的数组空间,会导致OOM吗?...
  8. GitHub创建仓库
  9. python常用单词读法-Python常用单词
  10. ERP基础数据 金蝶