引入jquery和jquery.eraser.js
https://github.com/boblemarin/jQuery.eraser
JS部分:
$(window).load(function () { //这个适用手机端,等图片加载完再显示,因为有可能会出现第一次加载图片没有加载完就不会出现canvas $('#redux').eraser( { size: 50, //设置橡皮擦大小 completeRatio: .6, //设置擦除面积比例 completeFunction: showResetButton //大于擦除面积比例触发函数 }); function showResetButton(){ $(".main_box .show,.main_box .mask").fadeIn(300); $(".show").css("display","flex"); } $(".main_box .mask,.main_box .show .close,.main_box .show .btn,.show").click(function(){ // $(".main_box .show,.main_box .mask").fadeOut(300); // $(".show").css("display","none"); window.location.reload(); }) })
HTML部分
<img id="redux" src="images/mask-img.png" />
/*
* jQuery.eraser v0.4.2
* makes any image or canvas erasable by the user, using touch or mouse input
* https://github.com/boblemarin/jQuery.eraser
*
* Usage:
*
* $('#myImage').eraser(); // simple way
*
* $(#canvas').eraser( {
* size: 20, // define brush size (default value is 40)
* completeRatio: .65, // allows to call function when a erased ratio is reached (between 0 and 1, default is .7 )
* completeFunction: myFunction // callback function when complete ratio is reached
* } );
*
* $('#image').eraser( 'clear' ); // erases all canvas content
*
* $('#image').eraser( 'reset' ); // revert back to original content
*
* $('#image').eraser( 'size', 80 ); // change the eraser size
*
*
* https://github.com/boblemarin/jQuery.eraser
* http://minimal.be/lab/jQuery.eraser/
*
* Copyright (c) 2010 boblemarin emeric@minimal.be http://www.minimal.be
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
(
function(
$ ){
var
methods = {
init
:
function(
options ) {
return
this.
each(
function(){
var
$this =
$(
this),
data =
$this.
data(
'eraser');
if ( !
data ) {
var
width =
$this.
width(),
height =
$this.
height(),
pos =
$this.
offset(),
$canvas =
$(
"<canvas/>"),
canvas =
$canvas.
get(
0),
size = (
options &&
options.
size )?
options.
size:
40,
completeRatio = (
options &&
options.
completeRatio )?
options.
completeRatio:
.7,
completeFunction = (
options &&
options.
completeFunction )?
options.
completeFunction:
null,
parts = [],
colParts =
Math.
floor(
width /
size ),
numParts =
colParts *
Math.
floor(
height /
size ),
n =
numParts,
ctx =
canvas.
getContext(
"2d");
// replace target with canvas
$this.
after(
$canvas );
canvas.
id =
this.
id;
canvas.
className =
this.
className;
canvas.
width =
width;
canvas.
height =
height;
ctx.
drawImage(
this,
0,
0 ,
width ,
height );
$this.
remove();
// prepare context for drawing operations
ctx.
globalCompositeOperation =
"destination-out";
ctx.
strokeStyle =
'rgba(255,0,0,255)';
ctx.
lineWidth =
size;
ctx.
lineCap =
"round";
// bind events
$canvas.
bind(
'mousedown.eraser',
methods.
mouseDown);
$canvas.
bind(
'touchstart.eraser',
methods.
touchStart);
$canvas.
bind(
'touchmove.eraser',
methods.
touchMove);
$canvas.
bind(
'touchend.eraser',
methods.
touchEnd);
// reset parts
while(
n-- )
parts.
push(
1);
// store values
data = {
posX
:
pos.
left,
posY
:
pos.
top,
touchDown
:
false,
touchID
:-
999,
touchX
:
0,
touchY
:
0,
ptouchX
:
0,
ptouchY
:
0,
canvas
:
$canvas,
ctx
:
ctx,
w
:
width,
h
:
height,
source
:
this,
size
:
size,
parts
:
parts,
colParts:
colParts,
numParts:
numParts,
ratio:
0,
complete:
false,
completeRatio:
completeRatio,
completeFunction:
completeFunction
};
$canvas.
data(
'eraser',
data);
// listen for resize event to update offset values
$(
window).
resize(
function() {
var
pos =
$canvas.
offset();
data.
posX =
pos.
left;
data.
posY =
pos.
top;
});
}
});
},
touchStart
:
function(
event ) {
var
$this =
$(
this),
data =
$this.
data(
'eraser');
if ( !
data.
touchDown ) {
var
t =
event.
originalEvent.
changedTouches[
0],
tx =
t.
pageX -
data.
posX,
ty =
t.
pageY -
data.
posY;
methods.
evaluatePoint(
data,
tx,
ty );
data.
touchDown =
true;
data.
touchID =
t.
identifier;
data.
touchX =
tx;
data.
touchY =
ty;
event.
preventDefault();
}
},
touchMove
:
function(
event ) {
var
$this =
$(
this),
data =
$this.
data(
'eraser');
if (
data.
touchDown ) {
var
ta =
event.
originalEvent.
changedTouches,
n =
ta.
length;
while(
n-- )
if (
ta[
n].
identifier ==
data.
touchID ) {
var
tx =
ta[
n].
pageX -
data.
posX,
ty =
ta[
n].
pageY -
data.
posY;
methods.
evaluatePoint(
data,
tx,
ty );
data.
ctx.
beginPath();
data.
ctx.
moveTo(
data.
touchX,
data.
touchY );
data.
touchX =
tx;
data.
touchY =
ty;
data.
ctx.
lineTo(
data.
touchX,
data.
touchY );
data.
ctx.
stroke();
event.
preventDefault();
break;
}
}
},
touchEnd
:
function(
event ) {
var
$this =
$(
this),
data =
$this.
data(
'eraser');
if (
data.
touchDown ) {
var
ta =
event.
originalEvent.
changedTouches,
n =
ta.
length;
while(
n-- )
if (
ta[
n].
identifier ==
data.
touchID ) {
data.
touchDown =
false;
event.
preventDefault();
break;
}
}
},
evaluatePoint
:
function(
data,
tx,
ty ) {
var
p =
Math.
floor(
tx/
data.
size) +
Math.
floor(
ty /
data.
size ) *
data.
colParts;
if (
p >=
0 &&
p <
data.
numParts ) {
data.
ratio +=
data.
parts[
p];
data.
parts[
p] =
0;
if ( !
data.
complete) {
if (
data.
ratio/
data.
numParts >=
data.
completeRatio ) {
data.
complete =
true;
if (
data.
completeFunction !=
null )
data.
completeFunction();
}
}
}
},
mouseDown
:
function(
event ) {
var
$this =
$(
this),
data =
$this.
data(
'eraser'),
tx =
event.
pageX -
data.
posX,
ty =
event.
pageY -
data.
posY;
methods.
evaluatePoint(
data,
tx,
ty );
data.
touchDown =
true;
data.
touchX =
tx;
data.
touchY =
ty;
data.
ctx.
beginPath();
data.
ctx.
moveTo(
data.
touchX-
1,
data.
touchY );
data.
ctx.
lineTo(
data.
touchX,
data.
touchY );
data.
ctx.
stroke();
$this.
bind(
'mousemove.eraser',
methods.
mouseMove);
$(
document).
bind(
'mouseup.eraser',
data,
methods.
mouseUp);
event.
preventDefault();
},
mouseMove
:
function(
event ) {
var
$this =
$(
this),
data =
$this.
data(
'eraser'),
tx =
event.
pageX -
data.
posX,
ty =
event.
pageY -
data.
posY;
methods.
evaluatePoint(
data,
tx,
ty );
data.
ctx.
beginPath();
data.
ctx.
moveTo(
data.
touchX,
data.
touchY );
data.
touchX =
tx;
data.
touchY =
ty;
data.
ctx.
lineTo(
data.
touchX,
data.
touchY );
data.
ctx.
stroke();
event.
preventDefault();
},
mouseUp
:
function(
event ) {
var
data =
event.
data,
$this =
data.
canvas;
data.
touchDown =
false;
$this.
unbind(
'mousemove.eraser');
$(
document).
unbind(
'mouseup.eraser');
event.
preventDefault();
},
clear
:
function() {
var
$this =
$(
this),
data =
$this.
data(
'eraser');
if (
data )
{
data.
ctx.
clearRect(
0,
0,
data.
w,
data.
h );
var
n =
data.
numParts;
while(
n-- )
data.
parts[
n] =
0;
data.
ratio =
data.
numParts;
data.
complete =
true;
if (
data.
completeFunction !=
null )
data.
completeFunction();
}
},
size
:
function(
value) {
var
$this =
$(
this),
data =
$this.
data(
'eraser');
if (
data &&
value )
{
data.
size =
value;
data.
ctx.
lineWidth =
value;
}
},
reset
:
function() {
var
$this =
$(
this),
data =
$this.
data(
'eraser');
if (
data )
{
data.
ctx.
globalCompositeOperation =
"source-over";
data.
ctx.
drawImage(
data.
source,
0,
0 );
data.
ctx.
globalCompositeOperation =
"destination-out";
var
n =
data.
numParts;
while(
n-- )
data.
parts[
n] =
1;
data.
ratio =
0;
data.
complete =
false;
}
}
};
$.
fn.
eraser =
function(
method ) {
if (
methods[
method] ) {
return
methods[
method].
apply(
this,
Array.
prototype.
slice.
call(
arguments,
1 ));
}
else
if (
typeof
method ===
'object' || !
method ) {
return
methods.
init.
apply(
this,
arguments );
}
else {
$.
error(
'Method ' +
method +
' does not yet exist on jQuery.eraser' );
}
};
})(
jQuery );