These are the button functions:
$("#undo").click(function() {
Stack1.undo();
});
$("#redo").click(function() {
Stack1.redo();
});
This is the undo function:
function clearCanvas()
{
ctx.clearRect(0,0,canvasWidth,canvasHeight);
}
Stack1 = new Stack();
///////////////////
function Stack(firstImg , size) {
var drawStack = new Array();
var stackIndex = 0;
var stackTop = 0;
var stackFloor = 0;
var stackSize = size;
drawStack[0] = firstImg;
this.add = function() {
drawStack[++stackIndex%stackSize] = canvas.toDataURL("image/png");
if (stackIndex >= stackSize) stackFloor = (stackIndex +1) % stackSize ;
stackTop = stackIndex % stackSize;
}
this.undo = function () {
if (stackIndex%stackSize == stackFloor ) return;
clearCanvas();
var tmpImg = new Image();
tmpImg.src = drawStack[--stackIndex%stackSize];
ctx.drawImage(tmpImg, 0, 0);
}
this.redo = function () {
if (stackIndex%stackSize == stackTop) return;
clearCanvas();
var tmpImg = new Image();
tmpImg.src = drawStack[++stackIndex%stackSize];
ctx.drawImage(tmpImg, 0, 0);
}
}
Also I declare the array at the top:
var drawStack = [];
I also put this code before I draw each stroke in my mouse down method:
Stack1.add();
Here is my working example..draw 3 circles on screen then click undo, everything goes blank, then click it again and only 2 remain. Its close but I cannot figure out the last part.
You've made this more complicated than it needs to be. The pseudo code for how an undo function usually works goes:
currentState = 0
maxStates = 10
stateArray = []
initialize:
push the current state onto the top of stateArray
save:
if there are states in stateArray above the currentState
clear the states in stateArray above the current state
push the current state onto the top of stateArray
currentState++
if the size of stateArray exceeds maxStates
remove the oldest state from the bottom of stateArray
currentState--
undo:
if there are previous states in stateArray
currentState--
revert the canvas to stateArray[currentState]
redo:
if there are newer states in stateArray
currentState++
revert the canvas to stateArray[currentState]
As you can see:
Edit : I noticed a different problem in your code, you are trying to immediately draw the image to the canvas instead of waiting for it to load. At minimum your undo function should look like:
this.undo = function () {
if (stackIndex%stackSize == stackFloor) return;
var tmpImg = new Image();
tmpImg.src = drawStack[--stackIndex%stackSize];
tmpImg.onload = function() {
clearCanvas();
ctx.drawImage(this, 0, 0);
}
}
If your indexes are right, which I suspect they are not. You can look at an example implementation of the algorithm I described above in this fiddle .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.