0

0

HTML5/CSS3专题 canvas 模拟实现电子彩票刮刮乐示例代码(图)

黄舟

黄舟

发布时间:2017-03-10 16:06:49

|

2702人浏览过

|

来源于php中文网

原创

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

效果图:


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


立即学习前端免费学习笔记(深入)”;

好了,下面开始原理:

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

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

很简单把~嘿嘿~

1、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对象进行了简单的封装,设置参数,绘制图形什么的,比较简单,大家可以完善下这个类~

Tome
Tome

先进的AI智能PPT制作工具

下载

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

相关文章

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

9

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

8

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

3

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

17

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 6.8万人学习

HTML+CSS基础与实战
HTML+CSS基础与实战

共132课时 | 9.9万人学习

前端开发(基础+实战项目合集)
前端开发(基础+实战项目合集)

共60课时 | 3.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号