Reputation: 11
I am working with a canvas and implementing undo-redo operation using JavaScript (Fabric.js). But the Undo Redo on Fabric.js the image disappears but appears on clicking on canvas area.
If anyone can provide any solution that would be helpful.
Running example : https://jsfiddle.net/devilla/wdrbohj5/4/
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js">
</script>
</head>
<body>
<div style=" height:80px; margin-bottom: 50px; margin-top: 50px;">
<p style="width:30; height:15px; font-size: 25px; font-family: appleberry;"></p>
<img src="https://www.w3schools.com/css/trolltunga.jpg" onclick="clipFunction(this)" style="width:60px; height:35px;margin-left: 2px; margin-top: 2px; margin-right: 2px;margin-bottom: 2px;">
<img src="https://www.planwallpaper.com/static/images/images_1_05GM1zY.jpg" onclick="clipFunction(this)" style="width:60px; height:35px;margin-left: 2px; margin-top: 2px; margin-right: 2px;margin-bottom: 2px;">
</div>
<div id="image5">
<canvas id="c" height="500px" width="280px" style="position:fixed; border:0px solid lightblue; user-select: none; border-radius: 7px;">
</canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script>
var canvas = new fabric.Canvas('c');
function clipFunction(elt) {
fabric.Image.fromURL(elt.src, function(oImg) {
oImg.setLeft(50);
oImg.set({
width: canvas.width / 2,
height: canvas.height / 2
});
oImg.setTop(150);
oImg.set('selectable', false);
img = new fabric.Group([oImg]);
canvas.add(img);
canvas.renderAll();
});
}
/* UNDO REDO */
var state = [];
var mods = 0;
canvas.on(
'object:modified',
function() {
updateModifications(true);
},
'object:added',
function() {
updateModifications(true);
});
function updateModifications(savehistory) {
if (savehistory === true) {
myjson = JSON.stringify(canvas);
state.push(myjson);
}
}
undo = function undo() {
if (mods < state.length) {
canvas.clear().renderAll();
canvas.loadFromJSON(state[state.length - 1 - mods - 1]);
canvas.renderAll();
//console.log("geladen " + (state.length-1-mods-1));
//console.log("state " + state.length);
mods += 1;
//console.log("mods " + mods);
}
}
redo = function redo() {
if (mods > 0) {
canvas.clear().renderAll();
canvas.loadFromJSON(state[state.length - 1 - mods + 1]);
canvas.renderAll();
//console.log("geladen " + (state.length-1-mods+1));
mods -= 1;
//console.log("state " + state.length);
//console.log("mods " + mods);
}
}
clearcan = function clearcan() {
canvas.clear().renderAll();
}
/**/
</script>
</div>
<div id="UR" style="position: fixed; bottom :10px; height:50px;width:180px; border:1px solid lightgreen;">
<input type="button" value="undo" onclick="undo()">
<input type="button" value="redo" onclick="redo()">
<input type="button" value="clear" onclick="clearcan()">
</div>
Upvotes: 0
Views: 764
Reputation: 14731
This happens because loadFromJSON is async.
you cannot call
canvas.loadFromJSON(json)
canvas.renderAll()
but you should use
canvas.loadFromJSON(json, function() {
canvas.renderAll()
})
Upvotes: 1