用Canvas实现刮刮卡功能的研究与实践
早上在给老刘看了之后,老刘问了我一些问题,然后就找了一篇资料让我再看一下。研究过后,我发现原来自己由于对HTML5的特性不甚理解,在设计实现的思路上犯了错误。为了完成任务,更为了满足自己的探索欲望,便结合着文章中的示例与自己的一些想法,重新做了一个刮刮卡的实现,这次的实现还算是令我满意,感觉和淘宝在双十一时使用过的刮刮卡差不多了。
document.querySelector('canvas');
|
得到页面中canvas元素。
|
canvas.getContext('2d');
|
得到绘图的上下文。
|
ctx.fillStyle = 'transparent';
|
设置矩形填充的属性,主要为矩形填充方法服务。
|
ctx.fillRect(0, 0, w, h);
|
根据给定的坐标与大小绘制一个矩形。
|
ctx.globalCompositeOperation = 'destination-out';(关键属性)
|
设置前后绘制的图形组合显示的效果。
|
ctx.getImageData(0, 10, w, h);
|
得到图片中的像素数据。 |
ctx.clearRect(0, 0, w, h);
|
根据给定的“坐标和大小”,以矩形方式擦掉原图层。 |
ctx.beginPath();
|
开始一个新的绘制路径。 |
ctx.arc(x, y, 25, 0, Math.PI * 2);
|
根据给定的“坐标,弧度与半径”绘制一条弧线。 |
ctx.;fill();
|
绘制后填充。
|
- 在后台根据“用户等级、中奖几率以及其他条件”计算出该用户此次抽奖是否可以抽中,并把计算出来的结果传递给前台页面;
- 前台页面再得到了计算结果后,用JS创建一个与计算结果“相符”的“中奖图片”对象;
- 设置Canvas的背景为该“中奖图片”;
- 在Canvas上绘制一个与“中奖图片”同样大小的“灰色覆盖区域”,以遮挡住图片信息;
- 在“灰色覆盖区域”上继续绘制之前,先设置一下图层的叠加方式(设置为:“在已有内容和新图形不重叠的地方,已有内容保留,所有其他内容成为透明。”),用以模拟擦除的效果;
- 在“灰色覆盖区域”上,使用算法绘制一条用以模拟手指的擦除效果的弧线;
- 当用户“擦除”了一定比例的遮挡区域后,就通知用户是否中奖,同时清除所有的“灰色覆盖区域”,让“中奖图片”完整的显示给用户看,以提升可用性。
<jsp:directive.page contentType="text/html; charset=UTF-8" language="java" />
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<jsp:directive.page session="false" />
<c:set var="ctxPath" value="${pageContext.request.contextPath}" /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><meta name="viewport" content="initial-scale=1.0, user-scalable=no" /><style type="text/css">html,body {width: 100%;height: 100%;margin: 0;padding: 0;}body {moz-user-select: none;webkit-user-select: none;}div,select,input,p,ul,li {margin: 0;padding: 0;}body {font-size: 12px;font-family: "宋体";line-height: 2em;}.main {width: 100%;height: 100%;overflow: hidden; hidden;margin: 0;}</style><title>单canvas实现刮刮卡</title></head><body><div id="container" class="main"><canvas/></div></body><script type="text/javascript">(function (bodyStyle) {// 在FF浏览器环境中,通过修改CSS3属性,使子元素中所有的文字都不能选择。bodyStyle.mozUserSelect = 'none';// 在Google浏览器环境中,通过修改CSS3属性,使子元素中所有的文字都不能选择。bodyStyle.webkitUserSelect = 'none';// 得到canvas对象。var canvas = document.querySelector('canvas');var canvasStyle = canvas.style;// 设置canvas的定位方式。canvasStyle.position = 'absolute';// 设置canvas的背景颜色为“透明”。canvasStyle.backgroundColor='transparent';// 构造一个图片对象。var img = new Image();img.src = '${ctxPath}/image/guagua_1canvas.png';// 监听载图片加载事件。img.addEventListener('load', function(e) {var w = img.width,h = img.height;var mousedown = false;// 把canvas的“宽”和“高”设置为图片的宽和高。canvas.width = w;canvas.height = h;// 把canvas移动到屏幕中央。canvas.style.left = ((document.body.clientWidth - w) / 2) + "px";canvas.style.top = ((document.body.clientHeight - h) / 2) + "px";// 把canvas绘布的背景设置为中奖图片。canvas.style.backgroundImage='url('+img.src+')';// 得到绘图的上下文,且绘制一个与中将图片同样大小的透明层。var ctx = canvas.getContext('2d');ctx.fillStyle = 'transparent';ctx.fillRect(0, 0, w, h);// 使用“gray”颜色对canvas画布进行“矩形”填充。ctx.fillStyle = 'gray';ctx.fillRect(0, 0, w, h);// 在已有内容和新图形不重叠的地方,已有内容保留,所有其他内容成为透明。ctx.globalCompositeOperation = 'destination-out';// 处理“鼠标”或“手指”按下时的动作。function eventDown(e){// 通知浏览器不要执行与事件关联的默认动作。e.preventDefault();mousedown = true;}// 处理“鼠标”或“手指”按下后移动时的动作。function eventMove(e){e.preventDefault();if (mousedown) {// 如果存在涉及当前事件的手指的一个列表(这里是指正在移动中的手指)。if (e.changedTouches){// 取得涉及当前事件中众多手指中的最后一个。e = e.changedTouches[e.changedTouches.length - 1];}// 计算当前“鼠标”或“手指”在canvas中的坐标(注意,计算的坐标是canvas里的坐标)。var x = (e.clientX + document.body.scrollLeft || e.pageX) - canvas.offsetLeft || 0,y = (e.clientY + document.body.scrollTop || e.pageY) - canvas.offsetTop || 0;with (ctx) {beginPath();arc(x, y, 25, 0, Math.PI * 2);fill();}}}// 处理“鼠标”或“手指”按下后抬起时的动作。function eventUp(e){e.preventDefault();mousedown = false;// 得到中奖图片的像素数据(像素计算非常耗费CPU和内存,可能会导致浏览器崩溃)。var data = ctx.getImageData(0, 10, w, h).data;// 通过计算每一个像素,得知还有多少“遮挡区域”。for (var i = 0, j = 0; i < data.length; i += 4) {if (data[i] && data[i + 1] && data[i + 2] && data[i + 3]) {j++;}}// 当还只剩下20%的遮挡区域时弹出中奖信息,同时撤掉遮挡区域。if (j <= w * h * 0.35) {alert('恭喜您中了2元现金');ctx.clearRect(0, 0, w, h);}}// 监听“触摸的开始、移动与抬起”事件。canvas.addEventListener('touchstart', eventDown);canvas.addEventListener('touchend', eventUp);canvas.addEventListener('touchmove', eventMove);// 监听“鼠标的开始、移动与抬起”事件。canvas.addEventListener('mousedown', eventDown);canvas.addEventListener('mouseup', eventUp);canvas.addEventListener('mousemove', eventMove);});})(document.body.style);</script></html>
用Canvas实现刮刮卡功能的研究与实践相关推荐
- android仿淘宝刮刮卡功能实现
去年淘宝和天猫的活动搞的有声有色的,其中有一个游戏还是很受大家欢迎的,那就是红包刮刮卡,自己也挺迷的,一刮起来就停不下来,有没有? 最近自己也在学习android入门,正好前些日子在搜索一个功能示例的 ...
- 【Unity3D小功能】Unity3D中实现UI擦除效果、刮刮卡功能
推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦. 一.前言 ...
- HTML5实现类似刮刮卡的功能
HTML5实现类似刮刮卡的功能 有这样一个功能,当我们使用微信公众号,发送图片时......此处省略300字! 注意要点设置: 1.设置用户缩放:user-scalable=no|yes <me ...
- html5 canvas制作刮刮卡
下班后,闲着无事,刚好近期在学习画布相关知识,就写了个刮刮卡的demo练一下手,兼容安卓.IOS哦.高手路过,多多指点! 刮刮卡实现原理: 通过canvas绘制一个图片,用户手指触发屏幕时,刮开当前一 ...
- 刮刮乐html5效果擦除,利用HTML5的画布Canvas实现刮刮卡效果
先给大家展示效果: 你玩过刮刮卡么?一不小心可以中奖的那种.今天我给大家分享一个基于HTML5技术实现的刮刮卡效果,在PC上只需按住鼠标,在手机上你只需按住指头,轻轻刮去图层就可以模拟真实的刮奖效果. ...
- H5活动刮刮卡功能的实现与注意事项
7月清仓活动有个刮刮卡的功能.找到了个很好用的插件,但是有个坑搞了我好久.就是当覆盖层是个图片的时候老显示跨域的问题. 先附上页面线上地址. https://m.shandjj.com/index.p ...
- 前端遮罩层实现_cocos creator--游戏开奖功能组件《刮刮卡》特效实现
一. 需求分析 [1]实现手指触摸刮开效果:[2]优化:判断刮开与否(能否正常看到奖项). 二. 游戏场景可视化编辑 三. 手指触摸刮刮卡动态刮开效果的实现 Mask为反向遮罩节点,必须确保大小和位置 ...
- html5 刮刮乐 源码,HTML5 canvas实现刮刮乐功能
最近比较闲,除了在群里给大家交流交流,就没啥学习重心.看了论坛里的各种帖子,各种问题满天飞,这里我就整理了2个h5 canvas的demo,分享给大家! 使用html5的canvas实现刮刮乐功能 舍 ...
- canvas绘制刮刮卡,超过一定面积显示全图
说明:栗子转自简书,在他的基础上添加了重置和超过一定面积显示全图,仅做学习使用.(推荐7.2的代码) 1.前端时间做的一个项目需要支持多终端,网页版需要使用html5中canvas画布对象对一组数据进 ...
最新文章
- 京东员工因两年一毛钱没涨而离职,618后跳槽涨薪翻倍
- 重磅MIT开源人工智能算法评估和理解对抗Logit配对的稳健性
- shell的嵌入命令大全
- java float x=26f_东软java笔试题
- 【django】配置文件
- 个人创业做什么好?以下这几个值得考虑
- PAT1004 成绩排名【vector sort排序、string的使用】
- mmdnn cannot import caffe
- python 代码格式规范脚本_Python编码规范
- python允许无止境的循环_ParisGabriel:Python无止境 day03
- 带你认识MindSpore量子机器学习库MindQuantum
- php判断访问的当前设备是手机还是电脑
- 面试题简答题——操作系统相关汇总
- python之Excel操作
- 华为机试HJ45:名字的漂亮度
- linux 创建文件夹快捷方式
- 不可能解开的谜题 (程序员修炼之道,评注者序)
- R语言金融基础:tidyquant数据整理(滑窗建模)
- 计算机三位科学家,华南理工大学这三位年轻科学家太优秀了!
- 学习Android studio时的报错Binary XML file line #10: Error inflating class fragment
热门文章
- 将个人java web网站发布至公网#内网穿透#花生壳#手把手教程
- lib/libSciCamera.so: file not recognized: file format not recognized
- java栈和堆的区别_Java中堆和栈的区别
- 『Linux基础 - 2 』操作系统,Linux背景知识和Ubuntu操作系统安装
- 使用Python实现伪防沉迷工具
- Linux基础指令(有图有真相,附实例)
- springboot使用POI读取excel数据
- VB.net或者C#编写按键精灵DLL教程
- 导入HttpPost包
- 绝地求生服务器维护9月19日,绝地求生9.19日无法登录游戏解决方法 绝地求生9月19日登录不了?...