zoukankan      html  css  js  c++  java
  • HTML5 CSS3 诱人的实例 :canvas 模拟实现电子*刮刮乐

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/34089553

    今天给大家带来一个刮刮乐的小例子~基于HTML5 canvas的,有兴趣的可以改成android版本的,或者其他的~

    效果图:


    贴一张我中500w的照片,咋办啊,怎么花呢~


    好了,下面开始原理:

    1、刮奖区域两个Canvas,一个是front , 一个back ,front遮盖住下面的canvas。

    2、canvas默认填充了一个矩形,将下面canvas效果图遮盖,然后监听mouse事件,根据mousemove的x,y坐标,进行擦出front canvas上的矩形区域,然后显示出下面的canvas的效果图。

    很简单把~嘿嘿~


    1、HTML文件内容:

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8">
    
        <script type="text/javascript" src="../../jquery-1.8.3.js"></script>
        <script type="text/javascript" src="canvas2d.js"></script>
    
        <script type="text/javascript" src="GuaGuaLe2.js"></script>
    
        <script type="text/javascript">
    
            $(function ()
            {
                var guaguale = new GuaGuaLe("front", "back");
                guaguale.init({msg: "¥5000000.00"});
            });
        </script>
        <style type="text/css">
    
    
            body
            {
                background: url("s_bd.jpg") repeat 0 0;
            }
    
            .container
            {
                position: relative;
                 400px;
                height: 160px;
                margin: 100px auto 0;
                background: url(s_title.png) no-repeat 0 0;
                background-size: 100% 100%;
            }
    
            #front, #back
            {
                position: absolute;
                 200px;
                left: 50%;
                top: 100%;
                margin-left: -130px;
                height: 80px;
                border-radius: 5px;
                border: 1px solid #444;
            }
    
        </style>
    
    </head>
    <body>
    
    <div class="container">
        <canvas id="back" width="200" height="80"></canvas>
        <canvas id="front" width="200" height="80"></canvas>
    </div>
    
    
    </body>
    </html>



    2、首先我利用了一个以前写的canvas辅助类,留下来今天要用的一些方法:

    /**
     * Created with JetBrains WebStorm.
     * User: zhy
     * Date: 13-12-17
     * Time: 下午9:42
     * To change this template use File | Settings | File Templates.
     */
    
    function Canvas2D($canvas)
    {
        var context = $canvas[0].getContext("2d"),
            width = $canvas[0].width,
            height = $canvas[0].height,
            pageOffset = $canvas.offset();
    
    
        context.font = "24px Verdana, Geneva, sans-serif";
        context.textBaseline = "top";
    
    
        /**
         * 绘制矩形
         * @param start
         * @param end
         * @param isFill
         */
        this.drawRect = function (start, end, isFill)
        {
            var w = end.x - start.x , h = end.y - start.y;
            if (isFill)
            {
                context.fillRect(start.x, start.y, w, h);
            }
            else
            {
                context.strokeRect(start.x, start.y, w, h);
            }
        };
    
        /**
         * 根据书写的文本,得到该文本在canvas上书写的中心位置的左上角坐标
         * @param text
         * @returns {{x: number, y: number}}
         */
        this.caculateTextCenterPos = function (text)
        {
            var metrics = context.measureText(text);
            console.log(metrics);
    //        context.font = fontSize + "px Verdana, Geneva, sans-serif";
            var textWidth = metrics.width;
            var textHeight = parseInt(context.font);
    
            return {
                x: width / 2 - textWidth / 2,
                y: height / 2 - textHeight / 2
            };
        }
        this.width = function ()
        {
            return width;
        }
        this.height = function ()
        {
            return height;
        }
        this.resetOffset = function ()
        {
            pageOffset = $canvas.offset();
        }
        /**
         * 当屏幕大小发生变化,重新计算offset
         */
        $(window).resize(function ()
        {
            pageOffset = $canvas.offset();
        });
    
        /**
         * 将页面上的左边转化为canvas中的坐标
         * @param pageX
         * @param pageY
         * @returns {{x: number, y: number}}
         */
        this.getCanvasPoint = function (pageX, pageY)
        {
            return{
                x: pageX - pageOffset.left,
                y: pageY - pageOffset.top
            }
        }
        /**
         * 清除区域,此用户鼠标擦出刮奖涂层
         * @param start
         * @returns {*}
         */
        this.clearRect = function (start)
        {
            context.clearRect(start.x, start.y, 10, 10);
            return this;
        };
    
        /**
         *将文本绘制到canvas的中间
         * @param text
         * @param fill
         */
        this.drawTextInCenter = function (text, fill)
        {
            var point = this.caculateTextCenterPos(text);
            if (fill)
            {
                context.fillText(text, point.x, point.y);
            }
            else
            {
                context.strokeText(text, point.x, point.y);
            }
        };
        /**
         * 设置画笔宽度
         * @param newWidth
         * @returns {*}
         */
        this.penWidth = function (newWidth)
        {
            if (arguments.length)
            {
                context.lineWidth = newWidth;
                return this;
            }
            return context.lineWidth;
        };
    
        /**
         * 设置画笔颜色
         * @param newColor
         * @returns {*}
         */
        this.penColor = function (newColor)
        {
            if (arguments.length)
            {
                context.strokeStyle = newColor;
                context.fillStyle = newColor;
                return this;
            }
    
            return context.strokeStyle;
        };
    
        /**
         * 设置字体大小
         * @param fontSize
         * @returns {*}
         */
        this.fontSize = function (fontSize)
        {
            if (arguments.length)
            {
                context.font = fontSize + "px Verdana, Geneva, sans-serif";
    
                return this;
            }
    
            return context.fontSize;
        }
    
    
    }

    这个类也就对Canvas对象进行了简单的封装,设置参数,绘制图形什么的,比较简单,大家可以完善下这个类~

    3、GuaGuaLe.js

    /**
     * Created with JetBrains WebStorm.
     * User: zhy
     * Date: 14-6-24
     * Time: 上午11:36
     * To change this template use File | Settings | File Templates.
     */
    function GuaGuaLe(idFront, idBack)
    {
        this.$eleBack = $("#" + idBack);
        this.$eleFront = $("#" + idFront);
        this.frontCanvas = new Canvas2D(this.$eleFront);
        this.backCanvas = new Canvas2D(this.$eleBack);
    
        this.isStart = false;
    
    }
    
    GuaGuaLe.prototype = {
        constructor: GuaGuaLe,
        /**
         * 将用户的传入的参数和默认参数做合并
         * @param desAttr
         * @returns {{frontFillColor: string, backFillColor: string, backFontColor: string, backFontSize: number, msg: string}}
         */
        mergeAttr: function (desAttr)
        {
            var defaultAttr = {
                frontFillColor: "silver",
                backFillColor: "gold",
                backFontColor: "red",
                backFontSize: 24,
                msg: "谢谢惠顾"
            };
            for (var p in  desAttr)
            {
                defaultAttr[p] = desAttr[p];
            }
    
            return defaultAttr;
    
        },
    
    
        init: function (desAttr)
        {
    
            var attr = this.mergeAttr(desAttr);
    
            //初始化canvas
            this.backCanvas.penColor(attr.backFillColor);
            this.backCanvas.fontSize(attr.backFontSize);
            this.backCanvas.drawRect({x: 0, y: 0}, {x: this.backCanvas.width(), y: this.backCanvas.height()}, true);
            this.backCanvas.penColor(attr.backFontColor);
            this.backCanvas.drawTextInCenter(attr.msg, true);
            //初始化canvas
            this.frontCanvas.penColor(attr.frontFillColor);
            this.frontCanvas.drawRect({x: 0, y: 0}, {x: this.frontCanvas.width(), y: this.frontCanvas.height()}, true);
    
            var _this = this;
            //设置事件
            this.$eleFront.mousedown(function (event)
            {
                _this.mouseDown(event);
            }).mousemove(function (event)
                {
                    _this.mouseMove(event);
                }).mouseup(function (event)
                {
                    _this.mouseUp(event);
                });
        },
        mouseDown: function (event)
        {
            this.isStart = true;
            this.startPoint = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
        },
        mouseMove: function (event)
        {
            if (!this.isStart)return;
            var p = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
            this.frontCanvas.clearRect(p);
        },
        mouseUp: function (event)
        {
            this.isStart = false;
        }
    };
    

    通过用户传入的两个canvas的id,然后生成一个对象,进行初始化操作,设置事件。当然了也提供用户设置可选的参数,各种颜色,已经刮开后显示的信息等,通过{
                frontFillColor: "silver",
                backFillColor: "gold",
                backFontColor: "red",
                backFontSize: 24,
                msg: "谢谢惠顾"
            };传给init方法进行设置。

    好了,然后就基本完工了,测试一下:

    基本实现了刮开图层,但是存在一个小问题,就是当用户滑动特别快时,会出现一些断点,当然也可以忽略,不过我们准备提供一下解决方案:


    产生原因:由于鼠标移动速度过快,产生的断点;解决方案:将mousemove中两次的鼠标左边,进行拆分成多个断点坐标:



    如上图,把两点之间进行连线,根据斜率,然后分成多个小段,分别获得线段上的坐标(有四种可能,有兴趣可以画画图,计算下,代码如下):

      var k;
            if (p.x > this.startPoint.x)
            {
                k = (p.y - this.startPoint.y) / (p.x - this.startPoint.x);
                for (var i = this.startPoint.x; i < p.x; i += 5)
                {
                    this.frontCanvas.clearRect({x: i, y: (this.startPoint.y + (i - this.startPoint.x) * k)});
                }
            } else
            {
                k = (p.y - this.startPoint.y) / (p.x - this.startPoint.x);
                for (var i = this.startPoint.x; i > p.x; i -= 5)
                {
                    this.frontCanvas.clearRect({x: i, y: (this.startPoint.y + ( i - this.startPoint.x  ) * k)});
                }
            }
            this.startPoint = p;

    4、最后贴一下完整的GuaGuaLe.js

    /**
     * Created with JetBrains WebStorm.
     * User: zhy
     * Date: 14-6-24
     * Time: 上午11:36
     * To change this template use File | Settings | File Templates.
     */
    function GuaGuaLe(idFront, idBack)
    {
        this.$eleBack = $("#" + idBack);
        this.$eleFront = $("#" + idFront);
        this.frontCanvas = new Canvas2D(this.$eleFront);
        this.backCanvas = new Canvas2D(this.$eleBack);
    
        this.isStart = false;
    
    }
    
    GuaGuaLe.prototype = {
        constructor: GuaGuaLe,
        /**
         * 将用户的传入的参数和默认参数做合并
         * @param desAttr
         * @returns {{frontFillColor: string, backFillColor: string, backFontColor: string, backFontSize: number, msg: string}}
         */
        mergeAttr: function (desAttr)
        {
            var defaultAttr = {
                frontFillColor: "silver",
                backFillColor: "gold",
                backFontColor: "red",
                backFontSize: 24,
                msg: "谢谢惠顾"
            };
            for (var p in  desAttr)
            {
                defaultAttr[p] = desAttr[p];
            }
    
            return defaultAttr;
    
        },
    
    
        init: function (desAttr)
        {
    
            var attr = this.mergeAttr(desAttr);
    
            //初始化canvas
            this.backCanvas.penColor(attr.backFillColor);
            this.backCanvas.fontSize(attr.backFontSize);
            this.backCanvas.drawRect({x: 0, y: 0}, {x: this.backCanvas.width(), y: this.backCanvas.height()}, true);
            this.backCanvas.penColor(attr.backFontColor);
            this.backCanvas.drawTextInCenter(attr.msg, true);
            //初始化canvas
            this.frontCanvas.penColor(attr.frontFillColor);
            this.frontCanvas.drawRect({x: 0, y: 0}, {x: this.frontCanvas.width(), y: this.frontCanvas.height()}, true);
    
            var _this = this;
            //设置事件
            this.$eleFront.mousedown(function (event)
            {
                _this.mouseDown(event);
            }).mousemove(function (event)
                {
                    _this.mouseMove(event);
                }).mouseup(function (event)
                {
                    _this.mouseUp(event);
                });
        },
        mouseDown: function (event)
        {
            this.isStart = true;
            this.startPoint = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
        },
        mouseMove: function (event)
        {
            if (!this.isStart)return;
            var p = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY);
            this.frontCanvas.clearRect(p);
        },
        mouseUp: function (event)
        {
            this.isStart = false;
        }
    };
    

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/34089553 

    好了,收工吃饭~


    源码点击下载


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    python字典的遍历
    python字典
    python可变对象
    python元组
    python的range()
    python遍历列表
    Kafka的知识总结(18个知识点)
    为什么fastjson字段为null时不输出空字符串?
    oracle建表字段包含关键字注意事项
    spring websocket 使用@SendToUser
  • 原文地址:https://www.cnblogs.com/dingxiaoyue/p/4924930.html
Copyright © 2011-2022 走看看