This answer is an improvisation on my previous answer at https://stackoverflow.com/a/67155647/3706717
So we have new requirement: delete/clear previous drawings
There are some possible approach here:
- @sinisake in comment suggested to reload the background so that we have fresh canvas with only the background intact (but for some reason, white doodle make the background gone)
- the library must have "delete" or "erase" doodle feature (which it didn't have)
- save each changes of the drawing when user click "save", so that user can "undo" to previous version of the drawing (like git's ```git commit``` and ```git reset``` command), I'll be using this approach in my answer
Ideally, you should use server-side language and persistent storage (e.g.: database). But in this case, to simulate such thing I'll be using javascript's localStorage API https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
Fiddle: https://jsfiddle.net/0da572jy/2/
Here is stack fiddle (modified because browser didn't allow stack fiddle to use localStorage)
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var localStorage1 = {
items: {},
removeItem: function(key) {
window.localStorage1.items[key] = null;
},
getItem: function(key) {
return window.localStorage1.items[key];
},
setItem: function(key, val) {
return window.localStorage1.items[key] = val;
},
}
//window.localStorage = localStorage1;
window.localStorage1 = localStorage1;
CanvasRenderingContext2D.prototype.clear =
CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
if (preserveTransform) {
this.save();
this.setTransform(1, 0, 0, 1, 0, 0);
}
this.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (preserveTransform) {
this.restore();
}
};
$(document).ready(function() {
$("#save").click(function() {
//console.log("save");
var base64Image = $("#target canvas").get(0).toDataURL();
//console.log(base64Image);
$("#outputBase64FormInput").val(base64Image);
$("#outputBase64").html(base64Image);
var savedImageJson = window.localStorage1.getItem("savedImage");
//console.log(savedImageJson);
if(savedImageJson == null || typeof savedImageJson == "undefined") savedImageJson = "[]";
var savedImageArr = JSON.parse(savedImageJson);
savedImageArr.push(base64Image);
window.localStorage1.setItem("savedImage", JSON.stringify(savedImageArr));
$("#numOfSavedHistory").html( savedImageArr.length );
});
$("#clear").click(function() {
//console.log("save");
window.localStorage1.removeItem("savedImage");
$("#numOfSavedHistory").html( 0 );
});
$("#undo").click(function() {
//contextCanvas.clear();
canvas.width = canvas.width;
//console.log("undo");
var savedImageJson = window.localStorage1.getItem("savedImage");
//console.log(savedImageJson);
if(savedImageJson == null || typeof savedImageJson == "undefined") savedImageJson = "[]";
var savedImageArr = JSON.parse(savedImageJson);
savedImageArr.pop();
window.localStorage1.setItem("savedImage", JSON.stringify(savedImageArr));
// draw old picture on canvas
var imageOld = new Image();
imageOld.src = savedImageArr[savedImageArr.length-1];
imageOld.onload = function() {
contextCanvas.drawImage(imageOld, 0, 0);
};
$("#numOfSavedHistory").html( savedImageArr.length );
});
// set background
var urlBackground = 'https://picsum.photos/id/100/500/400';
var imageBackground = new Image();
imageBackground.src = urlBackground;
//imageBackground.crossorigin = "anonymous";
imageBackground.setAttribute('crossorigin', 'anonymous');
$("#target").drawpad();
var canvas = $("#target canvas").get(0);
var contextCanvas = canvas.getContext('2d');
imageBackground.onload = function(){
contextCanvas.drawImage(imageBackground, 0, 0);
$("#clear").trigger("click"); // clear previous drawings when page refreshed
$("#save").trigger("click"); // save the first image (background only)
}
});
<!-- language: lang-css -->
body {background-color:rgb(248, 255, 227)}
#target {
width:500px;
height:400px;
}
<!-- language: lang-html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cnbilgin.github.io/jquery-drawpad/jquery-drawpad.css" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cnbilgin.github.io/jquery-drawpad/jquery-drawpad.js"></script>
</head>
<body>
<button id="undo">Undo</button>
<button id="save">Save</button>
<button id="clear">Clear Saved Picture</button>
<span id="numOfSavedHistory">0</span>
<div id="target" class="drawpad-dashed"></div>
<div id="outputBase64"></div>
</body>
</html>
<!-- end snippet -->
Others have already done an excellent job answering the question but if a simple `clear()` method on the context object would be useful to you (it was to me), this is the implementation I use based on answers here:
CanvasRenderingContext2D.prototype.clear =
CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
if (preserveTransform) {
this.save();
this.setTransform(1, 0, 0, 1, 0, 0);
}
this.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (preserveTransform) {
this.restore();
}
};
Usage:
window.onload = function () {
var canvas = document.getElementById('canvasId');
var context = canvas.getContext('2d');
// do some drawing
context.clear();
// do some more drawing
context.setTransform(-1, 0, 0, 1, 200, 200);
// do some drawing with the new transform
context.clear(true);
// draw more, still using the preserved transform
};