刮一刮效果
2017-02-23 17:47:13 0 举报
AI智能生成
新版思维导图是一种创新的思维工具,它以直观、清晰的图形化方式展示信息,帮助用户更好地理解和记忆复杂的知识结构。新版思维导图采用先进的算法和设计,使得节点和分支可以自由移动和调整,更加灵活地适应用户的需求。同时,它还支持多种颜色、形状和样式的自定义,使得每个思维导图都能反映出用户独特的思维方式。此外,新版思维导图还具有强大的协作功能,用户可以与他人共享和编辑思维导图,实现知识的共享和创新。总的来说,新版思维导图是一种高效、便捷的思维工具,能够帮助用户提升思维能力,提高工作和学习效率。
作者其他创作
大纲/内容
功能
1、定义一个Lotty的类和所需的变量
2、需要在原型链上面创建容器,两个canvas容器,并获取2d上下文内容
3、绘制第一个canvas,两种类型image/text/html,如果是图片直接用canvas的drawImage就可以了,如果是string,要先用白色填充,然后在上下左右居中的地方绘制字符串,
4、绘制第二个canvas,通3一样两种类型,并且需要重点处理如何把鼠标点击区域变成透明的呢?答案在这里:https://developer.mozilla.org/en/docs/Web/Guide/HTML/Canvas_tutorial/Compositing
即我们要把 maskCtx的 globalCompositeOperation 设置为 destination-out ,详细的用法请参考上面给出的链接。 这里resizeCanvas是改变canvas大小的工具方法。
5、绑定事件
绘制完成后,要给第二个canvas绑定事件。这里分了移动设备和PC-WEB两处情况。移动设备是 touchstart 和 touchmove 事件,对应的PC-WEB是keydown 和 mousemove事件,另外PC-WEB方式下,要给document绑定一个mouseup事件,用来判断鼠标是否按下
6、绘制点击和涂抹区域 这里用到了canvas的径向渐变,在鼠标从标处绘制一个圆形,
7、涂抹区域百分比
在很多时候,我们还需要知道用户涂抹了多少然后进行下一步交互,如当用户涂抹了80%后,才允许下一张显示。
这个百分比如何计算呢?其实很简单,我们可以用getImageData方法到画布上指定矩形的像素数据,由于每个像素都是用rgba表示的,而涂抹过的区域是透明的,所以我们只需要判断alpha通道的值就可以知道是否透明。
8、调用入口init
最后再提供一个入口用来进行绘制和重置
需要扩建功能
1、canvas的类型支持HTML格式
2、百分比大于60,涂层全部清除
3、--
高效的组织结构图
概念图
支持移动端
源码js
/***
*1、
*id:刮奖容器的id
cover:涂层内容,可以为图片地址或颜色值,可空,默认为 #ccc
coverType:涂层类型,值为 image 或 color,可空,默认为 color
width:刮奖区域宽度,默认为300px,可空
height:刮奖区域高度,默认为100px,可空
drawPercentCallback:刮开的区域百分比回调,可空
然后还定义了几个需要用到的变量:
background:第一个canvas元素
backCtx:background元素的2d上下文(context)
mask:第二个canvas元素
maskCtx:mask元素的2d上下文(context)
lottery:刮开后显示的内容,可以为图片地址或字符串
lotteryType:刮开后显示的内容类型,值为 image 或 text,要跟lottery匹配
clientRect:用于记录mask元素的 getBoundingClientRect() 值
*
* ***/
function Lottery(id, cover, coverType, width, height, drawPercentCallback) {
this.conId = id;
this.conNode = document.getElementById(this.conId);
this.cover = cover;
this.coverType = coverType;
this.background = null;
this.backCtx = null;
this.mask = null;
this.maskCtx = null;
this.lottery = null;
this.lotteryType = 'image';
this.width = width || 300;
this.height = height || 100;
this.clientRect = null;
this.drawPercentCallback = drawPercentCallback;
this.htmlObj = null;
}
Lottery.prototype = {
setHtmlObj: function (obj){
this.htmlObj = obj;
},
createElement: function (tagName, attributes) {
var ele = document.createElement(tagName);
for (var key in attributes) {
ele.setAttribute(key, attributes[key]);
}
return ele;
},
cleanMask: function (){
this.maskCtx.clearRect(0, 0, this.width, this.height);
},
/**
* (7)涂抹区域百分比
* 在很多时候,我们还需要知道用户涂抹了多少然后进行下一步交互,如当用户涂抹了80%后,才允许下一张显示。
这个百分比如何计算呢?其实很简单,我们可以用getImageData方法到画布上指定矩形的像素数据,由于每个像素都是用rgba表示的,而涂抹过的区域是透明的,所以我们只需要判断alpha通道的值就可以知道是否透明。
*
* ***/
getTransparentPercent: function(ctx, width, height) {
var imgData = ctx.getImageData(0, 0, width, height),
pixles = imgData.data,
transPixs = [];
for (var i = 0, j = pixles.length; i < j; i += 4) {
var a = pixles[i + 3];
if (a < 128) {
transPixs.push(i);
}
}
return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
},
resizeCanvas: function (canvas, width, height) {
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').clearRect(0, 0, width, height);
},
/**(6)
* 绘制点击和涂抹区域 这里用到了canvas的径向渐变,在鼠标从标处绘制一个圆形,
* ***/
drawPoint: function (x, y) {
this.maskCtx.beginPath();
var radgrad = this.maskCtx.createRadialGradient(x, y, 0, x, y, 30);
radgrad.addColorStop(0, 'rgba(0,0,0,0.6)');
radgrad.addColorStop(1, 'rgba(255, 255, 255, 0)');
this.maskCtx.fillStyle = radgrad;
this.maskCtx.arc(x, y, 30, 0, Math.PI * 2, true);
this.maskCtx.fill();
if (this.drawPercentCallback) {
this.drawPercentCallback.call(null, this.getTransparentPercent(this.maskCtx, this.width, this.height));
}
},
/**(5)
* 绑定事件
* 绘制完成后,要给第二个canvas绑定事件。这里分了移动设备和PC-WEB两处情况。移动设备是 touchstart 和 touchmove 事件,对应的PC-WEB是keydown 和 mousemove事件,另外PC-WEB方式下,要给document绑定一个mouseup事件,用来判断鼠标是否按下
* **/
bindEvent: function () {
var _this = this;
var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
var clickEvtName = device ? 'touchstart' : 'mousedown';
var moveEvtName = device? 'touchmove': 'mousemove';
if (!device) {
var isMouseDown = false;
document.addEventListener('mouseup', function(e) {
isMouseDown = false;
}, false);
} else {
document.addEventListener("touchmove", function(e) {
if (isMouseDown) {
e.preventDefault();
}
}, false);
document.addEventListener('touchend', function(e) {
isMouseDown = false;
}, false);
}
this.mask.addEventListener(clickEvtName, function (e) {
isMouseDown = true;
var docEle = document.documentElement;
if (!_this.clientRect) {
_this.clientRect = {
left: 0,
top:0
};
}
var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;
var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;
_this.drawPoint(x, y);
}, false);
this.mask.addEventListener(moveEvtName, function (e) {
if (!device && !isMouseDown) {
return false;
}
var docEle = document.documentElement;
if (!_this.clientRect) {
_this.clientRect = {
left: 0,
top:0
};
}
var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;
var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;
_this.drawPoint(x, y);
}, false);
},
// (2)添加二个canvas到刮奖容器,并获取2d上下文 这里用于了createElement工具方法,另外还绑定了事件,后面介绍。
drawLottery: function () {
this.background = this.background || this.createElement('canvas', {
style: 'width:100%;height:auto;margin:0;padding:0;display:block;position:absolute;left:0;top:0; background-clip: padding-box;background-size: 100% 100%;'
});
this.mask = this.mask || this.createElement('canvas', {
style: 'width:100%;height:auto;margin:0;padding:0;display:block;position:absolute;left:0;top:0; background-clip: padding-box;background-size: 100% 100%;'
});
if (!this.conNode.innerHTML.replace(/[\w\W]| /g, '')) {
this.conNode.appendChild(this.background);
this.conNode.appendChild(this.mask);
this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null;
this.bindEvent();
}
this.backCtx = this.backCtx || this.background.getContext('2d');
this.maskCtx = this.maskCtx || this.mask.getContext('2d');
// (3) 绘制第一个canvas 第一个canvas分两种类型,image 和 string,如果是图片直接用canvas的drawImage就可以了,如果是string,要先用白色填充,然后在上下左右居中的地方绘制字符串,
if (this.lotteryType == 'image') {
var image = new Image(),
_this = this;
image.onload = function () {
this.width = 290;
this.height = 173;
_this.width = this.width;
_this.height = this.height;
_this.resizeCanvas(_this.background, this.width, this.height);
_this.backCtx.drawImage(this, 0, 0);
_this.drawMask();
}
image.src = this.lottery;
} else if (this.lotteryType == 'text') {
this.width = this.width;
this.height = this.height;
this.resizeCanvas(this.background, this.width, this.height);
this.backCtx.save();
this.backCtx.fillStyle = '#FFF';
this.backCtx.fillRect(0, 0, this.width, this.height);
this.backCtx.restore();
this.backCtx.save();
var fontSize = 30;
this.backCtx.font = 'Bold ' + fontSize + 'px Arial';
this.backCtx.textAlign = 'center';
this.backCtx.fillStyle = '#F60';
this.backCtx.fillText(this.lottery, this.width / 2, this.height / 2 + fontSize / 2);
this.backCtx.restore();
this.drawMask();
} else if(this.lotteryType == "html"){
this.width = this.width;
this.height = this.height;
this.resizeCanvas(this.background, this.width, this.height);
//画张图 ST
_this = this;
var image1 = new Image();
image1.onload = function () {
this.width = 290;
this.height = 173;
_this.width = this.width;
_this.height = this.height;
_this.resizeCanvas(_this.background, this.width, this.height);
_this.backCtx.drawImage(this, 0, 0);
//1
_this.backCtx.save();
_this.backCtx.fillStyle = '#FFF';
// _this.backCtx.fillRect(0, 0, _this.width, _this.height); //矩形
// _this.backCtx.restore();//返回之前保存过的路径状态和属性
// _this.backCtx.save();//保存当前环境的状态
var fontSize = 21;
_this.backCtx.font = 'Bold ' + fontSize + 'px Arial';
_this.backCtx.textAlign = 'center';
_this.backCtx.fillStyle = "#fb0c0c";
_this.backCtx.fillText(_this.htmlObj.str1, _this.width / 2, 30);
_this.backCtx.font = 'Bold 18px Arial';
_this.backCtx.fillText(_this.htmlObj.str2, _this.width / 2, 80);
_this.backCtx.font = 'Bold 13px Arial';
_this.backCtx.fillText(_this.htmlObj.str3, _this.width / 2 , 120);
_this.backCtx.fillText(_this.htmlObj.str4, _this.width / 2 - 15 , 150);
_this.backCtx.restore();
_this.drawMask();
//2
// _this.drawMask();
}
image1.src = this.htmlObj.img;
//画张图 ENDe
}
},
/**(4)
* 第二个canvas也分 image 或 color 填充两种情况。
这里有一个难点,就是如何把鼠标点击区域变成透明的呢?答案在这里:https://developer.mozilla.org/en/docs/Web/Guide/HTML/Canvas_tutorial/Compositing
即我们要把 maskCtx的 globalCompositeOperation 设置为 destination-out ,详细的用法请参考上面给出的链接。 这里resizeCanvas是改变canvas大小的工具方法。
* */
drawMask: function() {
this.resizeCanvas(this.mask, this.width, this.height);
if (this.coverType == 'color') {
this.maskCtx.fillStyle = this.cover;
this.maskCtx.fillRect(0, 0, this.width, this.height);
this.maskCtx.globalCompositeOperation = 'destination-out';
} else if (this.coverType == 'image'){
var image = new Image(),
_this = this;
image.onload = function () {
_this.maskCtx.drawImage(this, 0, 0);
_this.maskCtx.globalCompositeOperation = 'destination-out';
}
image.src = this.cover;
}
},
/** 8.调用入口init
最后再提供一个入口用来进行绘制和重置,**/
init: function (lottery, lotteryType) {
this.lottery = lottery;
this.lotteryType = lotteryType || 'html';
this.drawLottery();
}
};
// window.onload = function () {
// var lottery = new Lottery('lotteryContainer', '#CCC', 'color', 290, 173, drawPercent);
// lottery.init('http://www.baidu.com/img/bdlogo.gif', 'image');
// // lottery.init('images/btnBg.png', 'image'); //底部照片
//
// document.getElementById('freshBtn').onclick = function() {
// drawPercentNode.innerHTML = '0%';
// lottery.init(getRandomStr(10), 'text');
// }
//
// var drawPercentNode = document.getElementById('drawPercent');
//
// function drawPercent(percent) {
// drawPercentNode.innerHTML = percent + '%';
// // if(percent > 10){
// // lottery.resizeCanvas(drawPercentNode,290,173);
// // }
// }
// }
function getRandomStr(len) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < len; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
js调用 lottery = new Lottery('lotteryContainer', '#CCC', 'color', 290, 173, drawPercent);
// lottery.init('http://www.baidu.com/img/bdlogo.gif', 'image');
lottery.init('images/btnBg2.png', 'image'); //底部照片
//刷新放结果
document.getElementById('gjBtn').onclick = function() {
getlottery();
};
//刮奖百分比
function drawPercent(percent) {
if(percent > 60){
lottery.cleanMask();
}
$("#gjBtn").removeClass("btngray").addClass("btnlight");
$("#modalContent").hide();
}
function getlottery() {
mobile=$("#mobile").val();
var params={
url:"/activity/wechat/lottery",
mobile:mobile,
activityId:activeid
};
$.ajax({
type: "POST",
url: path_api + "/util/httpcomm.do",
data: params,
dataType: 'json',
success: function (result) {
console.log(result);
if (result.status == 70023) {//status== 70023 活动不存在
$("#login").hide();
$("#modal,#modalContent").show();
$("#modalContent .content").html("活动不存在");
} else if (result.status == 70024) {//status==70024 抽检机会为零
$("#login,#freshBtn,#lotteryContainer,#gj").hide();
$("#modal,#modalContent").show();
$("#modalContent .content").html("抽奖次数已用完").show();
$("#gjBtn,#modalContent2").hide();
} else if (result.status == 70025) {//您已中奖
alert(result.msg);
$("#login").hide();
$("#modal,#modalContent").show();
$("#modalContent .content").html("您已中奖");
} else if(result.status == 0){//
var name = result.data.prize.name;
var bingo = result.data.bingo;
var remainLotteryCnt = result.data.remainLotteryCnt;
$("#cs").html( remainLotteryCnt + "次");
$("#login").hide();
$("#lotteryContainer,#gjBtn,#drawPercent").show();
$(".content").hide();
if(bingo == 0){//未中奖
lottery.init("谢谢参与", 'text');
}else if(bingo == 1){//中奖
lottery.setHtmlObj({
str1:"恭喜您中奖了!",
str2:"IMAX电影兑换券!",
str3:"奖品已放入"+ mobile +"账号中,请登录,",
str4:"万达 电影APP- 我的钱包查看使用。",
img:"images/bntbg2.png"
})
lottery.init("恭喜您中奖了", 'html');
}
} else if (result.status == 13010) {//没有登录
$.Confirm({
html: "亲,您尚未登录!只有登录后才能执行此操作!", buttons: {"确定": function () {}}
});
} else if( result.status == 19999){
$.Confirm({
html: "系统繁忙,请稍后再试,谢谢!", buttons: {"确定": function () {}}
});
}
},
error:function (XMLHttpRequest) {
}
});
}
0 条评论
下一页