skip to Main Content

Hi I want to have Layers sort control like on photoshop using FabricJS

enter image description here

I have this solution but it’s not working well when you have more than 3 objects on canvas:

$("#containerLayers").sortable({
  change: function(event, ui){
    $( "#containerLayers li" ).each(function(index,list){
        if(objectArray[$(list).attr('id')]){
            canvas.moveTo(objectArray[$(list).attr('id')],index);
        }
    });
    canvas.renderAll();
  }
});

Here is other parts of code:
https://jsfiddle.net/peLcju2h/16/

does anyone have a better solution than this?

2

Answers


  1. Chosen as BEST ANSWER

    Best solution for Layer ordering using FabricJS is this one:

    $("#containerLayers").sortable({
        update: function(event, ui){
    
            var items = $(this).children();
    
            items.each(function(i,item){
                canvas.sendToBack(objectArray[item.id]);
            });
            canvas.renderAll();
        }
    });
    

    Instead of using canvas.moveTo() just use canvas.sendToBack() and it will work perfect

    Here is link and you can see that ordering is working good https://jsfiddle.net/peLcju2h/24/


  2. First of all, you have some important refactorings to make in your code, mainly because of the fact that a lot of its snipets are duplicated.

    I did it already, and the final working code is here: https://jsfiddle.net/peLcju2h/18/


    Let’s see some considerations:

    • All the Canvas object creations had the same code, so wrap it into a function;
    • You were adding objs to your array through push() function, which is not wrong, but it messed up with your UI sortable handling. That’s because every time you change li‘s position, only the canvas and HTML are updated, but not the array itself.

      You could use a reordering function for this, but it wouldn’t fit the goal here once element positions don’t have a predefined order or changing logic.

      Instead, I decided to go with an auxiliary array, which is gonna be populated every time the items are sorted.

    • Push the items via [] operator into the array, using the object id as the key;

    • In the end, notice that I put a promise to guarantee the new objectArray will be rendered only after the canvas work has been done.

    Note: JSFiddle only works with HTTPS external links, so make sure you
    import them correctly in future attempts, even if you’re doing this
    via CSS @import.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search