JSFiddle - React, Tailwind, and code Playground

by Anuraj MS

HTML

<script src="http://rawgithub.com/kangax/fabric.js/master/dist/all.js"></script>
<script src=http://cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.js></script>
<canvas id="c" width="400" height="200"></canvas>
<br>
<br>
<input type="button" id="addtext" value="Add Text" />
<input type="button" id="undo" value="Undo" />
<input type="button" id="redo" value="redo" />
<input type="button" id="clear" value="Clear Canvas" />

CSS

canvas {
    border:1px solid #000;
}
.controles {
    margin:50px 0;
}

JavaScript

var canvas = new fabric.Canvas('c');

var current;
var list = [];
var state = [];
var index = 0;
var index2 = 0;
var action = false;
var refresh = true;

canvas.on("object:added", function (e) {
    var object = e.target;
    console.log('object:modified');

    if (action === true) {
        state = [state[index2]];
        list = [list[index2]];

        action = false;
        console.log(state);
        index = 1;
    }
    object.saveState();

    console.log(object.originalState);
    state[index] = JSON.stringify(object.originalState);
    list[index] = object;
    index++;
    index2 = index - 1;
    
    refresh = true;
});

canvas.on("object:modified", function (e) {
    var object = e.target;
    console.log('object:modified');

    if (action === true) {
        state = [state[index2]];
        list = [list[index2]];

        action = false;
        console.log(state);
        index = 1;
    }

    object.saveState();

    state[index] = JSON.stringify(object.originalState);
    list[index] = object;
    index++;
    index2 = index - 1;

    console.log(state);
    refresh = true;
});

function undo() {

    if (index <= 0) {
        index = 0;
        return;
    }
    
    if (refresh === true) {
        index--;
        refresh = false;
    }

    console.log('undo');

    index2 = index - 1;
    current = list[index2];
    current.setOptions(JSON.parse(state[index2]));

    index--;

    canvas.renderAll();
    action = true;
}

function redo() {

    action = true;
    if (index >= state.length - 1) {
        return;
    }

    console.log('redo');

    index2 = index + 1;
    current = list[index2];
    current.setOptions(JSON.parse(state[index2]));

    index++;

    canvas.renderAll();
}

var text = new fabric.Text('Sample', {
    fontFamily: 'Hoefler Text',
    left: 50,
    top: 30,
    //textAlign: 'center',
    fill: 'navy',

});
canvas.add(text);

$('#undo').click(function () {
    undo();
});
$('#redo').click(function () {
    redo();
});