javascripthtmlsvgsnap.svg

Remove and add elements from same position in snap svg group


I have snap svg group of 5 elements like;

let canvas = Snap('#svg');
let myGroup = canvas.g();

myGroup.add(canvas.rect(100, 200, 110, 220).attr({fill: '#000'}));
myGroup.add(canvas.circle(400, 400, 50).attr({fill: '#500'}));

// want to remove this element later
myGroup.add(canvas.rect(100, 200, 50, 60).attr({fill: '#050'}));

myGroup.add(canvas.text(50, 100, 'Some Text').attr({stroke: '#005'}));
myGroup.add(canvas.rect(700, 200, 110, 220).attr({fill: '#055'}));

Then I can access the specific elements of myGroup using the index, for instance, if I want to change the attributes of text I can use myGroup[3] because it is at 3rd index in myGroup.

Now I want to remove the element at 2nd index and then add some other element at same index, so I used remove() method like;

myGroup[2].remove();
myGroup.add(canvas.path('M 100 200 l 30 35').attr({stroke: '#050'}));

but the problem is; the elements at 3rd and 4th index got shifted up (2nd and 3rd respectively) and new element has been added to 4th index.

Does anyone know how can I add element at the same index?


Solution

  • you can use insertAfter or insertBefore method to achieve this.

    Example:

    If you like replace a node from canvas group with an index of 2. remove the node using remove method.

    myGroup[2].remove();
    

    and insert the new node with insertBefore method

    canvas.path('M 100 110 l 30 35').attr({
       stroke: '#050'
    }).insertBefore(myGroup[2]);
    

    this will replace the old node with the new one.

    Example Solution:

    let canvas = Snap('#svg');
    
    let myGroup = canvas.g();
    
    myGroup.add(canvas.rect(100, 110, 110, 220).attr({
      fill: '#000'
    }));
    myGroup.add(canvas.circle(400, 400, 50).attr({
      fill: '#500'
    }));
    
    // want to remove this element later
    myGroup.add(canvas.rect(100, 110, 50, 60).attr({
      fill: '#050'
    }));
    
    myGroup.add(canvas.text(50, 100, 'Some Text').attr({
      stroke: '#005'
    }));
    myGroup.add(canvas.rect(700, 200, 110, 220).attr({
      fill: '#055'
    }));
    
    function replaceElement() {
      myGroup[2].remove();
      canvas.path('M 100 110 l 30 35').attr({
        stroke: '#050'
      }).insertBefore(myGroup[2]);
    }
    #svg {
      width: 500px;
      height: 500px;
    }
    
    button {
      display: block;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js" integrity="sha512-Gk+uNk8NWN235mIkS6B7/424TsDuPDaoAsUekJCKTWLKP6wlaPv+PBGfO7dbvZeibVPGW+mYidz0vL0XaWwz4w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
    <button onclick="replaceElement()">replace</button>
    <svg id="svg"></svg>