美文网首页
Vue<幸运抽奖-刮刮卡>

Vue<幸运抽奖-刮刮卡>

作者: 誰在花里胡哨 | 来源:发表于2021-01-08 18:56 被阅读0次
ozwZI4ie5R.gif
实现思路:

主要是通过jq,canvas画布实现的,因为这里是用的别人的代码,这里主要跟大家说下怎么使用。

1.首先需要配置下jq到你的项目中
vue-cli2.0配置方法
vue-cli3.0好像直接 npm 下就可以了

2.我这边是通过mixin混合使用的别人的代码,因为这样看起来比较简洁,具体引用代码 jquery.eraser.js 看最下面

参数:

        completeRatio: 0.5, //当画布被擦除50%时触发事件
        size: 40, //橡皮擦大小,默认40
        completeFunction: function() { //擦出百分比达到 completeRatio 标准时执行的方法
          alert('谢谢参与')
        }

遇到问题:

1.目前代码的遮罩层及涂刮层必须是图片,而且canvas会根据图片尺寸的大小去创建画布,因此最终的大小是根据图片尺寸生成的;结果层是不受限制的,你可以设置成图片,也可以写成标签形式;
建议把图片的尺寸和标签大小都设成 330*126像素,基本都能在移动端正常显示了

2.你会发现,我在初始化方法 this.init() 的时候添加了一个计时器,因为有时候进入页面引入的部分代码没有执行,目前我这边是加上了一个计时器才解决的。原来的代码用的是监听页面的加载 addEventListener ,但是这种方法是存在问题的

 window.addEventListener('load', this.init, false)

使用页面:

<template>
  <div>
    <div class="container">
      <!-- 涂刮蹭 -->
      <img id="redux" src="@/assets/img/bb5fa12a-60a3-496c-8897-8c9190ff494b.png" />
      <!-- 结果层 也可以替换成标签 -->
      <!-- <img id="robot" src="@/assets/img/Tesla.jpg" /> -->
      <div v-if="load" id="robot">谢谢参与</div>
    </div>
    <h2>{{result}}</h2>
  </div>
</template>

<script>
import { jqueryEraser } from '../../assets/js/jquery.eraser'
export default {
  mixins: [jqueryEraser],
  data() {
    return {
      load: false,
      result: ''
    }
  },
  mounted() {
    setTimeout(() => {
      this.init()
    }, 300)
  },
  methods: {
    init(event) {
      let _this = this
      console.log(111)
      $('#redux').eraser({
        completeRatio: 0.7, //当画布被擦除50%时触发事件
        size: 50, //橡皮擦大小,默认40
        completeFunction: function() {
          _this.result = '谢谢参与'
        }
      })
      _this.load = true
    }
  }
}
</script>

<style lang="scss" scoped>
.container {
  display: inline-block;
  margin: 0 10%;
  position: relative;
  width: 330px;
  height: 126px;
  * {
    -webkit-touch-callout: none;
    -webkit-text-size-adjust: none;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    -webkit-user-select: none;
  }
}
#robot {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 50px;
  font-weight: bold;
  color: red;
  background: rgb(238, 238, 238);
}
#redux {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 9;
}
</style>

jquery.eraser.js引用代码:

export const jqueryEraser = {
  mounted() {
    var methods = {
      init: function (options) {
        return this.each(function () {
          var $this = $(this),
            data = $this.data('eraser');

          if (!data) {
            var width = $this.width(),
              height = $this.height(),
              pos = $this.offset(),
              $canvas = $("<canvas/>"),
              canvas = $canvas.get(0),
              size = (options && options.size) ? options.size : 40,
              completeRatio = (options && options.completeRatio) ? options.completeRatio : .7,
              completeFunction = (options && options.completeFunction) ? options.completeFunction : null,
              parts = [],
              colParts = Math.floor(width / size),
              numParts = colParts * Math.floor(height / size),
              n = numParts,
              ctx = canvas.getContext("2d");
            console.log(width, height);
            // replace target with canvas
            $this.after($canvas);
            canvas.id = this.id;
            canvas.className = this.className;
            canvas.style.position = 'absolute'
            canvas.style.left = 0
            canvas.style.top = 0
            canvas.style.zIndex = 99
            canvas.width = width;
            canvas.height = height;
            ctx.drawImage(this, 0, 0);
            $this.remove();

            // prepare context for drawing operations
            ctx.globalCompositeOperation = "destination-out";
            ctx.strokeStyle = 'rgba(255,0,0,255)';
            ctx.lineWidth = size;

            ctx.lineCap = "round";
            // bind events
            $canvas.bind('mousedown.eraser', methods.mouseDown);
            $canvas.bind('touchstart.eraser', methods.touchStart);
            $canvas.bind('touchmove.eraser', methods.touchMove);
            $canvas.bind('touchend.eraser', methods.touchEnd);

            // reset parts
            while (n--) parts.push(1);

            // store values
            data = {
              posX: pos.left,
              posY: pos.top,
              touchDown: false,
              touchID: -999,
              touchX: 0,
              touchY: 0,
              ptouchX: 0,
              ptouchY: 0,
              canvas: $canvas,
              ctx: ctx,
              w: width,
              h: height,
              source: this,
              size: size,
              parts: parts,
              colParts: colParts,
              numParts: numParts,
              ratio: 0,
              complete: false,
              completeRatio: completeRatio,
              completeFunction: completeFunction
            };
            $canvas.data('eraser', data);

            // listen for resize event to update offset values
            $(window).resize(function () {
              var pos = $canvas.offset();
              data.posX = pos.left;
              data.posY = pos.top;
            });
          }
        });
      },
      touchStart: function (event) {
        var $this = $(this),
          data = $this.data('eraser');

        if (!data.touchDown) {
          var t = event.originalEvent.changedTouches[0],
            tx = t.pageX - data.posX,
            ty = t.pageY - data.posY;
          methods.evaluatePoint(data, tx, ty);
          data.touchDown = true;
          data.touchID = t.identifier;
          data.touchX = tx;
          data.touchY = ty;
          event.preventDefault();
        }
      },
      touchMove: function (event) {
        var $this = $(this),
          data = $this.data('eraser');

        if (data.touchDown) {
          var ta = event.originalEvent.changedTouches,
            n = ta.length;
          while (n--)
            if (ta[n].identifier == data.touchID) {
              var tx = ta[n].pageX - data.posX,
                ty = ta[n].pageY - data.posY;
              methods.evaluatePoint(data, tx, ty);
              data.ctx.beginPath();
              data.ctx.moveTo(data.touchX, data.touchY);
              data.touchX = tx;
              data.touchY = ty;
              data.ctx.lineTo(data.touchX, data.touchY);
              data.ctx.stroke();
              event.preventDefault();
              break;
            }
        }
      },
      touchEnd: function (event) {
        var $this = $(this),
          data = $this.data('eraser');

        if (data.touchDown) {
          var ta = event.originalEvent.changedTouches,
            n = ta.length;
          while (n--)
            if (ta[n].identifier == data.touchID) {
              data.touchDown = false;
              event.preventDefault();
              break;
            }
        }
      },

      evaluatePoint: function (data, tx, ty) {
        var p = Math.floor(tx / data.size) + Math.floor(ty / data.size) * data.colParts;
        if (p >= 0 && p < data.numParts) {
          data.ratio += data.parts[p];
          data.parts[p] = 0;
          if (!data.complete) {
            if (data.ratio / data.numParts >= data.completeRatio) {
              data.complete = true;
              if (data.completeFunction != null) data.completeFunction();
            }
          }
        }

      },

      mouseDown: function (event) {
        var $this = $(this),
          data = $this.data('eraser'),
          tx = event.pageX - data.posX,
          ty = event.pageY - data.posY;
        methods.evaluatePoint(data, tx, ty);
        data.touchDown = true;
        data.touchX = tx;
        data.touchY = ty;
        data.ctx.beginPath();
        data.ctx.moveTo(data.touchX - 1, data.touchY);
        data.ctx.lineTo(data.touchX, data.touchY);
        data.ctx.stroke();
        $this.bind('mousemove.eraser', methods.mouseMove);
        $(document).bind('mouseup.eraser', data, methods.mouseUp);
        event.preventDefault();
      },

      mouseMove: function (event) {
        var $this = $(this),
          data = $this.data('eraser'),
          tx = event.pageX - data.posX,
          ty = event.pageY - data.posY;
        methods.evaluatePoint(data, tx, ty);
        data.ctx.beginPath();
        data.ctx.moveTo(data.touchX, data.touchY);
        data.touchX = tx;
        data.touchY = ty;
        data.ctx.lineTo(data.touchX, data.touchY);
        data.ctx.stroke();
        event.preventDefault();
      },

      mouseUp: function (event) {
        var data = event.data,
          $this = data.canvas;
        data.touchDown = false;
        $this.unbind('mousemove.eraser');
        $(document).unbind('mouseup.eraser');
        event.preventDefault();
      },

      clear: function () {
        var $this = $(this),
          data = $this.data('eraser');
        if (data) {
          data.ctx.clearRect(0, 0, data.w, data.h);
          var n = data.numParts;
          while (n--) data.parts[n] = 0;
          data.ratio = data.numParts;
          data.complete = true;
          if (data.completeFunction != null) data.completeFunction();
        }
      },

      size: function (value) {
        var $this = $(this),
          data = $this.data('eraser');
        if (data && value) {
          data.size = value;
          data.ctx.lineWidth = value;
        }
      },

      reset: function () {
        var $this = $(this),
          data = $this.data('eraser');
        if (data) {
          data.ctx.globalCompositeOperation = "source-over";
          data.ctx.drawImage(data.source, 0, 0);
          data.ctx.globalCompositeOperation = "destination-out";
          var n = data.numParts;
          while (n--) data.parts[n] = 1;
          data.ratio = 0;
          data.complete = false;
        }
      }
    }
    $.fn.eraser = function (method) {
      if (methods[method]) {
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
      } else if (typeof method === 'object' || !method) {
        return methods.init.apply(this, arguments);
      } else {
        $.error('Method ' + method + ' does not yet exist on jQuery.eraser');
      }
    };
  },
}

相关文章

  • Vue<幸运抽奖-刮刮卡>

    主要是通过jq,canvas画布实现的,因为这里是用的别人的代码,这里主要跟大家说下怎么使用。 1.首先需要配置下...

  • LuckyDraw幸运大抽奖(卡片、转盘、点云、幸运星)

    Introduction: 幸运抽奖Vue Web项目Luck draw Vue web project.GitH...

  • php实现刮刮卡大转盘抽奖概率

    php实现刮刮卡大转盘抽奖概率 本文实例为大家分享了php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法,用法很简单...

  • 魔众刮刮卡抽奖系统 v2.0.0 支付抽奖,更好用的刮刮卡系统

    魔众刮刮卡抽奖系统是一个可快速私有化的刮刮卡系统,可以创建多个刮刮卡活动,奖品支持现金红包、积分、实物礼品、兑换码...

  • Vue<幸运抽奖-砸金蛋>

    通过控制css动画的时间,来控制小锤子角度的变化,以及金蛋的消失,因此这里没有用到canvas等过多的js逻辑。 ...

  • Vue<幸运抽奖-翻牌子>

    1.实现反转的效果并不难,通过 的 就能实现; 2.根据参数 配置好卡片的数量,默认每张卡片后面都是空的,只有当用...

  • D14亲子阅读和个人成长记录

    坤宝期待了一天的刮刮卡抽奖结果不尽人意。 本来单元小测试考了个不错的成绩,按照班级规定,第一个上台抽取刮刮卡,却只...

  • Vue<幸运抽奖-大转盘>

    大转盘啊,大转盘。看了好多代码,很多都是通过 实现的,也有别的是通过计时器实现的,但是无非 代码多的一批,还看不懂...

  • Vue<幸运抽奖-老虎机🎰>

    此篇文章实现的原理和 比较类似,所以像更好的理解老虎机的实现原理,可以去参考下,这里针对细节方面就不做过多的解释了...

  • 2018-12-27抽奖

    2018-12-27(五)实现幸运抽奖 1. 需求说明 (1) . 登录成功后,用户选择幸运抽奖菜单,进入幸运抽奖...

网友评论

      本文标题:Vue<幸运抽奖-刮刮卡>

      本文链接:https://www.haomeiwen.com/subject/wnifaktx.html