Abhishek Raj
Abhishek Raj

Reputation: 11

While implementing Undo Redo on fabric js the image disappears but appears on clicking on canvas area

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

Answers (1)

AndreaBogazzi
AndreaBogazzi

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

Related Questions