源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
查看: 661|回复: 27

[CSS] HTML5+CSS3实例 :canvas 模拟实现电子彩票刮刮乐代码

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2016-12-30 17:03:08 | 显示全部楼层 |阅读模式
今天给大家带来一个刮刮乐的小例子~基于HTML5 canvas的,非常具有使用价值,有兴趣的可以了解一下。

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

效果图:

2016123016484547.gif

2016123016484547.gif

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

2016123016484648.jpg

2016123016484648.jpg

好了,下面开始原理:

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方法进行设置。

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

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

2016123016484649.jpg

2016123016484649.jpg

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

2016123016484650.png

2016123016484650.png

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

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;  
    }  
};  

源码点击下载:demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

回复

使用道具 举报

1

主题

2万

回帖

321

积分

中级会员

Rank: 3Rank: 3

积分
321
发表于 2022-10-24 07:49:11 | 显示全部楼层
还有什么好东西没
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

115

积分

注册会员

Rank: 2

积分
115
发表于 2022-11-7 14:06:47 | 显示全部楼层
谢谢小Y分享
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

55

积分

注册会员

Rank: 2

积分
55
发表于 2022-12-31 20:18:44 | 显示全部楼层
快更新啊,我擦
回复 支持 反对

使用道具 举报

4

主题

2万

回帖

107

积分

注册会员

Rank: 2

积分
107
发表于 2023-1-9 21:42:40 | 显示全部楼层
怕怕怕怕怕怕怕怕怕怕怕怕怕怕
回复 支持 反对

使用道具 举报

3

主题

2万

回帖

301

积分

中级会员

Rank: 3Rank: 3

积分
301
发表于 2023-2-4 16:34:13 | 显示全部楼层
灌灌灌灌水
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

307

积分

中级会员

Rank: 3Rank: 3

积分
307
发表于 2023-3-18 06:43:56 | 显示全部楼层
还有人在不。。。。。。。。。。啊
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

499

积分

中级会员

Rank: 3Rank: 3

积分
499
发表于 2023-4-10 18:31:19 | 显示全部楼层
女生看了弄丢了卡萨诺的卡洛斯
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-10-4 02:03:18 | 显示全部楼层
好东西可以可以可以可以
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

87

积分

注册会员

Rank: 2

积分
87
发表于 2023-10-20 23:13:08 | 显示全部楼层
看看看看
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2024-11-24 11:44 , Processed in 0.108153 second(s), 29 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表