zoukankan      html  css  js  c++  java
  • vue刮刮卡抽奖效果

    效果图如下:

      

    以下代码仅为刮刮卡部分:

    <template>
      <div class="scratch-card">
        <div :style="computedBgStyle" class="scratch-card-bg">
          <div class="canvas-wrap">
            <div class="prize-wrap">
              <h2 class="prize-item">一等奖</h2>
              <p class="prize-item">新秀丽行李箱新秀丽行李箱新秀丽行李箱新秀丽行李箱</p>
            </div>
            <canvas id="canvasMask" class="canvas"></canvas>
          </div>
        </div>
      </div>
    </template>
     
    <script>
    import { CTX, VERSION } from '@/constants/context'
    export default {
      props: {
        config: {
          type: Object,
          required: true
        }
      },
      data() {
        return {
          canvas: null,
          context: null,
           450, // canvas宽度
          height: 250, // canvas高度
          scaleRatio: 1 // 缩放比例
        }
      },
      computed: {
        computedBgStyle() {
          if(this.config.turnTableImg) {
            return {
              'backgroundImage': `url(${this.config.turnTableImg})`
            }
          }else {
            return {
              'backgroundImage': `url(${CTX}/static/img/scratch-card/prize-bg.png?v=${VERSION})`
            }
          }
        }
      },
      mounted() {
        this.$nextTick(() => {
          const clientW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
          this.scaleRatio = clientW / 750
          this.canvas = document.getElementById('canvasMask')
          this.canvas.width = this.width * this.scaleRatio
          this.canvas.height = this.height * this.scaleRatio
          this.context = this.canvas.getContext('2d')
          // 画灰色涂层图片
          const coatImg = new Image()
          coatImg.src = `${CTX}/static/img/scratch-card/coat-img.png?v=${VERSION}`
          coatImg.addEventListener('load', () => {
            this.context.drawImage(coatImg, 0, 0, this.canvas.width, this.canvas.height)
            // 启用了globalCompositeOperation= = 'destination-out' 之后,在 canvs 上绘制的新的图形,就会使得之前的 mask 变成透明的,从而显示出背景图片来。
            this.context.globalCompositeOperation = 'destination-out'
            // 监听touchmove
            this.canvas.addEventListener('touchmove', this.moveHandler)
          })
        })
      },
      methods: {// 手指划过 画圆
        moveHandler(event) {
          let context = this.context
          event.preventDefault()
          context.beginPath()
          // 根据某个点在canvas上画圆
          // x 坐标和 y 坐标 两个坐标是触摸点的坐标而不是画圆的圆心
          // 圆心通过计算得出
          var canvasRect = this.canvas.getBoundingClientRect()
          context.arc(event.touches[0].pageX - canvasRect.left, event.touches[0].pageY - canvasRect.top, 20 * this.scaleRatio, 0, Math.PI * 2)
          context.closePath()
          context.fillStyle = '#dddddd'
          context.fill()
          this.checkComplete()
        },
        // 检查完成度,判断是否完成刮奖 点数大于80%
        checkComplete() {
          var imgData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)
          var pxData = imgData.data // 获取字节数据
          var len = pxData.length // 获取字节长度
          var count = 0 // 记录透明点的个数
          // 主要的思想是 一个像素由四个数据组成,每个数据分别是 rgba() 所以第四个数据 a 表示alpha透明度
          for (var i = 0; i < len; i += 4) {
            var alpha = pxData[i + 3] // 获取每个像素的透明度
            if (alpha < 10) {
              // 透明度小于10
              count++
            }
          }
          var percent = count / (len / 4) // 计算百分比
          // 如果百分比大于0.8 则表示成功
          if (percent >= 0.8) {
            this.showResult()
          }
        },
        // 显示刮奖结果
        showResult() {
          this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
          alert('刮奖成功')
        }
      }
    }
    </script>
     
    <style lang="scss" scoped>
      .scratch-card {
         px2rem(690px);
        height: px2rem(546px);
        margin: 0 auto;
        position: relative;
        &-bg {
           100%;
          height: 100%;
          background-size: 100% 100%;
          padding-top: px2rem(204px);
        }
      }
      .canvas-wrap {
         px2rem(504px);
        height: px2rem(300px);
        background-image: img-url('../../assets/img/scratch-card/bg-scratch.png');
        background-size: 100% 100%;
        margin: 0 auto;
        position: relative;
        color: #fff;
        text-align: center;
        .prize-wrap {
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
          padding: 0 px2rem(30px);
        }
        .prize-item {
          @include font-dpr(30px);
          @include lh-dpr(42px);
          font-weight: 600;
          &:first-child {
            margin-bottom: px2rem(16px);
          }
        }
        .canvas {
          background-size: 100% 100%;
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
        }
      }
    </style>
  • 相关阅读:
    算法训练 P1103
    算法训练 表达式计算
    算法训练 表达式计算
    基础练习 时间转换
    基础练习 字符串对比
    Codeforces 527D Clique Problem
    Codeforces 527C Glass Carving
    Codeforces 527B Error Correct System
    Codeforces 527A Glass Carving
    Topcoder SRM 655 DIV1 250 CountryGroupHard
  • 原文地址:https://www.cnblogs.com/uno1990/p/12448422.html
Copyright © 2011-2022 走看看