200行HTML+JavaScript实现年会抽奖程序


Posted in Javascript onJanuary 22, 2019

本文实例为大家分享了js实现年会抽奖程序的具体代码,供大家参考,具体内容如下

需求分析

1.多轮抽奖,每轮只有3个环节:展示奖品图,人名闪动,停止闪动确定中奖名单
2.中奖分级,例如试用期员工不能中二等奖或以上
3.每轮抽奖的中奖人数不同。每个人只能中一次奖
4.可临时加场,现场输入奖品名、数量。额外窗口输入,避免被观众看到修改过程。
5.本地记录每轮的奖品和中奖名单
6.全屏显示。不确定现场的屏幕分辨率,故核心部分固定1024*768,居中显示;背景拉伸铺满全屏。

200行HTML+JavaScript实现年会抽奖程序

技术选型

搞桌面程序第一时间就想到了这几个框架:Java Swing、Python Tkinter、C++ Qt、C# WPF。虽然都可行,但感觉开发不够便捷。而且谁知道年会现场那台电脑有没有对应的运行时库。

最后经同事给的灵感想到了用JavaScript做,选定了node-webkit,即nw.js。没有选electron是它需要搭开发环境。

既然连开发环境都懒得搭,那自然也用不了Vue、React、Angular。实际上也没必要,小学生才用牛刀杀鸡。

代码开源

开源在 年会抽奖程序 。文末会贴一下当前的版本,但以github上的为准。

使用方法
启动
Windows的启动方法:到 这里 下载node-webkit,解压出来,把代码的整个目录拖动到nwjs.exe上。

其它操作系统按官方说明做:

cd /path/to/your/app
/path/to/nw .

/path/to/nw is the binary file of NW.js. On Windows, it's nw.exe; On Linux, it's nw; On Mac, it's nwjs.app/Contents/MacOS/nwjs.

按键

  • f:切换全屏
  • 4:下一步。进入下一轮抽奖的展示奖品图片、进入名单滚动。
  • 空格:立刻停止名单滚动。即确定中奖人员。
  • 8:重新加载配置文件。主要用于临场增加奖项
  • 1:上一步,用来看看上个奖项的情况

核心文件说明

  • index.html:所有代码都在这
  • steps.json:流程配置文件,应该一看就懂。中奖后此文件会被修改,包含中奖名单。如果需要加奖项,不用退出程序,编辑完这个文件后按8就能重新加载配置,继续抽。
  • names.ini:人员名单与可中奖等级,等级数字越小表示可中更大的奖。中奖后此文件会被修改,删除已中奖的人

TODO

  • 启动的时候设置窗口大小和位置会闪动,可以做得体验好点,虽然没必要
  • 更多的可动态设置项
  • 启动方式还是有点别扭,可打包一下程序

代码

程序步骤说明:

1.调整窗口大小和位置
2.读取配置文件,得到人员名单和抽奖轮次信息
3.进入第1轮。通过按键4和空格进入下个环节
4.用state变量来记录状态:展示图片、滚动名单、显示中奖名单

html的部分:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <script>
  var win = nw.Window.get()
  win.resizeTo(1024, 768)
  win.moveTo(0, 0)
 </script>
 <style type="text/css">
  * {
  margin: 0;
  padding: 0;
  }
  html, body {
  width: 100%;
  height: 100%;
  }
  body {
  text-align: center;
  background: url("./bg.png") no-repeat;
  overflow: hidden;
  background-size: 100% 100%;
  font-weight: bold;
  color: #D40000;
  }
  #container {
  min-width: 1000px;
  min-height: 700px;
  }
  #title {
  font-size: 100px;
  margin-top: 80px;
  }
  #disc {
  font-size: 40px;
  margin: 10px 0;
  }
  #image {
  margin-top: 20px;
  max-height: 280px;
  border: 1px solid #E23540FF;
  border-radius: 20px;
  }
  #list {
  margin: 0 auto;
  max-width: 800px;
  }
  #list span {
  display: inline-block;
  width: 160px;
  font-size: 36px;
  margin-top: 8px;
  }
 </style>
 </head>

 <body>
 <div id="container">
  <div id="title">XX公司年会</div>
  <div id="disc">奖品描述</div>
  <img id="image" />
  <div id="list"></div>
 </div>
 <script>
  var fs = require('fs')
  var steps = null
  var step = 0
  var names = null
  var state = ''
  
  var disc = document.getElementById('disc')
  var image = document.getElementById('image')
  var list = document.getElementById('list')

  function reloadConf(func) {
  fs.readFile('names.ini', 'utf8', function(err, data) {
   names = data.split('\n').map(x => x.split(','))
  })
  fs.readFile('./steps.json', 'utf8', function(err, data) {
   steps = eval(data)
   if (func) func()
  })
  }

  function saveConf(func) {
  fs.writeFile('./steps.json', JSON.stringify(steps), function(err) {
   if (err) {
   alert(err)
   }
  })
  fs.writeFile('./names.ini', names.map(x => x.join(',')).join('\n'), function(err) {
   if (err) {
   alert(err)
   }
  })
  }

  function showPic(data) {
  disc.innerHTML = data.disc
  image.src = data.image
  image.style.display = 'inline'
  list.style.display = 'none'
  while (list.hasChildNodes()) {
   list.removeChild(list.firstChild)
  }
  }

  function showBlink(data) {
  disc.innerHTML = data.disc
  image.style.display = 'none'
  list.style.display = 'block'
  var spans = []
  for (var i = 0; i < data.count; ++i) {
   var span = document.createElement('span')
   list.appendChild(span)
   spans.push(span)
  }

  function doBlink() {
   if (state == 'showBlink') {
   names.sort(function() {
    return 0.5 - Math.random()
   })
   for (var i = 0; i < data.count; ++i) {
    spans[i].innerHTML = names[i][0]
   }
   window.requestAnimationFrame(doBlink)
   }
  }

  window.requestAnimationFrame(doBlink)
  }

  function showList(data) {
  disc.innerHTML = data.disc
  image.style.display = 'none'
  list.style.display = 'block'
  while (list.hasChildNodes()) {
   list.removeChild(list.firstChild)
  }
  for (var i = 0; i < data.list.length; ++i) {
   var span = document.createElement('span')
   span.innerHTML = data.list[i]
   list.appendChild(span)
  }
  }

  function nextStep() {
  var data = steps[step]
  if (state == 'showPic') {
   data.list = data.list || []
   if (data.list.length > 0) {
   state = 'showList'
   showList(data)
   } else {
   state = 'showBlink'
   showBlink(data)
   }
  } else if (state == 'showBlink') {
   if (data.list.length > 0) {
   state = 'showList'
   showList(data)
   }
  } else if (state == 'showList') {
   if (step < (steps.length - 1)) {
   ++step
   state = ''
   nextStep()
   }
  } else {
   state = 'showPic'
   showPic(data)
  }
  }

  function previousStep() {
  if (step > 0) {
   --step
  }
  state = ''
  nextStep()
  }

  function drawPrize() {
  if (state == 'showBlink') {
   var data = steps[step]
   names.sort(function (a, b) {
   if (a[1] <= data.level && b[1] > data.level) {
    return -1
   }
   return 0
   })
   var luck = names.splice(0, data.count)
   data.list = luck.map(x => x[0])
   saveConf()
   nextStep()
  }
  }

  document.addEventListener('keydown', function(e) {
  e=e||window.event
  if (e.keyCode == 56) {
   // 8
   reloadConf()
  } else if (e.keyCode == 52) {
   // 4
   nextStep()
  } else if (e.keyCode == 49) {
   // 1
   previousStep()
  } else if (e.keyCode == 32) {
   // 空格
   drawPrize()
  } else if (e.keyCode == 70) {
   // f
   win.toggleFullscreen()
  }
  })
  
  reloadConf(nextStep)
 </script> 
 </bdoy>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
使用非html5实现js板连连看游戏示例代码
Sep 22 Javascript
Express.JS使用详解
Jul 17 Javascript
原生javascript实现图片按钮切换
Jan 12 Javascript
jQuery EasyUI学习教程之datagrid点击列表头排序
Jul 09 Javascript
vue.js指令v-model实现方法
Dec 05 Javascript
Web前端框架Angular4.0.0 正式版发布
Mar 28 Javascript
jquery如何实现点击空白处隐藏元素
Dec 05 jQuery
详解React中传入组件的props改变时更新组件的几种实现方法
Sep 13 Javascript
Vue.js实现的购物车功能详解
Jan 27 Javascript
jquery操作select常见方法大全【7种情况】
May 28 jQuery
微信小程序与公众号实现数据互通的方法
Jul 25 Javascript
jQuery实现王者荣耀手风琴效果
Jan 17 jQuery
微信小程序使用map组件实现获取定位城市天气或者指定城市天气数据功能
Jan 22 #Javascript
微信小程序使用map组件实现解析经纬度功能示例
Jan 22 #Javascript
微信小程序全局变量功能与用法详解
Jan 22 #Javascript
微信小程序使用map组件实现路线规划功能示例
Jan 22 #Javascript
JavaScript JMap类定义与使用方法示例
Jan 22 #Javascript
vue2.0 如何在hash模式下实现微信分享
Jan 22 #Javascript
JavaScript继承与聚合实例详解
Jan 22 #Javascript
You might like
基于wordpress主题制作的具体实现步骤
2013/05/10 PHP
PHP禁止个别IP访问网站
2013/10/30 PHP
php获得用户ip地址的比较不错的方法
2014/02/08 PHP
php读取der格式证书乱码解决方法
2015/06/22 PHP
PHP解压ZIP文件到指定文件夹的方法
2016/11/17 PHP
PHP面向对象中new self()与 new static()的区别浅析
2017/08/17 PHP
PHP addcslashes()函数讲解
2019/02/03 PHP
js中onload与onunload的使用示例
2013/08/25 Javascript
浅析js中的浮点型运算问题
2014/01/06 Javascript
使用VS开发 Node.js指南
2015/01/06 Javascript
基于jQuery实现自动轮播旋转木马特效
2015/11/02 Javascript
JavaScript String 对象常用方法详解
2016/05/13 Javascript
零基础轻松学JavaScript闭包
2016/12/30 Javascript
Javascript中字符串和数字的操作方法整理
2017/01/22 Javascript
JavaScript判断浏览器和hack滚动条的写法
2017/07/23 Javascript
微信小程序性能优化之checkSession的使用
2019/03/06 Javascript
vue项目中运用webpack动态配置打包多种环境域名的方法
2019/06/24 Javascript
vantUI 获得piker选中值的自定义ID操作
2020/11/04 Javascript
javascript实现放大镜功能
2020/12/09 Javascript
[46:10]2014 DOTA2国际邀请赛中国区预选赛 CnB VS HGT
2014/05/21 DOTA
python机器学习理论与实战(一)K近邻法
2021/01/28 Python
python批量替换多文件字符串问题详解
2018/04/22 Python
python实现微信小程序自动回复
2018/09/10 Python
django开发post接口简单案例,获取参数值的方法
2018/12/11 Python
Python 中使用 PyMySQL模块操作数据库的方法
2019/11/10 Python
python读写数据读写csv文件(pandas用法)
2020/12/14 Python
请写出char *p与"零值"比较的if语句
2014/09/24 面试题
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
写自荐信有哪些不宜?
2013/10/17 职场文书
人力资源经理的岗位职责
2014/03/02 职场文书
优秀德育工作者事迹材料
2014/05/07 职场文书
作风转变年心得体会
2014/10/22 职场文书
上班迟到检讨书范文
2015/05/06 职场文书
2015年班组建设工作总结
2015/05/13 职场文书
JS继承最简单的理解方式
2021/03/31 Javascript
Python办公自动化PPT批量转换操作
2021/09/15 Python