Working with layers and Fabric.js

Template with Twitter Bootstrap and Fabric.js

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.2.0/fabric.all.min.js"></script>
<div class="container">
    <div class="row">
<div class="span2">
    <div id="btnGroup" class="btn-group">
        <button id="btnCreateCircle" class="btn btn-small" data-toggle="tooltip" title="Circle" rel="tooltip"><i class="icon-adjust"></i></button>
        <button id="btnCreateText" class="btn btn-small" data-toggle="tooltip" title="Text" rel="tooltip"><i class="icon-font"></i></button>
        <button id="btnCreateImage" class="btn btn-small" data-toggle="tooltip" title="Image" rel="tooltip"><i class="icon-picture"></i></button>
    </div>
    

</div>
<div class="span10">
    <canvas id="c" width="400" height="400"></canvas>
</div>
</div>
</div>
    <ul id="containerLayers">
    </ul>

CSS

@import url('http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css');
@import url('http://twitter.github.com/bootstrap/assets/css/bootstrap.css');
    
canvas{
  border-width: 1px;
  border-style: solid;
  border-color: #000;
  margin: 5px; 
}
#btnGroup{
  margin: 5px 5px 10px 3px;
}
#containerLayers { 
    list-style-type: none; 
    margin: 0; 
    padding: 0; 
    width: 100%; 
}
#containerLayers li { 
    margin: 0 0 2px 4px; 
    padding: 0.4em; 
    padding-left: 1.5em;
    height: 15px;
    cursor: move;
}
#containerLayers li span { 
    position: absolute; 
    margin-left: -1.3em; 
}

.actived{
    border: 1px solid black;
}

JavaScript

// Bootstrap tooltip
$("[data-toggle='tooltip']").tooltip({
  delay: { show: 500, hide: 100 },
  placement: "bottom"
});

// http://www.paulirish.com/2009/random-hex-color-code-snippets/
function randomColor(){
  return '#'+Math.floor(Math.random()*16777215).toString(16);
}

var imageSource = "http://fabricjs.com/lib/pug.jpg";

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

canvas.on("mouse:down", function(){
  var obj = canvas.getActiveObject();
  if(!obj){
    $("li").removeClass("actived");  
  }
});

$("#btnCreateCircle").click(function(evt){
  // remove active state of each layer
  $("li").removeClass("actived");
  canvas.deactivateAll();
    
  // object
  var circle = new fabric.Circle({
    left: fabric.util.getRandomInt(25, canvas.width - 25),
    top: fabric.util.getRandomInt(25, canvas.height - 25),
    radius: 25,
    fill: randomColor(),
    hasRotatingPoint: true
  });
  canvas.add(circle);
  canvas.setActiveObject(circle);
  canvas.renderAll();
    
  // layer
  var id = canvas.getObjects().length - 1;
  $("#containerLayers").prepend('<li id="'+ id +'" class="ui-state-default actived"><span class="ui-icon ui-icon-arrow-2-n-s"></span> item ' + id + '</li>');
  $("#"+id).click(function(evt){
    if($(this).hasClass("actived")){
      // remove active state of all layers and objects
      $("li").removeClass("actived");
      canvas.deactivateAll();
      canvas.renderAll();            
    }
    else{
      // remove active state of all layers and objects
      $("li").removeClass("actived");
      canvas.deactivateAll();
      canvas.renderAll();
      // activate layer and object      
      $(this).addClass("actived");
      var obj = canvas.item(id);
      canvas.setActiveObject(obj);
      canvas.renderAll();        
    }        
  });    
    
  circle.on('selected', function() {
    $("li").removeClass("actived");
    $("#"+id).addClass("actived");
  });
    
});

$("#btnCreateText").click(function(evt){
  // remove active state of...