• JS框架_(JQuery.js)模拟刮奖


     百度云盘:传送门  密码:6p5q

    纯CSS模拟刮奖效果

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <style>
            *{
                margin: 0;
                padding: 0;
            }    
            
            p {
              position: fixed;
              top: 60%;
              left: 0;
              right: 0;
              text-align: center;
              transform: translateY(-50%);
              font-size: 40px;
              font-weight: 900;
              color: white;
              text-shadow: 0 0 50px black;
              text-transform: capitalize;
              font-family: 'Roboto','Helvetica','Arial',sans-serif;
              letter-spacing: 5px;
            }
            
            .box{
                margin: 80px;
                position: relative;
                width: 300px;
                height: 180px;
                left: 460px;
            }
            #canvas{
                position: absolute;
                top: 0;
                left: 0;
                z-index: 5;
            }
            .bk{
                width: 300px;
                height: 180px;
                background: #fff;
                position: absolute;
                top: 0;
                left: 0;
                text-align: center;
                line-height: 180px;
            }
            #freshBtn{
                margin-left: 660px;
                user-select: none;
                background: #ddd;
                width: 80px;
                height: 40px;
                text-align: center;
                line-height: 40px;
            }
        </style>
    <body>
    <p>Gary</p>
        <div class="box">
            <div class="bk">
                一等奖
            </div>
            <canvas id="canvas"></canvas>
        </div>
        <div id="freshBtn">重置</div>
    </body>
    <script src="./js/canvas.js"></script>
    <script>
        var canvas = new canvasInit({
            id: 'canvas',
            text: '刮开抽奖',
            cover: '#1f1f1f',
            coverType: 'color',
             300,
            height: 180,
            drawPercentCallback: (num) => {
                if(num > 30) {
                    alert('恭喜获得一等奖')
                    canvas.fresh() // 重置
                }
            }
        })
    </script>
    </html>
    index.html
    class canvasClass {
        constructor (id,text,cover,coverType,width,height,drawPercentCallback) {
            this.conId = id; /*canvasID */
            this.conNode = document.getElementById(this.conId);
            this.ctx = this.conNode.getContext('2d');
            this.coverText = text;
            this.cover = cover; /**图层颜色或图片 */
            this.coverType = coverType; /**图层类型(image/color) */
            this.width = width;
            this.height = height;
            this.drawPercentCallback = drawPercentCallback
            this.clientRect = null;
            this.isMouseDown = false;
        }
        /**
         * 绘制canvas
         */
        fillCanvas () {
            this.conNode.setAttribute('width', this.width);
            this.conNode.setAttribute('height', this.height);
            if (this.coverType == 'color') {
                this.ctx.save();
                this.ctx.fillStyle = this.cover;
                this.ctx.fillRect(0, 0, this.width, this.height);
                this.ctx.restore();
                this.ctx.save();
                var fontSize = 30;
                this.ctx.font = '30px Arial';
                this.ctx.textAlign = 'center';
                this.ctx.fillStyle = '#fff';
                this.ctx.fillText(this.coverText, this.width/2, this.height/2+fontSize/2);
                this.ctx.restore();
                this.ctx.globalCompositeOperation = 'destination-out';
            } else if (this.coverType == 'image') {
                var image = new Image(this.width, this.height)
                image.onload = () => {
                    this.ctx.drawImage(image, 0, 0, this.width, this.height);
                }
                image.src = this.cover;
            }
            this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null
        }
        /**
         * 事件监听
         */
        bindEvent () {
            /**移动端检测 */
            var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
            var clickEvt = device ? 'touchstart' : 'mousedown';
            var moveEvt = device ? 'touchmove' : 'mousemove';
            var x1,y1,x2,y2;
            
            if (!device) {
                document.addEventListener('mouseup', (e) => {
                    this.isMouseDown = false;
                })
            } else {
                document.addEventListener("touchmove", (e) => {
                    if (this.isMouseDown) {
                        e.preventDefault();
                    }
                })
                document.addEventListener("touchend", (e) => {
                    this.isMouseDown = false;
                })
            }
            /**添加监听 */
            this.conNode.addEventListener(clickEvt, (e) => {
                this.isMouseDown = true;
                x1 = device ? e.touches[0].offsetX : e.offsetX;
                y1 = device ? e.touches[0].offsetY : e.offsetY;
                this.drawPoint(x1, y1)
            })
            this.conNode.addEventListener(moveEvt, (e) => {
                if (!device && !this.isMouseDown) {
                    return false;
                }
                this.isMouseDown = true;
                x2 = device ? e.touches[0].offsetX : e.offsetX;
                y2 = device ? e.touches[0].offsetY : e.offsetY;
                this.drawPoint(x1, y1, x2, y2)
                // console.log(x1,x2,y1,y2)
                x1 = x2
                y1 = y2
                // [x1, y1] = [x2, y2]
            })
        }
        /**
         * 抹去, 返回百分比
         */
        drawPoint (x1, y1, x2, y2) {
            var bar = 20; // 半径
            this.ctx.beginPath();
            if (x2) {
                /**
                 * 优化绘制路径
                 */
                var asin = bar*Math.sin(Math.atan((y2-y1)/(x2-x1)));
                var acos = bar*Math.cos(Math.atan((y2-y1)/(x2-x1)))
                var x3 = x1+asin;
                var y3 = y1-acos;
                var x4 = x1-asin;
                var y4 = y1+acos;
                var x5 = x2+asin;
                var y5 = y2-acos;
                var x6 = x2-asin;
                var y6 = y2+acos;
                this.ctx.save();
                this.ctx.beginPath();
                this.ctx.moveTo(x3,y3);
                this.ctx.lineTo(x5,y5);
                this.ctx.lineTo(x6,y6);
                this.ctx.lineTo(x4,y4);
                this.ctx.closePath();
                this.ctx.clip();
                this.ctx.clearRect(0,0,this.width,this.height);
                this.ctx.restore();
                this.ctx.arc(x2, y2, bar, 0, Math.PI*2, true);
            } else {
                this.ctx.arc(x1, y1, bar, 0, Math.PI*2, true);
            }
            this.ctx.fill();
            if (this.drawPercentCallback) {
                this.drawPercentCallback(this.getTransparentPercent());
            }
        }
    
        getTransparentPercent () {
            var imgData = this.ctx.getImageData(0, 0, this.width, this.height),
                pixles = imgData.data,
                transPixs = [];
            for (var i = 0, j = pixles.length; i < j; i += 4) {
                var a = pixles[i + 3];
                if (a < 128) {
                    transPixs.push(i);
                }
            }
            return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
        }
    
    }
    
    function canvasInit(json) {
        var arr = []
        for (let item in json) {
            arr.push(json[item])
        }
        this.init = new canvasClass(...arr)
        this.init.fillCanvas()
        this.init.bindEvent()
    
        var btn = document.querySelector('#freshBtn');
        btn.addEventListener('click', (e) => {
            this.init.fillCanvas()
        });
    
    }
    
    canvasInit.prototype.fresh = function () {
        console.log(this.init)
        this.init.fillCanvas()
        this.init.isMouseDown = false
    }
    canvas.css

    (直接复制就可以使用了O(∩_∩)O~   ES6编写)

    =>是es6语法中的arrow function(箭头函数)
    举例:
      (x) => x + 6

      相当于


      function(x){
      return x + 6;
      }

    实现过程

    CSS

    画板.class

    class canvasClass {
        constructor (id,text,cover,coverType,width,height,drawPercentCallback) {
            this.conId = id; /*canvasID */
            this.conNode = document.getElementById(this.conId);
            this.ctx = this.conNode.getContext('2d');
            this.coverText = text;
            this.cover = cover; /**图层颜色或图片 */
            this.coverType = coverType; /**图层类型(image/color) */
            this.width = width;
            this.height = height;
            this.drawPercentCallback = drawPercentCallback
            this.clientRect = null;
            this.isMouseDown = false;
        }
        /**
         * 绘制canvas
         */
        fillCanvas () {
            this.conNode.setAttribute('width', this.width);
            this.conNode.setAttribute('height', this.height);
            if (this.coverType == 'color') {
                this.ctx.save();
                this.ctx.fillStyle = this.cover;
                this.ctx.fillRect(0, 0, this.width, this.height);
                this.ctx.restore();
                this.ctx.save();
                var fontSize = 30;
                this.ctx.font = '30px Arial';
                this.ctx.textAlign = 'center';
                this.ctx.fillStyle = '#fff';
                this.ctx.fillText(this.coverText, this.width/2, this.height/2+fontSize/2);
                this.ctx.restore();
                this.ctx.globalCompositeOperation = 'destination-out';
            } else if (this.coverType == 'image') {
                var image = new Image(this.width, this.height)
                image.onload = () => {
                    this.ctx.drawImage(image, 0, 0, this.width, this.height);
                }
                image.src = this.cover;
            }
            this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null
        }
        /**
         * 事件监听
         */
        bindEvent () {
            /**移动端检测 */
            var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
            var clickEvt = device ? 'touchstart' : 'mousedown';
            var moveEvt = device ? 'touchmove' : 'mousemove';
            var x1,y1,x2,y2;
            
            if (!device) {
                document.addEventListener('mouseup', (e) => {
                    this.isMouseDown = false;
                })
            } else {
                document.addEventListener("touchmove", (e) => {
                    if (this.isMouseDown) {
                        e.preventDefault();
                    }
                })
                document.addEventListener("touchend", (e) => {
                    this.isMouseDown = false;
                })
            }
            /**添加监听 */
            this.conNode.addEventListener(clickEvt, (e) => {
                this.isMouseDown = true;
                x1 = device ? e.touches[0].offsetX : e.offsetX;
                y1 = device ? e.touches[0].offsetY : e.offsetY;
                this.drawPoint(x1, y1)
            })
            this.conNode.addEventListener(moveEvt, (e) => {
                if (!device && !this.isMouseDown) {
                    return false;
                }
                this.isMouseDown = true;
                x2 = device ? e.touches[0].offsetX : e.offsetX;
                y2 = device ? e.touches[0].offsetY : e.offsetY;
                this.drawPoint(x1, y1, x2, y2)
                // console.log(x1,x2,y1,y2)
                x1 = x2
                y1 = y2
                // [x1, y1] = [x2, y2]
            })
        }
        /**
         * 抹去, 返回百分比
         */
        drawPoint (x1, y1, x2, y2) {
            var bar = 20; // 半径
            this.ctx.beginPath();
            if (x2) {
                /**
                 * 优化绘制路径
                 */
                var asin = bar*Math.sin(Math.atan((y2-y1)/(x2-x1)));
                var acos = bar*Math.cos(Math.atan((y2-y1)/(x2-x1)))
                var x3 = x1+asin;
                var y3 = y1-acos;
                var x4 = x1-asin;
                var y4 = y1+acos;
                var x5 = x2+asin;
                var y5 = y2-acos;
                var x6 = x2-asin;
                var y6 = y2+acos;
                this.ctx.save();
                this.ctx.beginPath();
                this.ctx.moveTo(x3,y3);
                this.ctx.lineTo(x5,y5);
                this.ctx.lineTo(x6,y6);
                this.ctx.lineTo(x4,y4);
                this.ctx.closePath();
                this.ctx.clip();
                this.ctx.clearRect(0,0,this.width,this.height);
                this.ctx.restore();
                this.ctx.arc(x2, y2, bar, 0, Math.PI*2, true);
            } else {
                this.ctx.arc(x1, y1, bar, 0, Math.PI*2, true);
            }
            this.ctx.fill();
            if (this.drawPercentCallback) {
                this.drawPercentCallback(this.getTransparentPercent());
            }
        }
    
        getTransparentPercent () {
            var imgData = this.ctx.getImageData(0, 0, this.width, this.height),
                pixles = imgData.data,
                transPixs = [];
            for (var i = 0, j = pixles.length; i < j; i += 4) {
                var a = pixles[i + 3];
                if (a < 128) {
                    transPixs.push(i);
                }
            }
            return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
        }
    
    }
    class canvasClass

      1、绘制canvas画布

      2、添加事件监听 

      3、刮奖效果

         构造函数省略...

      1、绘制canvas画布

        fillCanvas () {
            this.conNode.setAttribute('width', this.width);
            this.conNode.setAttribute('height', this.height);
            if (this.coverType == 'color') {
                this.ctx.save();
                this.ctx.fillStyle = this.cover;
                this.ctx.fillRect(0, 0, this.width, this.height);
                this.ctx.restore();
                this.ctx.save();
                var fontSize = 30;
                this.ctx.font = '30px Arial';
                this.ctx.textAlign = 'center';
                this.ctx.fillStyle = '#fff';
                this.ctx.fillText(this.coverText, this.width/2, this.height/2+fontSize/2);
                this.ctx.restore();
                this.ctx.globalCompositeOperation = 'destination-out';
            } else if (this.coverType == 'image') {
                var image = new Image(this.width, this.height)
                image.onload = () => {
                    this.ctx.drawImage(image, 0, 0, this.width, this.height);
                }
                image.src = this.cover;
            }
            this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null
        }

      2、添加事件监听

     bindEvent () {
            /**移动端检测 */
            var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
            var clickEvt = device ? 'touchstart' : 'mousedown';
            var moveEvt = device ? 'touchmove' : 'mousemove';
            var x1,y1,x2,y2;
            
            if (!device) {
                document.addEventListener('mouseup', (e) => {
                    this.isMouseDown = false;
                })
            } else {
                document.addEventListener("touchmove", (e) => {
                    if (this.isMouseDown) {
                        e.preventDefault();
                    }
                })
                document.addEventListener("touchend", (e) => {
                    this.isMouseDown = false;
                })
            }
            /**添加监听 */
            this.conNode.addEventListener(clickEvt, (e) => {
                this.isMouseDown = true;
                x1 = device ? e.touches[0].offsetX : e.offsetX;
                y1 = device ? e.touches[0].offsetY : e.offsetY;
                this.drawPoint(x1, y1)
            })
            this.conNode.addEventListener(moveEvt, (e) => {
                if (!device && !this.isMouseDown) {
                    return false;
                }
                this.isMouseDown = true;
                x2 = device ? e.touches[0].offsetX : e.offsetX;
                y2 = device ? e.touches[0].offsetY : e.offsetY;
                this.drawPoint(x1, y1, x2, y2)
                // console.log(x1,x2,y1,y2)
                x1 = x2
                y1 = y2
                // [x1, y1] = [x2, y2]
            })
        }

      3、刮奖效果

        drawPoint (x1, y1, x2, y2) {
            var bar = 20; // 半径
            this.ctx.beginPath();
            if (x2) {
                /**
                 * 优化绘制路径
                 */
                var asin = bar*Math.sin(Math.atan((y2-y1)/(x2-x1)));
                var acos = bar*Math.cos(Math.atan((y2-y1)/(x2-x1)))
                var x3 = x1+asin;
                var y3 = y1-acos;
                var x4 = x1-asin;
                var y4 = y1+acos;
                var x5 = x2+asin;
                var y5 = y2-acos;
                var x6 = x2-asin;
                var y6 = y2+acos;
                this.ctx.save();
                this.ctx.beginPath();
                this.ctx.moveTo(x3,y3);
                this.ctx.lineTo(x5,y5);
                this.ctx.lineTo(x6,y6);
                this.ctx.lineTo(x4,y4);
                this.ctx.closePath();
                this.ctx.clip();
                this.ctx.clearRect(0,0,this.width,this.height);
                this.ctx.restore();
                this.ctx.arc(x2, y2, bar, 0, Math.PI*2, true);
            } else {
                this.ctx.arc(x1, y1, bar, 0, Math.PI*2, true);
            }
            this.ctx.fill();
            if (this.drawPercentCallback) {
                this.drawPercentCallback(this.getTransparentPercent());
            }
        }

    初始化canvas.class画布

    function canvasInit(json) {
        var arr = []
        for (let item in json) {
            arr.push(json[item])
        }
        this.init = new canvasClass(...arr)
        this.init.fillCanvas()
        this.init.bindEvent()
    
        var btn = document.querySelector('#freshBtn');
        btn.addEventListener('click', (e) => {
            this.init.fillCanvas()
        });
    
    }

    按钮

            #freshBtn{
                margin-left: 660px;
                user-select: none;
                background: #ddd;
                 80px;
                height: 40px;
                text-align: center;
                line-height: 40px;
            }

    刮奖区域

            .box{
                margin: 80px;
                position: relative;
                 300px;
                height: 180px;
                left: 460px;
            }

    DOM

    设置文档内容和显示文本

        <div class="box">
            <div class="bk">
                一等奖
            </div>
            <canvas id="canvas"></canvas>
        </div>
        <div id="freshBtn">重置</div>

      模拟抽奖效果时bk中文字可以用随机

    给canvas.class画布传参

    <script>
        var canvas = new canvasInit({
            id: 'canvas',
            text: '刮开抽奖',
            cover: '#1f1f1f',
            coverType: 'color',
             300,
            height: 180,
            drawPercentCallback: (num) => {
                if(num > 30) {
                    alert('恭喜获得一等奖')
                    canvas.fresh() // 重置
                }
            }
        })
    </script>

     

    (如需转载学习,请标明出处)
  • 相关阅读:
    高程第五章(引用类型)
    第四章(变量、作用域、内存问题)
    label语句和break continue的使用(高程第三章)
    高级程序设计第三章
    max取得数组的最大值
    使用bind()扩充作用域
    函数
    数据类型、字符编码、文件处理
    Python入门
    8.8每日作业系列之循环模块运用
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/9418340.html
Copyright © 2020-2023  润新知