发布日期 » 2019年4月11日 星期四

作者署名 » 陈帅华

原创声明 » 署名-非商业性使用-相同方式共享

抽奖九宫格

图片源自网络

思路

1、面向对象,将奖品块视作状态与动作的集合。
2、8个奖品块包含两种视觉状态,默认样式与高亮样式。
3、数组存储这8种奖品的DOM引用,定时从第0个奖品依次遍历。
4、随机循环次数,既定抽奖结果。

布局

1、准备8种奖品的默认+高亮状态切图16张。
2、每1种奖品的两种状态为1组,如下:

...
<div data-state="" class="card">
  <img src="..." alt="这是默认状态的奖品">
  <img src="..." alt="这是高亮状态的奖品">
</div>
...

3、使用属性选择器控制显示奖品默认图或高亮图,如下:

.card[data-state=""] img:first-child {display: block;}
.card[data-state=""] img:last-child {display: none;}

.card[data-state="1"] img:first-child {display: none;}
.card[data-state="1"] img:last-child {display: block;}

动画

1、霓虹灯闪烁动效。

.blink_panel {
  -webkit-animation: blink_panel 600ms linear infinite;
  animation: blink_panel 600ms linear infinite;
}
@-webkit-keyframes blink_panel {
  0% {opacity: 0;}
  10% {opacity: 1;}
  50% {opacity: 1;}
  60% {opacity: 0;}
  100% {opacity: 0;}
}
@keyframes blink_panel {
  0% {opacity: 0;}
  10% {opacity: 1;}
  50% {opacity: 1;}
  60% {opacity: 0;}
  100% {opacity: 0;}
}

代码片段

var model = {
  elMapId: ['card_fanbubao','card_fanhuansvip','card_xiexie1','card_yiduiyi','card_jiangyi','card_dikou','card_xiexie2','card_wenju'],
  isStart: false,
  timer: null,
  index: 0,
  nodes: [],
  round: 0,
  handleClick: function(){
    model.start('card_fanhuansvip')
  },
  onStart: function(next){
    next()
  },
  onEnd: function(which){
    console.log(which)
    console.log('end-------')
  },
  start: function(target){
    model.onStart && model.onStart(model.begin.bind(null,target))
  },
  begin: function(target){
    if(model.isStart) return
    model.isStart = true
    model.index = 0
    model.nodes = []
    model.round = 2 + Math.floor(Math.random() * 2)

    for(var i=0; i<model.round; i++) model.nodes = model.nodes.concat(model.elMapId)
    model.nodes = model.nodes.concat(model.elMapId.slice(0, (model.elMapId.indexOf(target))+1))

    model.nextTick()
  },
  nextTick: function(){
    clearTimeout(model.timer)
    model.timer = null

    if(model.index >= model.nodes.length){
      model.isStart = false
      model.onEnd && model.onEnd(model.nodes[model.nodes.length-1])
      return
    }

    var allCardEls = document.querySelectorAll('.thing')
    for(var i=0; i<allCardEls.length; i++) allCardEls[i].dataset.state = ''

    var targetCardEl = document.querySelector('#'+model.nodes[model.index])
    targetCardEl.dataset.state = '1'

    var time = 100
    var diff = model.nodes.length - model.index
    if(diff < 10) time += 100 - diff * 10

    model.timer = setTimeout(model.nextTick, time)
    model.index++
  }
}

document.querySelector('#start').addEventListener('click', model.handleClick)