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 相关文章推荐
jquery实现图片裁剪思路及实现
Aug 16 Javascript
jquery $.each() 使用小探
Aug 23 Javascript
jquery中使用循环下拉菜单示例代码
Sep 24 Javascript
javascript实现给定半径求出圆的面积
Jun 26 Javascript
javascript表格的渲染组件
Jul 03 Javascript
javascript 的变量、作用域和内存问题
Apr 19 Javascript
JavaScript制作简单的框选图表
May 15 Javascript
vue使用keep-alive实现数据缓存不刷新
Oct 21 Javascript
详解Webpack实战之构建 Electron 应用
Dec 25 Javascript
angular2路由之routerLinkActive指令【推荐】
May 30 Javascript
微信小程序分享海报生成的实现方法
Dec 10 Javascript
微信小程序设置全局请求URL及封装wx.request请求操作示例
Apr 02 Javascript
微信小程序使用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
PHP获取文件后缀名的三个函数
2012/10/15 PHP
kohana框架上传文件验证规则写法示例
2014/07/14 PHP
PHP+mysql+ajax轻量级聊天室实现方法详解
2016/10/17 PHP
PHP进制转换实例分析(2,8,16,36,64进制至10进制相互转换)
2017/02/04 PHP
laravel配置Redis多个库的实现方法
2019/04/10 PHP
解决laravel session失效的问题
2019/10/14 PHP
php7 list()、session及其他模块的修改实例分析
2020/05/25 PHP
PHP Web表单生成器案例分析
2020/06/02 PHP
javascript 对象的定义方法
2007/01/10 Javascript
javascript getElementsByClassName函数
2010/04/01 Javascript
Jquery读取URL参数小例子
2013/08/30 Javascript
JavaScript中实现PHP的打乱数组函数shuffle实例
2014/10/11 Javascript
jquery分割字符串的方法
2015/06/24 Javascript
js实现当复选框选择匿名登录时隐藏登录框效果
2015/08/14 Javascript
jquery正则表达式验证(手机号、身份证号、中文名称)
2015/12/31 Javascript
Nodejs获取网络数据并生成Excel表格
2020/03/31 NodeJs
AngularJS入门教程之服务(Service)
2016/07/27 Javascript
javascript 中null和undefined区分和比较
2017/04/19 Javascript
利用node.js制作命令行工具方法教程(一)
2017/06/22 Javascript
Node.js+jade抓取博客所有文章生成静态html文件的实例
2017/09/19 Javascript
vue项目打包后打开页面空白解决办法
2018/06/29 Javascript
使用webpack构建应用的方法步骤
2019/03/04 Javascript
angular4+百分比进度显示插件用法示例
2019/05/05 Javascript
JQuery实现简单的复选框树形结构图示例【附源码下载】
2019/07/16 jQuery
利用Python中的输入和输出功能进行读取和写入的教程
2015/04/14 Python
在Python中封装GObject模块进行图形化程序编程的教程
2015/04/14 Python
Python编程实现线性回归和批量梯度下降法代码实例
2018/01/04 Python
零基础使用Python读写处理Excel表格的方法
2019/05/02 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
PyCharm2020.3.2安装超详细教程
2021/02/08 Python
CSS3区域模块region相关编写示例
2015/08/28 HTML / CSS
Hunkemöller西班牙:欧洲最大的内衣连锁店
2018/08/15 全球购物
团结演讲稿范文
2014/05/23 职场文书
停水通知
2015/04/16 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
Java SSH 秘钥连接mysql数据库的方法
2021/06/28 Java/Android