• canvas刮刮卡


    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <title> - jsFiddle demo by artwl</title>
    </head>
    <body>
        <!-- 
            Author  : Yaodongxin
            Date     : 2016-08-31
            Tips      : 如果蒙层是图片需要放到服务前环境测试
         -->
        <button id="freshBtn">刷新</button><label>已刮开 <span id="drawPercent">0%</span> 区域。</label>
        <div style="position:relative" id = "card"></div>
        <script type='text/javascript'>
            var Card = function(options){
                this.id = options.id;
                this.width = options.width;//如果底层图层是图片,这个值会更新成图片尺寸
                this.height = options.height;//如果底层图层是图片,这个值会更新成图片尺寸
                this.wrap = null;//包裹canvas的对象
                this.mask = null;//蒙层canvas对象
                this.bacCtx = null; //context 对象
                this.maskCtx = null; //context 对象
                this.backType = options.backType || 'text'; // 'image' || 'text'
                this.backImg = options.backImg; //刮开后的图层
                this.texts = options.texts;//文字串码
                this.fontSize = options.fontSize || 36;//文字串码字体大小
                this.maskType = options.maskType || 'color';// 'color' || 'image'
                this.maskImg = options.maskImg;
                this.maskColor = options.maskColor || '#ccc';
                this.callback = options.callback || false; //是否执行刮开百分比函数 boollean类型
                this.percentDom = options.percentDom || document.getElementById('drawPercent');
            }
            Card.prototype = {
                init : function(){
                    this.percentDom.innerHTML = '0%';
                    this.draw();
                },
                draw : function(){
                    this.wrap = document.getElementById(this.id);
                    this.drawMask();
                },
                // 画底层内容
                drawCard : function(){
                    var _this = this;
                    _this.resizeCanvas(_this.card, _this.width, _this.height);
                    _this.bacCtx = _this.card.getContext('2d');
                    if(_this.backType == 'image'){
                        if(!_this.backImg){
                            console.error('A back image url is need.');
                        }else{
                            var image = new Image();
                            image.src = _this.backImg;
                            image.onload = function(){
                                _this.width = this.width;
                                _this.height = this.height;
                                _this.resizeCanvas(_this.card, this.width, this.height);
                                _this.bacCtx.drawImage(this, 0, 0); //绘背景图
                            }
                            image.error = function(){
                                console.error('image load failed. Check your url or network.');
                            }
                        }
                    }else{
                        _this.texts = _this.texts || getRandomStr(6);
                        _this.bacCtx.font = 'Bold ' + _this.fontSize + 'px "microsoft yahei"';
                        _this.bacCtx.fillStyle = '#ff6600';
                        _this.bacCtx.textAlign = 'center';
                        _this.bacCtx.textBaseline = 'middle';
                        _this.bacCtx.fillText(_this.texts, _this.width/2, _this.height/2);
                    }
                },
    
                // 绘制蒙层
                drawMask : function(){
                    var _this = this;
                    // _this.wrap.innerHTML = ''
                    if(_this.wrap.innerHTML == ''){
                        _this.mask = document.createElement('canvas');
                        _this.wrap.appendChild(_this.mask);
                        _this.mask.setAttribute('style','position:absolute;left:0;top:0;');
                        _this.card = document.createElement('canvas');
                        _this.wrap.appendChild(_this.card);
                        this.bindEvents();
                    }
                    _this.resizeCanvas(_this.mask, _this.width, _this.height);
                    _this.maskCtx = _this.mask.getContext('2d');
                    if(_this.maskType == 'image'){
                        if(!_this.maskImg){
                            console.error('A mask image url is need.');
                        }else{
                            var image = new Image();
                            image.src = _this.maskImg;
                            image.onload = function(){
                                _this.maskCtx.drawImage(this, 0, 0); //绘蒙层
                                _this.drawCard();//绘制随机码
                            }
                            image.error = function(){
                                console.error('image load failed. Check your url or network.');
                            }
                        }
                    }else{
                        _this.maskCtx.fillStyle = this.maskColor;
                        _this.maskCtx.fillRect(0, 0, _this.width, _this.height);
                        _this.drawCard();//绘制随机码
                    }
                    _this.clientRect = _this.wrap ? _this.wrap.getBoundingClientRect() : null;
                },
    
                // 绘制擦除圆
                drawPoint : function(x, y){
                    this.maskCtx.globalCompositeOperation = 'destination-out';
                    this.maskCtx.beginPath();
                    // var radgrad = this.maskCtx.createRadialGradient(x, y, 0, x, y, 30);
                    // radgrad.addColorStop(0, 'rgba(0, 0, 0, 1)');
                    // radgrad.addColorStop(1, 'rgba(0, 0, 0, 1)');
                    radgrad = '#fff';
                    this.maskCtx.fillStyle = radgrad;
                    this.maskCtx.arc(x, y, 30, 0, Math.PI * 2, true);
                    this.maskCtx.fill();
                },
    
                //绑定事件
                bindEvents : function(){
                    var _this = this,
                        device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())),
                        clickEvtName = device ? 'touchstart' : 'mousedown',
                        moveEvtName = device? 'touchmove': 'mousemove',
                        isMouseDown = false,
                        start ={x:0, y:0},
                        end = {x:0, y:0};
                    if (!device) {//pc
                        isMouseDown = false;
                        document.addEventListener('mouseup', function(e) {
                            isMouseDown = false;
                            start ={x:0, y:0};
                            end = {x:0, y:0};
                        }, false);
                        document.addEventListener('mouseout', function(e) {
                            isMouseDown = false;
                            start ={x:0, y:0};
                            end = {x:0, y:0};
                        }, false);
                    }else{//mobile
                        document.addEventListener('touchmove', function(e) {
                            if (isMouseDown) {
                                e.preventDefault();
                            }
                        }, false);
                        document.addEventListener('touchend', function(e) {
                            isMouseDown = false;
                            start ={x:0, y:0};
                            end = {x:0, y:0};
                        }, false);
                    }
                    // 绑定擦除事件
                    var docEle = document.documentElement || document.body;
                    _this.mask.addEventListener(clickEvtName, function(e){
                        // console.log(device)
                        start ={x:0, y:0};
                        end = {x:0, y:0};
                        isMouseDown = true;
                        var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;
                        var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;
                        _this.drawPoint(x, y);
                    }, false);
                    _this.mask.addEventListener(moveEvtName, function(e){
                        if (!isMouseDown) {
                            return false;
                        }
                        isMouseDown = true;
                        var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;
                        var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;
                        if(start.x!=0){
                            end.x = start.x;
                            end.y = start.y;
                        }
                        start.x = x;
                        start.y = y;
                        _this.drawPoint(x, y);
                        if(end.x!=0){
                            _this.addDraw(start, end);
                        }
                        if(_this.callback){
                            var percent = _this.drawPercent(_this.maskCtx);
                            _this.percentDom.innerHTML = percent + '%';
                        }
                    }, false);
                },
    
                /**
                 * 这个函数是用来补充move的时候中间的空白
                 * @param {object} start 形式{x:10,y:10}的对象,画线开始坐标
                 * @param {object} end   形式{x:20,y:20}的对象,画线结束坐标
                 */
                addDraw : function(start, end){
                    var _this = this;
                    _this.maskCtx.lineWidth = 60;
                    _this.maskCtx.lineStyle = '#f00';
                    _this.maskCtx.beginPath();
                    _this.maskCtx.moveTo(start.x, start.y);
                    _this.maskCtx.lineTo(end.x, end.y);
                    _this.maskCtx.stroke();
                },
                
                /**
                 * 重置canvas的宽高
                 * @param  {object} canvas canvas对象
                 * @param {number} w canvas宽
                 * @param {number} h canvas高
                 */
                resizeCanvas : function(canvas, w, h){
                    canvas.width = w;
                    canvas.height = h;
                },
    
                /**
                 *  计算刮开的百分比
                 * @param  {object} ctx context2d对象
                 * @return {number}     刮开图层所占百分比
                 */
                drawPercent : function(ctx){
                    var imgData = ctx.getImageData(0, 0, this.width, this.height),
                        pixles = imgData.data,
                        transPixs = [],
                        len = pixles.length;
                    for(var i = 0; i<len; i+=4){
                        if(pixles[i+3] == 0){
                            transPixs.push(pixles[i+3]);
                        }
                    }
                    return (transPixs.length/(len/4)*100).toFixed(2);
                }
            }
    
            /**
             * 生成随机串码
             * @param  {number} len 生成随机串码的长度
             * @return {string}     生成的串码
             */
            function getRandomStr(len) {
                var text = '';
                var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
                for( var i=0; i < len; i++ )
                    text += possible.charAt(Math.floor(Math.random() * possible.length));
                return text;
            }
    
            window.onload = function(){
                var card = new Card({
                    id : 'card',
                    backType : 'text',
                    width : '325',
                    height : '174'
                });
                card.init();
    
                // 刷新
                document.getElementById('freshBtn').addEventListener('click', function(){
                    card.init();
                }, false);
            }
        </script>
    </body>
    </html>

    demo:预览地址

  • 相关阅读:
    curl 抓取图片
    checkbox 全选
    大文件断点上传 js+php
    php快速排序
    直接插入排序(Straight Insertion Sort)
    选择排序 Selection sort
    57.猴子吃桃问题
    56.一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
    55.输入两个正整数m和n,求其最大公约数和最小公倍数
    54.将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5
  • 原文地址:https://www.cnblogs.com/youzhuxiaoyao/p/6861625.html
Copyright © 2020-2023  润新知