1. 程式人生 > >HTML5 CSS3 誘人的例項 canvas 模擬實現電子彩票刮刮樂

HTML5 CSS3 誘人的例項 canvas 模擬實現電子彩票刮刮樂

               

今天給大家帶來一個刮刮樂的小例子~基於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;            width: 400px;            height: 160px;            margin: 100px auto 0;            background: url(s_title.png) no-repeat 0 0;            background-size: 100% 100%;        }        #front, #back        {            position: absolute;            width: 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 

好了,收工吃飯~