canvas下面有一个div,div中可以显示文字。
基于github中一个项目修改的。http://github.com/websanova/wScratchPad
html
css
.guaguaka{
display: inline-block;
position: relative;
}
js
(function($)
{
$.fn.wScratchPad = function(option, settings)
{
if(typeof option === 'object')
{
settings = option;
}
else if(typeof option == 'string')
{
var values = [];
var elements = this.each(function()
{
var data = $(this).data('_wScratchPad');
if(data)
{
if(option === 'reset') { data.reset(); }
else if(option === 'clear') { data.clear(); }
else if(option === 'enabled') { data.enabled = settings === true; }
else if($.fn.wScratchPad.defaultSettings[option] !== undefined)
{
if(settings !== undefined) { data.settings[option] = settings; }
else { values.push(data.settings[option]); }
}
}
});
if(values.length === 1) { return values[0]; }
if(values.length > 0) { return values; }
else { return elements; }
}
settings = $.extend({}, $.fn.wScratchPad.defaultSettings, settings || {});
return this.each(function()
{
var elem = $(this);
var $settings = jQuery.extend(true, {}, settings);
//test for HTML5 canvas
var test = document.createElement('canvas');
if(!test.getContext)
{
elem.html("Browser does not support HTML5 canvas, please upgrade to a more modern browser.");
return false;
}
var sp = new ScratchPad($settings, elem);
elem.append($('').css({
position:'absolute',
margin:'0',width:'100%',
height:'100%',
'text-align':'center',
'line-height':$settings.height+'px',
'font-size':$settings.height/2 + 'px'
}).html($settings.text));
elem.append(sp.generate());
//get number of pixels of canvas for percent calculations
sp.pixels = sp.canvas.width * sp.canvas.height;
elem.data('_wScratchPad', sp);
sp.init();
});
};
$.fn.wScratchPad.defaultSettings =
{
text : 'none',
width : 483, // set width - best to match image width
height : 340, // set height - best to match image height
image : null, // set image path
image2 : null, // set overlay image path - if set color is not used
color : '#888', // set scratch color - if image2 is not set uses color
overlay : 'none', // set the type of overlay effect 'none', 'lighter' - only used with color
size : 10, // set size of scratcher
realtimePercent : false, // Update scratch percent only on the mouseup/touchend (for better performances on mobile device)
scratchDown : null, // scratchDown callback
scratchUp : null, // scratchUp callback
scratchMove : null, // scratcMove callback
cursor : null // Set path to custom cursor
};
function ScratchPad(settings, elem)
{
this.sp = null;
this.settings = settings;
this.$elem = elem;
this.enabled = true;
this.scratch = false;
this.canvas = null;
this.ctx = null;
return this;
}
ScratchPad.prototype =
{
generate: function()
{
var $this = this;
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
this.sp =
$('')
.css({position: 'relative'})
.append(
$(this.canvas)
.attr('width', this.settings.width + 'px')
.attr('height', this.settings.height + 'px')
)
$(this.canvas)
.mousedown(function(e)
{
if(!$this.enabled) return true;
e.preventDefault();
e.stopPropagation();
//reset canvas offset in case it has moved
$this.canvas_offset = $($this.canvas).offset();
$this.scratch = true;
$this.scratchFunc(e, $this, 'Down');
})
.mousemove(function(e)
{
e.preventDefault();
e.stopPropagation();
if($this.scratch) $this.scratchFunc(e, $this, 'Move');
})
.mouseup(function(e)
{
e.preventDefault();
e.stopPropagation();
//make sure we are in draw mode otherwise this will fire on any mouse up.
if($this.scratch)
{
$this.scratch = false;
$this.scratchFunc(e, $this, 'Up');
}
});
this.bindMobile(this.sp);
return this.sp;
},
bindMobile: function($el)
{
$el.bind('touchstart touchmove touchend touchcancel', function ()
{
var touches = event.changedTouches, first = touches[0], type = "";
switch (event.type)
{
case "touchstart": type = "mousedown"; break;
case "touchmove": type = "mousemove"; break;
case "touchend": type = "mouseup"; break;
default: return;
}
var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null);
first.target.dispatchEvent(simulatedEvent);
event.preventDefault();
});
},
init: function()
{
this.sp.css('width', this.settings.width);
this.sp.css('height', this.settings.height);
this.sp.css('cursor', (this.settings.cursor ? 'url("' + this.settings.cursor + '"), default' : 'default'));
$(this.canvas).css({cursor: (this.settings.cursor ? 'url("' + this.settings.cursor + '"), default' : 'default')});
this.canvas.width = this.settings.width;
this.canvas.height = this.settings.height;
this.pixels = this.canvas.width * this.canvas.height;
if(this.settings.image2)
{
this.drawImage(this.settings.image2);
}
else
{
if(this.settings.overlay != 'none')
{
if(this.settings.image)
{
this.drawImage(this.settings.image);
}
this.ctx.globalCompositeOperation = this.settings.overlay;
}
else
{
this.setBgImage();
}
this.ctx.fillStyle = this.settings.color;
this.ctx.beginPath();
this.ctx.rect(0, 0, this.settings.width, this.settings.height)
this.ctx.fill();
}
},
reset: function()
{
this.ctx.globalCompositeOperation = 'source-over';
this.init();
},
clear: function()
{
this.ctx.clearRect(0, 0, this.settings.width, this.settings.height);
},
setBgImage: function()
{
if(this.settings.image)
{
this.sp.css({backgroundImage: 'url('+this.settings.image+')'});
}
},
drawImage: function(imagePath)
{
var $this = this;
var img = new Image();
img.src = imagePath;
$(img).load(function(){
$this.ctx.drawImage(img, 0, 0);
$this.setBgImage();
})
},
scratchFunc: function(e, $this, event)
{
e.pageX = Math.floor(e.pageX - $this.canvas_offset.left);
e.pageY = Math.floor(e.pageY - $this.canvas_offset.top);
$this['scratch' + event](e, $this);
if(this.settings.realtimePercent || event == "Up") {
if($this.settings['scratch' + event]) $this.settings['scratch' + event].apply($this, [e, $this.scratchPercentage($this)]);
}
},
scratchPercentage: function($this)
{
var hits = 0;
var imageData = $this.ctx.getImageData(0,0,$this.canvas.width,$this.canvas.height)
for(var i=0, ii=imageData.data.length; i