zoukankan      html  css  js  c++  java
  • 移动端canvas扭蛋机

    在这里插入图片描述
    在这里插入图片描述

    <template>
      <div class="component">
        <div class="bg">
          <div class="lotterybg" :style="`background: url(`+canvasUrl+`)center center / cover no-repeat`">
            <canvas
              :style="canvasStyle"
              id="myCanvas"
            ></canvas>
          </div>
        </div>
         <div v-for="(item,index) in prizeList" :key="index">
          <img
          :src="item.picUrl"
          class="imgSrc"
        />
        </div>
          <!-- <img src="https://www.17sucai.com/preview/5730/2018-03-05/2/images/an_go.png" id="start" @click="play" /> -->
        <div id="award" :style="awardStyle"><span id="awardBall" :style="`background: url(`+awardImgUrl+`)center center / cover no-repeat`"> 
        </span></div> 
      </div>
    </template>
    <script src="./js/point"></script>
    // <script src="./js/hidpi-canvas.min"></script>
    <script>
    import Ball from './js/point'
    export default {
      name: 'twistedEgg',
      props: {
        canvasUrl: {
          editor: {
            type: 'image',
            label: '扭蛋机背景图',
          },
          type: String,
          default: 'https://vueweb.oss-cn-qingdao.aliyuncs.com/vueweb/resource/ymm_1632812102882.png',
        },
        isData: {
              type: Boolean,
              default: false,
              editor: {
                  type: 'boolean',
                  label: '是否数据源'
              }
          },
        dataScoped: {
            type: String,
            default: '',
            editor: {
                type: 'string',
                label: '数据源名称(dataHub)'
            }
        },
        imgUrl: {
          type: Array,
          default () {
            return [
              {
                url: 'https://vueweb.oss-cn-qingdao.aliyuncs.com/vueweb/resource/ymm_1632810357807.png'
              }
            ]
          },
          editor: {
            ignore: true
          }
        },
        canvasWidth: {
          default: 300,
          type: Number,
          editor: {
              type: 'number',
              label: '扭蛋区域的宽',
          }
        },
        canvasHeight: {
          default: 292,
          type: Number,
          editor: {
              type: 'number',
              label: '扭蛋区域的高',
          }
        },
        canvasTop: {
          default: -26,
          type: Number,
          editor: {
              type: 'number',
              label: '扭蛋区域距离顶部的距离',
          }
        },
        canvasLeft: {
          default: 26,
          type: Number,
          editor: {
              type: 'number',
              label: '扭蛋区域距离左侧的值',
          }
        },
         canvasBorderRadius: {
          default: '0',
          type: String,
          editor: {
              type: 'string',
              label: '扭蛋区域的圆角',
          }
        },
        canvasPadding: {
          default: 0,
          type: Number,
          editor: {
              type: 'number',
              label: '扭蛋区域内边距',
          }
        },
        ballWidth: {
          default: 65,
          type: Number,
          editor: {
              type: 'number',
              label: '扭蛋宽',
          }
        },
        ballHeight: {
          default: 66,
          type: Number,
          editor: {
              type: 'number',
              label: '扭蛋高',
          }
        },
        awardPosition: {
            type: String,
            default: ' 50px;height: 50px;top: 380px;left:10px',
            editor: {
                type: 'string',
                label: '出口位置'
            }
        },
        functionPop: {
          type: String,
          editor: {
            type: 'string',
            label: '抽奖完成奖品弹出框方法:',
          },
        },
      },
      computed: {
          // 数据源列表
        prizeList () {
          if (this.isData) {
             if (!this.isEmpty(this.$parent.DataHub) && !this.isEmpty(this.$parent.DataHub[this.dataScoped])) {
                return this.$parent.DataHub[this.dataScoped]
            } else {
                return []
            }
          } else {
              return this.fakeDataSource
          }
        },
        canvasStyle () {
          let style = {
            top: this.canvasTop + 'px',
            left: this.canvasLeft + 'px',
            borderRadius: this.canvasBorderRadius,
            padding: this.canvasPadding + 'px',
          }
          return style
        },
        awardStyle () {
           return `${this.awardPosition};color:${this.itemTextColor};`
        },
      },
      data () {
        return {
          canvas: '',
          ctx: '',
          ballList: [],
          ballNum: '',
          awardList: [],
          scale: 1,
          fakeDataSource: [
            {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/5.png',
            },
              {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/7.png',
            },
              {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/6.png',
            }, {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/5.png',
            },
             {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/5.png',
            },
              {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/7.png',
            },
              {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/6.png',
            }, {
                'picUrl': 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/5.png',
            },
          ],
          awardImgUrl: 'https://vueweb.oss-cn-qingdao.aliyuncs.com/platform/5.png',
        }
      },
      editorMethods: {
      },
      watch: {
      },
      mounted () {
              this.demo()
      },
      methods: {
        demo () {
          this.canvas = document.getElementById('myCanvas')
          this.scale = window.devicePixelRatio
          this.canvas.width = this.canvasWidth * this.scale
          this.canvas.height = this.canvasHeight * this.scale
          this.canvas.style.width = this.canvas.width / this.scale + 'px'
          this.canvas.style.height = this.canvas.height / this.scale + 'px'
          this.ctx = this.canvas.getContext('2d')
          this.ballList = Array.from(document.getElementsByClassName('imgSrc'))
          this.ballNum = this.ballList.length // 扭蛋机里面的小球数
           for (let i = 0; i < this.ballNum; i++) { // 随机生成各色小球
            this.awardList[i] = new Ball(this.canvas, this.ballList[i], this.ballWidth, this.ballHeight, i) // 新建小球对象
          }
        },
        isEmpty (str) {
          if (typeof str == 'undefined' || str == null || str == '') {
              return true
          } else {
              return false
          }
        },
        play () {
           var award = document.getElementById('awardBall')
           award.removeAttribute('class', 'dropBall')
          if (this.awardList.length === 0) { // 奖池中没有小球
            this.init()
          } else {
            window.clearInterval(this.timer) // 清除计时器
            this.timer = setInterval(() => {
              this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) // 清空画布
              for (let i = 0; i < this.awardList.length; i++) {
                this.awardList[i].run(this.ctx, this.canvas, this.ballWidth, this.ballHeight)
              } // 使小球运动
            }, 15)
            this.clear()
          }
        },
        init () { // 初始化
          for (let i = 0; i < this.ballNum; i++) { // 随机生成各色小球
            let index = Math.floor(4 * Math.random())
            this.awardList[i] = new Ball(this.canvas, index, this.ballList[index]) // 新建小球对象
          }
          window.clearInterval(this.timer) // 清除计时器
          this.timer = setInterval(() => {
            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) // 清空画布
            for (let i = 0; i < this.awardList.length; i++) {
              this.awardList[i].run(this.ctx, this.canvas, this.ballWidth, this.ballHeight)
            } // 使小球运动
          }, 100)
          this.clear()
        },
        clear () {
         var award = document.getElementById('awardBall')
         document.getElementById('awardBall').style.display = 'inline'
          setTimeout(() => {
           window.clearInterval(this.timer) // 清除计时器
            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) // 清空画布
            for (let i = 0; i < this.ballNum; i++) { // 随机生成各色小球
            this.awardList[i] = new Ball(this.canvas, this.ballList[i], this.ballWidth, this.ballHeight, i) // 新建小球对象
          }
           award.setAttribute('class', 'dropBall')
          }, 1500)
            let that = this
          setTimeout(() => {
             if (!that.functionPop) {
                return
              }
              eval(`that.${that.functionPop}()`)
          }, 1600)
        }
      }
    }
    </script>
    
    <style lang="stylus" rel="stylesheet/stylus" type="text/stylus" scoped>
    .component {
      width: 100%;
      height: 100%;
    }
    
    .bg {
      position: absolute;
      width: 100%;
      height: 100%;
    }
    
    .lotterybg {
      position: absolute;
      background-size: contain;
      overflow: visible;
      width: 100%;
      height: 100%;
    }
    
    #myCanvas {
      position: absolute;
      border: none;
      // background-color: rgb(118, 185, 185);
    }
    
    #start {
      position: absolute;
      z-index: 3;
      width: 50px;
      margin-top: 370px;
      margin-left: 50%;
    }
    
    .imgSrc {
      display:none;
      position: absolute;
    }
    
    #award {
      position: absolute;
      border: none;
    }
    .awardImgUrl{
      width :100%;
      height :100%
    }
    #awardBall{
      display :none
    }
    .dropBall {
       content: "";position: absolute;left: 0;top: 0;
       width: 100%;height: 100%;
       display: block;
       background-size: contain;
       animation: drop 1s ease-out forwards;
       -webkit-animation: drop 1s ease-out forwards;
       }
    @keyframes drop {
        0% {
            transform: scale(0.7);
        }
        50% {
            transform: scale(1);
        }
        51% {
            transform: translateY(0px);
        }
        100% {
            transform: translateY(10px);
        }
    }
    
    @-webkit-keyframes drop {
        0% {
            -webkit-transform: scale(0.7);
        }
        50% {
            -webkit-transform: scale(1);
        }
        51% {
            -webkit-transform: translateY(0px);
        }
        100% {
            -webkit-transform: translateY(10px);
        }
    }
    </style>
    
    

    point.js

    class Ball {
        constructor (canvas, img, width, height, index) {
        //scale 是为了解决移动端图片模糊问题 有点乱,后期再整理
            this.scale = window.devicePixelRatio
            //小球随机位置设置到容器下半部分,不至于悬浮在上面
            this.x = this.rand(canvas.width - width * this.scale)
            this.y = this.rand(canvas.height - height * this.scale - (canvas.height / 2)) + canvas.height  / 2
            this.img = img
            this.index = index
            if (width) {
              canvas.getContext('2d').drawImage(this.img, this.x, this.y, width * this.scale, height * this.scale)
            }
            this.init()
        }
        init () {
            do {
                this.speedX = this.rand(20) - 10
            } while (this.speedX < 5)
            do {
                this.speedY = this.rand(20) - 10
            } while (this.speedY < 5)
        }
        rand (num) {
            return Math.random() * num
        }
        run (ctx, canvas, width, height) {
            this.x += this.speedX
            this.y += this.speedY
            if (this.x > canvas.width - width * this.scale) {
                this.speedX = -this.speedX
            }
            if (this.x < 0) {
                this.speedX = Math.abs(this.speedX)
            }
            if (this.y > canvas.height - height * this.scale) {
                this.speedY = -this.speedY
            }
            if (this.y < 0) {
                this.speedY = Math.abs(this.speedY)
            }
            canvas.getContext('2d').drawImage(this.img, this.x, this.y, width * this.scale, height * this.scale)
        }
    }
    export default Ball
    
    请用今天的努力,让明天没有遗憾。
  • 相关阅读:
    什么是Servlet
    Linux进程创建、执行和切换过程理解
    java实现验证码登录
    jsp页面如何动态显示当前时间
    java容器的一些存取用法
    java内存的那些事
    eclipse的常用快捷键
    二叉树前序、中序、后序遍历相互求法
    二叉树的遍历
    jsp添加背景音乐
  • 原文地址:https://www.cnblogs.com/cupid10/p/15617588.html
Copyright © 2011-2022 走看看