vue 中實現刮刮卡


先看一下效果圖:

ps: 圖片有晃動的效果,是博主截圖大小不一致造成的,以至於合成的gif圖有晃動的效果,實際頁面中是沒有的,請勿擔心哦

 

實現的原理: 

  1.通過canvas標簽屬性進行繪畫實現

  2.實際有3層,底層是存放獎品名稱,中層是canvas畫出的刮層,表層是那個紅色的禮節 通過absolute 絕對定位實現重疊效果(單獨切紅色禮節,就是避免計算canvas特殊形狀,只需要簡單地舉行即可)

  3.首次看會以為我的canvas底部畫的是不規則的形狀,其實不然,canvas刮層畫的是矩形,上面通過單獨把 紅色禮節 切圖出來,定位上去的

 

上代碼:

 

1.html :

<template>
  <div class="container" id="top">
    <div class="award_box">
      <div class="award" v-if="showPrize">
        <div class="title">
          恭喜您獲得
          <span>198元享受580元(燙/染2選1)優惠券</span>
        </div>
      </div>
      <div class="surface"></div>
      <canvas
        id="c1"
        class="canvas"
        @touchmove="touchmove"
        @touchstart="touchstart"
        @touchend="touchend"
        v-show="!isScratch"
      ></canvas>
    </div>
    
  </div>
</template>

 

2.js:

export default {
  name: "scratchCard",
  data() {
    return {
      c1: "", //畫布
      ctx: "", //畫筆
      ismousedown: false, //標志用戶是否按下鼠標或開始觸摸
      fontem: "", // 獲取html字體大小
      isScratch: false, // 是否刮過卡
      showPrize: false // 顯示獎品
    };
  },
  mounted() {
    this.fontem = parseInt(
      window.getComputedStyle(document.documentElement, null)["font-size"]
    );
    //這是為了不同分辨率上配合@media自動調節刮的寬度
    this.c1 = document.getElementById("c1");
    //這里很關鍵,canvas自帶兩個屬性width、height,我理解為畫布的分辨率,跟style中的width、height意義不同。
    //最好設置成跟畫布在頁面中的實際大小一樣
    //不然canvas中的坐標跟鼠標的坐標無法匹配
    this.c1.width = this.c1.clientWidth + 15
    this.c1.height = this.c1.clientHeight;
    this.ctx = this.c1.getContext("2d");
    this.initCanvas();
  },
  methods: {
    // 畫刮刮卡
    initCanvas() {
      this.ctx.globalCompositeOperation = "source-over";
      this.ctx.fillStyle = "#e5e5e5";
      this.ctx.fillRect(0, 0, this.c1.clientWidth, this.c1.clientHeight);
      this.ctx.fill();
      this.ctx.font = "Bold 24px Arial";
      this.ctx.textAlign = "center";
      this.ctx.fillStyle = "#a0a0a0";
      this.ctx.fillText("刮開有獎", this.c1.width / 2, 55);
      //有些老的手機自帶瀏覽器不支持destination-out,下面的代碼中有修復的方法
      this.ctx.globalCompositeOperation = "destination-out";
    },
    touchstart(e) {
      e.preventDefault();
      this.ismousedown = true;
    },
    // 操作刮卡
    touchend(e) {
      sessionStorage.setItem('isScratch',true)
      e.preventDefault();
      //得到canvas的全部數據
      var a = this.ctx.getImageData(0, 0, this.c1.width, this.c1.height);
      var j = 0;
      for (var i = 3; i < a.data.length; i += 4) {
        if (a.data[i] == 0) j++;
      }
      //當被刮開的區域等於一半時,則可以開始處理結果
      if (j >= a.data.length / 8) {
        this.isScratch = true;
      }
      this.ismousedown = false;
    },
    touchmove(e) {
      this.showPrize = true
      e.preventDefault();
      if (this.ismousedown) {
        if (e.changedTouches) {
          e = e.changedTouches[e.changedTouches.length - 1];
        }
        var topY = document.getElementById("top").offsetTop;
        var oX = this.c1.offsetLeft,
          oY = this.c1.offsetTop + topY;
        var x = (e.clientX + document.body.scrollLeft || e.pageX) - oX || 0,
          y = (e.clientY + document.body.scrollTop || e.pageY) - oY || 0;
        //畫360度的弧線,就是一個圓,因為設置了ctx.globalCompositeOperation = 'destination-out';
        //畫出來是透明的
        this.ctx.beginPath();
        this.ctx.arc(x, y, this.fontem * 0.5, 0, Math.PI * 2, true); // 調整畫筆的大小
        //下面3行代碼是為了修復部分手機瀏覽器不支持destination-out
        //我也不是很清楚這樣做的原理是什么
        // this.c1.style.display = 'none';
        // this.c1.offsetHeight;
        // this.c1.style.display = 'inherit';
        this.ctx.fill();
      }
    }
  }
};

 

3.css:

.container {
  width: 100%;
  height: 100%;
  background-color: #985113;
  padding:100px 0;
  .award_box {
    width: 95%;
    height: 360px;
    margin: 0px auto;
    background: url("./img/2.img")
      no-repeat center/100%;
    padding-top: 70px;
    .award {
      width: 85%;
      height: 180px;
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      width: 68%;
      .title {
        color: rgba(3, 45, 97, 1);
        font-size: 32px;
        font-weight: 800;
        line-height: 50px;
        margin-top: 50px;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        span {
          color: #cc162d;
        }
      }
    }
    .surface {
      position: absolute;
      z-index: 98;
      width: 95%;
      height: 160px;
      margin: 150px auto;
      background: url("./img/1.png")
        no-repeat center/100%;
      padding-top: 70px;
    }
    .canvas {
      position: relative;
    }
  }

  .map_box{
    margin-top: 200px;
    width: 100%;
    height: 500px;
    padding:10px;
    bottom:5px solid orange;
    box-sizing:border-box;
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM