JSFiddle - React, Tailwind, and code Playground

by Anand Rathod

HTML

<input type="button" value="addrect" onclick="addrect()">
<input type="button" value="undo" onclick="undo()">
<input type="button" value="redo" onclick="redo()">
    <input type="button" value="clear" onclick="clearcan()">
<br/>
<canvas id="fabriccanvas" width="600" height="200" style="border:1px solid #ccc"></canvas>

JavaScript

/*
undo redo commandhistory with canvas
*/

var canvas = new fabric.Canvas('fabriccanvas');
canvas.counter = 0;
var newleft = 0;
canvas.selection = false;

addrect = function addrect(top, left, width, height, fill) {
    canvas.add(new fabric.Rect({
        top: document.getElementById("fabriccanvas").height,
        name: 'rectangle ' + window.counter,
        left: 0 + newleft,
        width: 100,
        height: 100,
        fill: '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6),
        //fix attributes applied for all rects
        opacity: 0.75,
        lockRotation: true,
        originX: 'left',
        originY: 'bottom',
        cornerSize: 15,
        hasRotatingPoint: false,
        perPixelTargetFind: true,
        minScaleLimit: 1
    }));
    canvas.counter++;
    newleft += 100;
}

canvas.on({
    'object:added': countmods
});



var state = [];
ctr = 0; //counter
function countmods() {
    myjson = JSON.stringify(canvas);
    state.push(myjson);
}
undo = function undo() {
    ctr = ctr - 1;
    console.log('u :' + state[state.length - 1 + ctr]);
    canvas.loadFromJSON(state[state.length - 1 + ctr], canvas.renderAll.bind(canvas));
}

redo = function redo() {
    ctr = ctr + 1;
    console.log('u :' + state[state.length - 1 + ctr]);
    canvas.loadFromJSON(state[state.length - 1 + ctr], canvas.renderAll.bind(canvas));
}

clearcan = function clearcan() {
    canvas.clear().renderAll();
    newleft = 0;
}