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 相关文章推荐
2012年开发人员的16款新鲜的jquery插件体验分享
Dec 28 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
Aug 30 Javascript
javascript实现可全选、反选及删除表格的方法
May 15 Javascript
JSON 对象未定义错误的解决方法
Sep 29 Javascript
微信小程序 开发之快递查询功能的实现
Jan 09 Javascript
微信小程序 自动登陆PHP源码实例(源码下载)
May 08 Javascript
详解使用angular-cli发布i18n多国语言Angular应用
May 20 Javascript
简单实现js鼠标跟随效果
Aug 02 Javascript
js实现前端图片上传即时预览功能
Aug 02 Javascript
10个经典的网页鼠标特效代码
Jan 09 Javascript
vue+vue-router转场动画的实例代码
Sep 01 Javascript
在vue中使用echarts(折线图的demo,markline用法)
Jul 20 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检查日期函数checkdate用法实例
2015/03/19 PHP
微信公众平台开发教程⑤ 微信扫码支付模式介绍
2019/04/10 PHP
CLASS_CONFUSION JS混淆 全源码
2007/12/12 Javascript
js实现幻灯片效果(基于jquery插件)
2013/11/05 Javascript
javascript根据时间生成m位随机数最大13位
2014/10/30 Javascript
javascript先序遍历DOM树的方法
2016/02/27 Javascript
vue自定义指令实现v-tap插件
2016/11/03 Javascript
JS新包管理工具yarn和npm的对比与使用入门
2016/12/09 Javascript
javascript实现页面滚屏效果
2017/01/17 Javascript
微信小程序 request接口的封装实例代码
2017/04/26 Javascript
JavaScript数组,JSON对象实现动态添加、修改、删除功能示例
2018/05/26 Javascript
使用pm2部署node生产环境的方法步骤
2019/03/09 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)
2019/11/21 Javascript
详解一些适用于Node.js的命名约定
2019/12/08 Javascript
Vue开发中遇到的跨域问题及解决方法
2020/02/11 Javascript
uniapp实现可以左右滑动导航栏
2020/10/21 Javascript
[00:42]《辉夜杯》—职业组预选赛12月3日15点 正式打响
2015/12/03 DOTA
Python接收Gmail新邮件并发送到gtalk的方法
2015/03/10 Python
用Python创建声明性迷你语言的教程
2015/04/13 Python
Python的requests网络编程包使用教程
2016/07/11 Python
安装Python的教程-Windows
2017/07/22 Python
python数据类型判断type与isinstance的区别实例解析
2017/10/31 Python
python http接口自动化脚本详解
2018/01/02 Python
解决pycharm 误删掉项目文件的处理方法
2018/10/22 Python
Python网络编程之使用TCP方式传输文件操作示例
2019/11/01 Python
python读取raw binary图片并提取统计信息的实例
2020/01/09 Python
CSS3的常见transformation图形变化用法小结
2016/05/13 HTML / CSS
Timberland法国官网:购买靴子、鞋子、衣服、夹克和配饰
2019/11/30 全球购物
几个Shell Script面试题
2012/08/31 面试题
自考毕业自我鉴定
2014/03/18 职场文书
优秀应届本科生求职信
2014/07/19 职场文书
实践论读书笔记
2015/06/29 职场文书
2015年新农村建设指导员工作总结
2015/07/24 职场文书
少儿励志名言(80句)
2019/08/14 职场文书
MYSQL中文乱码问题的解决方案
2022/06/14 MySQL