Skip to content

Commit f152042

Browse files
committed
fix: Clear edge background color when erasing
1 parent fd948d9 commit f152042

File tree

2 files changed

+62
-48
lines changed

2 files changed

+62
-48
lines changed

js/canvas.js

+34-29
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @module CrysyanCanvas
44
* @depend util.js
55
*/
6-
(function($util) {
6+
(function ($util) {
77
'use strict';
88
/**
99
* @class CrysyanCanvas
@@ -50,19 +50,20 @@
5050
// the most length of history 'revokeImgDatas' list
5151
this.historyListLen = ops.historyListLen;
5252
}
53+
5354
CrysyanCanvas.prototype = {
5455
// Save e drawing surface
55-
saveDrawingSurface: function() {
56+
saveDrawingSurface: function () {
5657
this.drawingSurfaceImageData = this.playContext.getImageData(0, 0,
5758
this.playCanvas.width,
5859
this.playCanvas.height);
5960
},
6061
// Restore drawing surface
61-
restoreDrawingSurface: function() {
62+
restoreDrawingSurface: function () {
6263
this.playContext.putImageData(this.drawingSurfaceImageData, 0, 0);
6364
},
6465
// save history ''drawingSurfaceImageData''
65-
saveRevokeImgDatas: function() {
66+
saveRevokeImgDatas: function () {
6667
var drawingSurfaceImageData = this.playContext.getImageData(0, 0, this.playCanvas.width, this.playCanvas.height);
6768
if (this.revokeImgDatas.length >= this.historyListLen) {
6869
// If the length is longer than the maximum length of the configuration
@@ -76,12 +77,12 @@
7677
// clear the array
7778
this.forwardRevokeImgDatas = [];
7879
},
79-
saveForwardRevokeFirstFrame: function() {
80+
saveForwardRevokeFirstFrame: function () {
8081
this.forwardRevokeImgDatas[0] = this.playContext.getImageData(0, 0, this.playCanvas.width, this.playCanvas.height);
8182
},
8283
// Revoke
8384
// if length of list is zero ,return zero
84-
revoke: function() {
85+
revoke: function () {
8586
if (this.revokeImgDatas.length <= 0)
8687
return 0;
8788
var drawingSurfaceImageData = this.revokeImgDatas.pop();
@@ -90,16 +91,20 @@
9091
},
9192
// Forward revoke
9293
// if length of list is zero ,return zero
93-
forwardRevoke: function() {
94+
forwardRevoke: function () {
9495
if (this.forwardRevokeImgDatas.length <= 0)
9596
return 0;
9697
var drawingSurfaceImageData = this.forwardRevokeImgDatas.pop();
9798
this.revokeImgDatas.push(drawingSurfaceImageData);
9899
this.playContext.putImageData(drawingSurfaceImageData, 0, 0);
99100
},
100101
//
101-
clearCanvas: function() {
102+
clearCanvas: function () {
102103
this.playContext.clearRect(0, 0, this.playCanvas.width, this.playCanvas.height);
104+
this.clearCanvasWithOnlyBackGroupImage();
105+
},
106+
//
107+
clearCanvasWithOnlyBackGroupImage: function () {
103108
if (this.backgroudImage.image !== null) {
104109
var image = this.backgroudImage.image;
105110
this.drawImage(image, (this.playCanvas.width - image.width) / 2, (this.playCanvas.height - image.height) / 2, image.width, image.height);
@@ -112,7 +117,7 @@
112117
* @param {number} x e.clientX
113118
* @param {number} y e.clientY
114119
*/
115-
windowToCanvas: function(x, y) {
120+
windowToCanvas: function (x, y) {
116121
var bbox = this.playCanvas.getBoundingClientRect();
117122
return {
118123
x: x - bbox.left,
@@ -128,7 +133,7 @@
128133
* @param {String|File|Image|Blob} obj
129134
* @param mode
130135
*/
131-
drawBackGroupWithImage: function(obj, mode) {
136+
drawBackGroupWithImage: function (obj, mode) {
132137
if (typeof mode === "undefined") {
133138
// image scaling mode
134139
// if mode !=1 ,fulling mode
@@ -150,15 +155,15 @@
150155
if (image.width >= canvas.playCanvas.width && ivwr > ivhr) {
151156
// Beyond the canvas's width
152157
// zoom ratio
153-
canvas.backgroudImage.height = canvas.playCanvas.height * (1 / ivwr).toFixed(2);
158+
image.width = canvas.backgroudImage.width;
159+
image.height = canvas.backgroudImage.height = canvas.playCanvas.height * (1 / ivwr).toFixed(2);
154160
} else if (image.height >= canvas.playCanvas.height && (ivhr > ivwr)) {
155161
// Beyond the canvas's height
156162
// zoom ratio
157-
canvas.backgroudImage.width = canvas.playCanvas.width * (1 / ivhr).toFixed(2);
163+
image.height = canvas.backgroudImage.height;
164+
image.width = canvas.backgroudImage.width = canvas.playCanvas.width * (1 / ivhr).toFixed(2);
158165
}
159-
image.width = canvas.backgroudImage.width;
160-
image.height = canvas.backgroudImage.height;
161-
}else{
166+
} else {
162167
// if the width of image bigger than canvas's,will set to canvas's width
163168
if (image.width >= canvas.backgroudImage.width) {
164169
image.width = canvas.backgroudImage.width;
@@ -171,16 +176,16 @@
171176
canvas.clearCanvas();
172177
};
173178
// image the image object maybe come from parent's window.
174-
if (obj instanceof Image ||(parent&&parent.window&&obj instanceof parent.window.Image)||typeof obj.src!=="undefined") {
179+
if (obj instanceof Image || (parent && parent.window && obj instanceof parent.window.Image) || typeof obj.src !== "undefined") {
175180
image.src = obj.src;
176181
return;
177182
}
178183
// file the File|Blob object maybe come from parent's window.
179184
if (obj instanceof File
180185
|| obj instanceof Blob
181-
||(parent&&parent.window&&(obj instanceof parent.window.File||obj instanceof parent.window.Blob))) {
186+
|| (parent && parent.window && (obj instanceof parent.window.File || obj instanceof parent.window.Blob))) {
182187
var reader = new FileReader();
183-
reader.onload = function(event) {
188+
reader.onload = function (event) {
184189
image.src = event.target.result;
185190
};
186191
reader.readAsDataURL(file);
@@ -205,10 +210,10 @@
205210
* 3、Cut the image and locate the part on the canvas:
206211
* drawImageFile(imagefile,sx,sy,swidth,sheight,x,y,width,height);
207212
*/
208-
drawImageFile: function(file) {
213+
drawImageFile: function (file) {
209214
var canvas = this;
210215
var reader = new FileReader();
211-
reader.onload = function(event) {
216+
reader.onload = function (event) {
212217
canvas.drawDataUrl(event.target.result);
213218
};
214219
reader.readAsDataURL(file);
@@ -218,12 +223,12 @@
218223
*
219224
* @param dataUrl
220225
*/
221-
drawDataUrl: function(dataUrl) {
226+
drawDataUrl: function (dataUrl) {
222227
var ctx = this.playContext;
223228
var image = new Image();
224229
// CORS settings attributes
225230
image.crossOrigin = 'Anonymous';
226-
image.onload = function() {
231+
image.onload = function () {
227232
arguments[0] = image;
228233
ctx.drawImage.apply(ctx, arguments);
229234
};
@@ -241,7 +246,7 @@
241246
* 3、Cut the image and locate the part on the canvas:
242247
* drawImage(image,sx,sy,swidth,sheight,x,y,width,height);
243248
*/
244-
drawImage: function() {
249+
drawImage: function () {
245250
var ctx = this.playContext;
246251
ctx.drawImage.apply(ctx, arguments);
247252
},
@@ -255,7 +260,7 @@
255260
* Other arguments are ignored.
256261
*@return {string}
257262
*/
258-
toDataURL: function(type, encoderOptions) {
263+
toDataURL: function (type, encoderOptions) {
259264
return this.playCanvas.toDataURL(type, encoderOptions);
260265
},
261266

@@ -267,9 +272,9 @@
267272
* @param callback called in image.onload
268273
* @returns {Image} image dom element
269274
*/
270-
toImageEle: function(type, encoderOptions, callback) {
275+
toImageEle: function (type, encoderOptions, callback) {
271276
var image = new Image();
272-
image.onload = function() {
277+
image.onload = function () {
273278
callback();
274279
};
275280
image.src = this.toDataURL(type, encoderOptions);
@@ -280,7 +285,7 @@
280285
* See toDataURL()
281286
* @return {Blob}
282287
*/
283-
toBlob: function(type, encoderOptions) {
288+
toBlob: function (type, encoderOptions) {
284289
//DataURL: 'data:text/plain;base64,YWFhYWFhYQ=='
285290
var arr = this.toDataURL(type, encoderOptions).split(','),
286291
mime = arr[0].match(/:(.*?);/)[1],
@@ -300,7 +305,7 @@
300305
* @deprecated
301306
* @link http://weworkweplay.com/play/saving-html5-canvas-as-image/
302307
*/
303-
saveAsLocalImagePng: function() {
308+
saveAsLocalImagePng: function () {
304309
// here is the most important part because if you don't replace you will get a DOM 18 exception.
305310
var image = this.toDataURL("image/png").replace("image/png", "image/octet-stream;Content-Disposition:attachment;filename=foo.png");
306311
//var image = this.toDataURL("image/png").replace("image/png", "image/octet-stream");
@@ -309,7 +314,7 @@
309314
},
310315

311316
// add event to canvas
312-
addEvent: function(eventType, callback) {
317+
addEvent: function (eventType, callback) {
313318
$util.addEvent(this.playCanvas, eventType, callback);
314319
},
315320
//

js/widget/eraser.js

+28-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(function($widget) {
1+
(function ($widget) {
22
'use strict';
33

44
var ERASER_LINE_WIDTH = 1,
@@ -12,36 +12,28 @@
1212
var eraser = CrysyanEraserWidget;
1313
eraser.eraserWidth = 25;
1414
// eraser.mouseDown = function(e, loc) {};
15-
eraser.mouseMove = function(e, loc) {
15+
eraser.mouseMove = function (e, loc) {
1616
if (!eraser.isDown) return;
1717
var ctx = eraser.crysyanCanvas.playContext;
1818
eraser.eraseLast(ctx);
1919
eraser.drawEraser(loc, ctx);
2020
eraser.prePiont.e = e;
2121
eraser.prePiont.loc = loc;
2222
};
23-
eraser.mouseUp = function(e, loc) {
23+
eraser.mouseUp = function (e, loc) {
2424
var ctx = eraser.crysyanCanvas.playContext;
2525
eraser.eraseLast(ctx);
2626
};
2727
//
28-
eraser.setDrawPathForEraser = function(loc, context) {
28+
eraser.setDrawPathForEraser = function (loc, context) {
2929
context.beginPath();
3030
context.arc(loc.x, loc.y,
3131
eraser.eraserWidth / 2,
3232
0, Math.PI * 2, false);
3333
context.clip();
3434
};
3535
//
36-
eraser.setErasePathForEraser = function(context) {
37-
context.beginPath();
38-
context.arc(eraser.prePiont.loc.x, eraser.prePiont.loc.y,
39-
eraser.eraserWidth / 2 + ERASER_LINE_WIDTH,
40-
0, Math.PI * 2, false);
41-
context.clip();
42-
};
43-
//
44-
eraser.setEraserAttributes = function(context) {
36+
eraser.setEraserAttributes = function (context) {
4537
context.lineWidth = ERASER_LINE_WIDTH;
4638
context.shadowColor = ERASER_SHADOW_STYLE;
4739
context.shadowOffsetX = ERASER_SHADOW_OFFSET;
@@ -50,16 +42,33 @@
5042
context.strokeStyle = ERASER_STROKE_STYLE;
5143
};
5244
//
53-
eraser.eraseLast = function(context) {
54-
var last = eraser.prePiont.loc;
55-
var radio = eraser.eraserWidth / 2 + ERASER_LINE_WIDTH;
45+
eraser.eraseLast = function (context) {
46+
// clear
47+
context.save();
48+
context.beginPath();
49+
context.arc(eraser.prePiont.loc.x, eraser.prePiont.loc.y,
50+
eraser.eraserWidth / 2 + ERASER_LINE_WIDTH,
51+
0, Math.PI * 2, false);
52+
context.globalCompositeOperation="destination-out";
53+
// context.strokeStyle = "rgba(0, 0,0,0)";
54+
// context.fillStyle = "rgb(255, 255, 255)";
55+
// context.stroke();
56+
context.fill();
57+
context.restore();
58+
59+
// draw backgroup Image
5660
context.save();
57-
eraser.setErasePathForEraser(context);
58-
eraser.crysyanCanvas.clearCanvas();
61+
context.beginPath();
62+
// Clear edge background color, so the radius of the circle 1 units bigger than the previous
63+
context.arc(eraser.prePiont.loc.x, eraser.prePiont.loc.y,
64+
eraser.eraserWidth / 2 + ERASER_LINE_WIDTH+1,
65+
0, Math.PI * 2, false);
66+
context.clip();
67+
eraser.crysyanCanvas.clearCanvasWithOnlyBackGroupImage();
5968
context.restore();
6069
};
6170
//
62-
eraser.drawEraser = function(loc, context) {
71+
eraser.drawEraser = function (loc, context) {
6372
context.save();
6473
eraser.setEraserAttributes(context);
6574
eraser.setDrawPathForEraser(loc, context);

0 commit comments

Comments
 (0)