zoukankan      html  css  js  c++  java
  • 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 {
       100%;
      height: 100%;
      background-color: #985113;
      padding:100px 0;
      .award_box {
         95%;
        height: 360px;
        margin: 0px auto;
        background: url("./img/2.img")
          no-repeat center/100%;
        padding-top: 70px;
        .award {
           85%;
          height: 180px;
          position: absolute;
          left: 50%;
          transform: translateX(-50%);
           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;
           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;
         100%;
        height: 500px;
        padding:10px;
        bottom:5px solid orange;
        box-sizing:border-box;
      }
    }
  • 相关阅读:
    RE_知识回顾
    python网络爬虫边看边学(selenium模块三验证码)
    python网络爬虫边看边学(selenium模块二无头浏览器)
    python网络爬虫边看边学(selenium模块一)
    python爬虫边看边学(多线程多进程协程)
    python爬虫边看边学(xpath模块解析)
    python爬虫边看边学(bs4安装与使用)
    python爬虫边看边学(数据解析)
    python爬虫边看边学(基础)
    python基础结束
  • 原文地址:https://www.cnblogs.com/huangaiya/p/12755401.html
Copyright © 2011-2022 走看看