在 fabric js 上实现撤消重做时,图像消失但出现在单击 canvas 区域时

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

我正在使用 canvas 并使用 JavaScript (Fabric.js) 执行撤销-重做操作。但是 Fabric.js 上的撤消重做图像消失了,但在单击 canvas 区域时出现。

如果有人能提供任何有用的解决方案。

运行 示例: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>

发生这种情况是因为 loadFromJSON 是异步的。

你不能打电话

canvas.loadFromJSON(json) canvas.renderAll()

但你应该使用

canvas.loadFromJSON(json, function() { canvas.renderAll() })