js刮刮樂程式碼例項

螞蟻小編發表於2017-04-14

本章節分享一段程式碼例項,它實現了刮刮樂效果。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
#rectangle {
  width: 200px;
  height: 50px;
  background-color: #ddd;
  border: 1px solid #aaa;
  padding: 10px;
  font-size:18px;
  font-weight:bold;
  text-align: center;
  line-height: 50px;
  position: relative;
  color: #f00;
}
</style>
<script type="text/javascript">
var cache = {};
//手機端事件
(function(exports) {
  function touchEvent(target, startEvent, moveEvent, endEvent) {
    var slider = {
      //判斷裝置是否支援touch事件
      touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,
      slider: null,
      startEvent: null,
      moveEvent: null,
      endEvent: null,
      //滑動開始
      start: function(event) {
        var touch = event.targetTouches[0]; //touches陣列物件獲得螢幕上所有的touch,取第一個touch
        startPos = {
          x: touch.pageX,
          y: touch.pageY,
          time: +new Date
        }; //取第一個touch的座標值
        isScrolling = 0; //這個引數判斷是垂直滾動還是水平滾動
        slider.slider.addEventListener('touchmove', slider.move, false);
        slider.slider.addEventListener('touchend', slider.end, false);
        if (slider.startEvent != undefined && typeof(slider.startEvent) == "function")
          slider.startEvent.call(this, touch);
      },
      //移動
      move: function(event) {
        //當螢幕有多個touch或者頁面被縮放過,就不執行move操作
        if (event.targetTouches.length > 1 || event.scale && event.scale !== 1) return;
        var touch = event.targetTouches[0];
        endPos = {
          x: touch.pageX - startPos.x,
          y: touch.pageY - startPos.y
        };
        //isScrolling為1時,表示縱向滑動,0為橫向滑動
        isScrolling = Math.abs(endPos.x) < Math.abs(endPos.y) ? 1 : 0; 
        if (isScrolling === 0) {
          //  event.preventDefault();      //阻止觸控事件的預設行為,即阻止滾屏
        }
        if (slider.moveEvent != undefined && typeof(slider.moveEvent) == "function")
          slider.moveEvent.call(this, touch);
      },
      //滑動釋放
      end: function(event) {
        var duration = +new Date - startPos.time; //滑動的持續時間
        if (isScrolling === 0) { //當為水平滾動時
          if (Number(duration) > 10) {
            //判斷是左移還是右移,當偏移量大於10時執行
            if (endPos.x > 10) {
 
            } else if (endPos.x < -10) {
 
            }
          }
          if (slider.endEvent != undefined && typeof(slider.endEvent) == "function")
            slider.endEvent.call(this, event);
        }
        //解綁事件
        slider.slider.removeEventListener('touchmove', slider.move, false);
        slider.slider.removeEventListener('touchend', slider.end, false);
      },
 
      //初始化
      init: function() {
        var self = this; //this指slider物件 
        //addEventListener第二個引數可以傳一個物件,會呼叫該物件的handleEvent屬性        
        if (!!self.touch) self.slider.addEventListener('touchstart', this.start, false);
      }
    }
    slider.slider = target;
    slider.startEvent = startEvent;
    slider.moveEvent = moveEvent;
    slider.endEvent = endEvent;
    slider.init();
    return {
      touch: slider.touch,
      target: slider.slider
    }
  };
  //windows按下拖動物件
  function dragEvent(down_target, move_target, down, move, up) {
    var drag = {
      down_target: null,
      move_target: null,
      move: null,
      up: null,
      down: null,
      intial: function(down_target, move_target, down, move, up) {
        if (down_target == undefined || move_target == undefined || move == undefined)
          return;
        this.down_target = down_target;
        this.move_target = move_target;
        this.down = down;
        this.move = move;
        this.up = up;
        drag.prefixedEvent(drag.down_target, "mousedown", this.mousedown, true);
        drag.prefixedEvent(drag.down_target, "mouseup", this.mouseup, true);
        drag.prefixedEvent(document, "mouseup", this.mouseup, true);
      },
      mouseup: function(e) {
        drag.stopEvent(e); //這裡需要冒泡
        if (drag.up != undefined && typeof(drag.up) == "function")
          drag.up.call(this, e);
        drag.prefixedEvent(drag.move_target, "mousemove", drag.mousemove, false);
      },
      mousemove: function(evt) {
        var e = (evt) ? evt : window.event;
        drag.move.call(this, e);
      },
      mousedown: function(evt) {
        drag.stopEvent(evt); //這裡阻止冒泡
        var e = (evt) ? evt : window.event;
        if (drag.down != undefined && typeof(drag.down) == "function")
          drag.down.call(this, e);
        drag.prefixedEvent(drag.move_target, "mousemove", drag.mousemove, true);
      },
      stopEvent: function(evt) {
        if (evt == undefined) return;
        //判斷瀏覽器的型別,在基於ie核心的瀏覽器中的使用cancelBubble
        var e = (evt) ? evt : window.event; 
        if (window.event) {
          e.cancelBubble = true;
        } else {
          e.stopPropagation();
        }
      },
      prefixedEvent: function(element, type, callback, isAdd) {
        var pfx = ["webkit", "moz", "MS", "o", ""];
        for (var p = 0; p < pfx.length; p++) {
          if (!pfx[p]) type = type.toLowerCase();
          if (isAdd)
            element.addEventListener(pfx[p] + type, callback, false);
          else
            element.removeEventListener(pfx[p] + type, callback, false);
        }
      }
    }
    drag.intial(down_target, move_target, down, move, up);
    return drag;
  }
  //**********獲取元素相對螢幕的xy值*******************
  var elmentTop = function(e) { /*獲取元素相對於螢幕的X值*/
    var offset = e.offsetTop;
    if (e.offsetParent != null)
      offset += arguments.callee(e.offsetParent);
    return offset;
  }
  var elmentLeft = function(e) { /*獲取元素相對於螢幕的Y值*/
      var offset = e.offsetLeft;
      if (e.offsetParent != null)
        offset += arguments.callee(e.offsetParent);
      return offset;
    }
    //刮刮卡物件
  exports.guagua = function(opts) {
    opts = opts || {};
    this.parent = opts.parent;
    this.color = opts.color || "#555";
    this.unit = opts.unit || 10;
    this.range = opts.range || 5;
    this.fuzzy = opts.fuzzy || 3;
    this.rate = opts.rate || 0.7;
    this.success = opts.success || null;
    this.successed = false;
    this.draws = [];
    this.drawsed = [];
    if (this.parent != undefined && this.parent != null) {
      this.width = this.parent.offsetWidth;
      this.height = this.parent.offsetHeight;
      this.lastMoveX = null;
      this.lastMoveY = null;
      this.intial();
    }
  }
  guagua.prototype = {
    intial: function() {
      this.rows = Math.round(this.width / this.unit);
      this.columns = Math.round(this.height / this.unit);
      this.createDraw();
      this.createMask();
    },
    createUnit: function() {
      var div = document.createElement('div');
      div.style.margin = 0;
      div.style.position = "absolute";
      div.style.width = this.unit + "px";
      div.style.height = this.unit + "px";
      div.style.backgroundColor = this.color;
      div.style.zIndex = 1;
      div.style.border = "none";
      div.style.padding = 0;
      return div;
    },
    createDraw: function() {
      for (var i = 0; i < this.columns; i++)
        for (var j = 0; j < this.rows; j++) {
          var div = this.createUnit();
          div.style.left = (j * this.unit) + "px";
          div.style.top = (i * this.unit) + "px";
          div.id = (i * this.unit) + "|" + (j * this.unit);
          this.draws.push(div.id);
          this.parent.appendChild(div);
        }
    },
    createMask: function() {
      var div = document.createElement('div');
      div.style.margin = 0;
      div.style.position = "absolute";
      div.style.width = this.width + "px";
      div.style.height = this.height + "px";
      div.style.left = 0;
      div.style.top = 0;
      div.style.zIndex = 2;
      var that = this;
 
      function move(e) {
        var moveX = e.pageX - document.downX,
          moveY = e.pageY - document.downY;
        that.drawMove(moveX, moveY);
        // console.log("x,y:" + moveX + "," + moveY);
      }
 
      function up(e) {
        that.lastMoveX = null;
        that.lastMoveY = null;
      }
 
      function down(e) {
        document.downX = elmentLeft(this);
        document.downY = elmentTop(this);
      }
      touchEvent(div, down, move, up);
      this.drawer = dragEvent(div, div, down, move, up);
      this.parent.appendChild(div);
    },
    drawMove: function(moveX, moveY) {
      moveX = Math.round(moveX);
      moveY = Math.round(moveY);
      for (var k = 0; k < this.range; k++) {
        var range = Math.round(Math.sqrt(this.range * this.range - k * k)); //獲取圓形區域
        this.doDraw(k + moveX, range, moveY, moveX);
        this.doDraw(moveX - k, range, moveY, moveX);
      }
      this.doDrawLine(moveX, moveY);
    },
    doDraw: function(j, range, moveY, moveX) {
      var alpha, start = moveY - range,
        end = moveY + range,
        flag = false;
      for (var i = start; i < end; i++) {
        var id = i + "|" + j;
        var div = document.getElementById(id);
        if (div != undefined && div != null) {
          flag = false
          for (k = this.range - this.fuzzy, m = 0; k < this.range; k++, m++) {
            alpha = m * 100 / this.fuzzy;
            if ((j - moveX) * (j - moveX) + (i - moveY) * (i - moveY) >= k * k) {
              div.style.filter = 'alpha(opacity=' + alpha + ')';
              div.style.opacity = alpha / 100;
              flag = true;
            }
          }
          if (!flag) {
            div.style.background = "";
            if (this.drawsed.indexOf(id) < 0) {
              this.drawsed.push(id);
            }
            if (this.drawsed.length / this.draws.length > this.rate) {
              if (!this.successed) {
                this.successed = true;
                this.drawer.mouseup();
                if (this.success != undefined && typeof(this.success) == "function")
                  this.success.call(this);
                return;
              }
            }
          }
 
        }
      }
    },
    doDrawLine: function(moveX, moveY) {
      if (this.lastMoveX != null && this.lastMoveY != null) {
        var k = -(moveY - this.lastMoveY) / (moveX - this.lastMoveX);
        var startX, endX, startY, endY, lineX, lineY;
        if (moveX < this.lastMoveX) {
          endX = this.lastMoveX;
          startX = moveX;
          endY = this.lastMoveY;
          startY = moveY;
        } else {
          endX = moveX;
          startX = this.lastMoveX
          endY = moveY;
          startY = this.lastMoveY;
        }
        for (var i = 0; i < endX - startX; i++) {
          lineX = startX + i;
          lineY = Math.round(startY - i * k);
          this.doDraw(lineX, this.range, lineY, lineX);
        }
      }
      this.lastMoveX = moveX;
      this.lastMoveY = moveY;
    }
  }
}(window));
</script>
</head>
<body>
<div id="rectangle">一等獎</div>
<script>
var gua = new guagua({
  parent: document.getElementById("rectangle"),
  unit: 4, //顆粒大小
  range: 10, //繪製範圍
  fuzzy: 5, //羽化範圍
  rate: 0.6,//掛出的面積比例
  success: function () {
    alert("恭喜您中獎了");
  }
});
</script>
</body>
</html>

相關文章