canvas 之刮刮卡
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./scratch.js"></script> </head> <body> <canvas id="down" width=300 height=100 style="position:absolute;left:10px; top:10px; border:1px solid #333;" ></canvas> <canvas id="up" width=300 height=100 style="position:absolute;left:10px; top:10px; border:1px solid #333"></canvas> <script> var options = { awards:['一等奖','二等奖','三等奖','特等奖','没中奖'], maskColor:"gray", textStyle:{ 'size':'30', 'family':'Arial', 'align':'center', 'color':"orange" }, radius:30 } var scratch = new Scratch(options); scratch.init(); </script> </body> </html>
(function (doc,win){
var Scratch = function(options){
this.options = options;
this.up = doc.querySelector("#up");
this.upCtx = this.up.getContext("2d");
this.down = doc.querySelector("#down")
this.downCtx = this.down.getContext("2d");
this.width = this.up.width;
this.height = this.up.height;
}
Scratch.prototype = {
constructor: Scratch,
init:function(){
this.drawText();
this.drawMask();
this.addEvent();
},
drawText:function(){
var ctx = this.downCtx;
ctx.font = this.options.textStyle.size + "px " + this.options.textStyle.family;
ctx.textAlign = this.options.textStyle.align;
ctx.fillStyle = this.options.textStyle.color;
ctx.textBaseline = "top";
var random = parseInt(Math.random() * this.options.awards.length) || 0;
this.award = this.options.awards[random];
ctx.fillText(this.award,this.width/2,this.height/2 - this.options.textStyle.size/2);
},
drawMask:function(){
var ctx = this.upCtx;
ctx.fillStyle = this.options.maskColor;
ctx.fillRect(0,0,this.width,this.height);
ctx.globalCompositeOperation = 'destination-out';
},
addEvent:function(){
var _this = this;
_this.up.addEventListener('mousedown',function(ev){
_this.up.addEventListener('mousemove',callback1 = function(ev){
var ctx = _this.upCtx;
var x = ev.clientX - _this.up.offsetLeft;
var y = ev.clientY - _this.up.offsetTop;
var radius = _this.options.radius;
ctx.beginPath();
var gradient = ctx.createRadialGradient(x, y, 0, x, y, options.radius);
gradient.addColorStop(0,"rgba(255, 255, 255, 0.3)");
gradient.addColorStop(1,"rgba(255, 255, 255, 0)");
ctx.fillStyle = gradient;
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
if(_this.result() > 0.8){
alert(_this.award);
}
},false)
doc.addEventListener('mouseup',callback2 = function(ev){
_this.up.removeEventListener('mousemove',callback1);
doc.removeEventListener('mouseup',callback2);
},false)
},false)
},
result:function(){
//文字宽度
var textWidth = this.options.textStyle.size * this.award.length;
//文字高度
var textHeight = this.options.textStyle.size;
var transPixel = [];
var imgData = this.upCtx.getImageData(this.width/2-textWidth/2,this.height/2-textHeight/2,textWidth,textHeight);
var pixels = imgData.data;
for(var i = 0; i < pixels.length; i += 4){
var a = pixels[i+3];
if(a < 128){
transPixel.push(a);
}
}
return transPixel.length / (pixels.length/4);
}
};
win.Scratch = Scratch;
})(document,window)
var Scratch = function(options){
this.options = options;
this.up = doc.querySelector("#up");
this.upCtx = this.up.getContext("2d");
this.down = doc.querySelector("#down")
this.downCtx = this.down.getContext("2d");
this.width = this.up.width;
this.height = this.up.height;
}
Scratch.prototype = {
constructor: Scratch,
init:function(){
this.drawText();
this.drawMask();
this.addEvent();
},
drawText:function(){
var ctx = this.downCtx;
ctx.font = this.options.textStyle.size + "px " + this.options.textStyle.family;
ctx.textAlign = this.options.textStyle.align;
ctx.fillStyle = this.options.textStyle.color;
ctx.textBaseline = "top";
var random = parseInt(Math.random() * this.options.awards.length) || 0;
this.award = this.options.awards[random];
ctx.fillText(this.award,this.width/2,this.height/2 - this.options.textStyle.size/2);
},
drawMask:function(){
var ctx = this.upCtx;
ctx.fillStyle = this.options.maskColor;
ctx.fillRect(0,0,this.width,this.height);
ctx.globalCompositeOperation = 'destination-out';
},
addEvent:function(){
var _this = this;
_this.up.addEventListener('mousedown',function(ev){
_this.up.addEventListener('mousemove',callback1 = function(ev){
var ctx = _this.upCtx;
var x = ev.clientX - _this.up.offsetLeft;
var y = ev.clientY - _this.up.offsetTop;
var radius = _this.options.radius;
ctx.beginPath();
var gradient = ctx.createRadialGradient(x, y, 0, x, y, options.radius);
gradient.addColorStop(0,"rgba(255, 255, 255, 0.3)");
gradient.addColorStop(1,"rgba(255, 255, 255, 0)");
ctx.fillStyle = gradient;
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
if(_this.result() > 0.8){
alert(_this.award);
}
},false)
doc.addEventListener('mouseup',callback2 = function(ev){
_this.up.removeEventListener('mousemove',callback1);
doc.removeEventListener('mouseup',callback2);
},false)
},false)
},
result:function(){
//文字宽度
var textWidth = this.options.textStyle.size * this.award.length;
//文字高度
var textHeight = this.options.textStyle.size;
var transPixel = [];
var imgData = this.upCtx.getImageData(this.width/2-textWidth/2,this.height/2-textHeight/2,textWidth,textHeight);
var pixels = imgData.data;
for(var i = 0; i < pixels.length; i += 4){
var a = pixels[i+3];
if(a < 128){
transPixel.push(a);
}
}
return transPixel.length / (pixels.length/4);
}
};
win.Scratch = Scratch;
})(document,window)