Drawing SVG element on top with smooth transitions

I have a page with various SVG elements that react when they hover. When hovering, the element grows in size to cover the adjacent elements. My problem is that some of the neighbors were made later and will not be covered. [ Example ]

I tried to fix this issue by using appendChild()

on hover to make it the last element rendered, but that removes the smooth transition effect I set with CSS.

Example:

for (var i = 0; i < 20; i++) {
  for (var n = 0; n < 5; n++) {
    var new_rect = document.getElementById("0").cloneNode(true);
    new_rect.setAttributeNS(null, "cx", i * 20 + 10);
    new_rect.setAttributeNS(null, "cy", n * 20 + 10);

    new_rect.setAttributeNS(null, "id", i + n);
    document.getElementById("mainG").appendChild(new_rect);
  }
}

function expand(evt) {
  //evt.target.parentNode.appendChild(evt.target);
  evt.target.setAttributeNS(null, "r", "25");
}

function shrink(evt) {
  evt.target.setAttributeNS(null, "r", "10");
}
      

.circle {
  fill: hsl(100, 30%, 80%);
  -webkit-transition: .1s ease-in-out;
}
.circle:hover {
  fill: hsl(0, 50%, 70%);
}
      

<svg version="1.1" baseProfile="full" width="440" height="150" xmlns="http://www.w3.org/2000/svg">
  <g id="mainG">
    <circle id="0" cx="10" cy="10" r="10" stroke="none" fill="white" class="circle" onmouseover="expand(evt)" onmouseout="shrink(evt)"></circle>
  </g>
  <g id="cloneG"></g>
</svg>
      

Run codeHide result


How can I get the element to be drawn on top while still having smooth transitions between states?

+3


source to share


2 answers


You can force payment as follows.

var test = evt.target.offsetHeight;

      

Do this just before changing the radius



for (var i = 0; i < 20; i++) {
  for (var n = 0; n < 5; n++) {
    var new_rect = document.getElementById("0").cloneNode(true);
    new_rect.setAttributeNS(null, "cx", i * 20 + 10);
    new_rect.setAttributeNS(null, "cy", n * 20 + 10);

    new_rect.setAttributeNS(null, "id", i + n);
    document.getElementById("mainG").appendChild(new_rect);
  }
}

function expand(evt) {
  evt.target.parentNode.appendChild(evt.target);
  var test = evt.target.offsetHeight;
  evt.target.setAttributeNS(null, "r", "25");
}

function shrink(evt) {
  evt.target.setAttributeNS(null, "r", "10");
}
      

.circle {
  fill: hsl(100, 30%, 80%);
  -webkit-transition: 1s ease-in-out;
}
.circle:hover {
  fill: hsl(0, 50%, 70%);
}
      

<svg version="1.1" baseProfile="full" width="440" height="150" xmlns="http://www.w3.org/2000/svg">
  <g id="mainG">
    <circle id="0" cx="10" cy="10" r="10" stroke="none" fill="white" class="circle" onmouseover="expand(evt)" onmouseout="shrink(evt)"></circle>
  </g>
  <g id="cloneG"></g>
</svg>
      

Run codeHide result


+1


source


this way you keep the CSS transition:

    for (var i = 0; i < 20; i++) {
  for (var n = 0; n < 5; n++) {
    var new_rect = document.getElementById("0").cloneNode(true);
    new_rect.setAttributeNS(null, "cx", i * 20 + 10);
    new_rect.setAttributeNS(null, "cy", n * 20 + 10);

    new_rect.setAttributeNS(null, "id", i + n);
    document.getElementById("mainG").appendChild(new_rect);
  }
}

function expand(evt) {
  evt.target.parentNode.appendChild(evt.target); 
  evt.target.setAttributeNS(null, "r", "25");
  evt.target.style.fill='hsl(0, 50%, 70%)';
}

function shrink(evt) {
  evt.target.setAttributeNS(null, "r", "10");
  evt.target.style.fill='hsl(100, 30%, 80%)';
}
      

 .circle {
  fill: hsl(100, 30%, 80%);
  -webkit-transition: .4s ease-in-out;
}
      

<svg version="1.1" baseProfile="full" width="440" height="150" xmlns="http://www.w3.org/2000/svg">
  <g id="mainG">
    <circle id="0" cx="10" cy="10" r="10" stroke="none" fill="white" class="circle" onmouseover="expand(evt)" onmouseout="shrink(evt)"></circle>
  </g>
  <g id="cloneG"></g>
</svg>
      

Run codeHide result




or (same with CSS added via JS)

    for (var i = 0; i < 20; i++) {
      for (var n = 0; n < 5; n++) {
        var new_rect = document.getElementById("0").cloneNode(true);
        new_rect.setAttributeNS(null, "cx", i * 20 + 10);
        new_rect.setAttributeNS(null, "cy", n * 20 + 10);
        new_rect.style.fill='hsl(100, 30%, 80%)';
        new_rect.setAttributeNS(null, "id", i + n);
        document.getElementById("mainG").appendChild(new_rect);
          
      }
    }

    function expand(evt) {
      evt.target.parentNode.appendChild(evt.target); 
      evt.target.setAttributeNS(null, "r", "25");
      evt.target.style.fill='hsl(0, 50%, 70%)';
      evt.target.style.transition= '.4s ease-in-out';
    }

    function shrink(evt) {
      evt.target.setAttributeNS(null, "r", "10");
      evt.target.style.fill='hsl(100, 30%, 80%)';
    }
      

<svg version="1.1" baseProfile="full" width="440" height="150" xmlns="http://www.w3.org/2000/svg">
      <g id="mainG">
        <circle id="0" cx="10" cy="10" r="10" stroke="none" fill="white" class="circle" onmouseover="expand(evt)" onmouseout="shrink(evt)"></circle>
      </g>
      <g id="cloneG"></g>
    </svg>
      

Run codeHide result


0


source







All Articles