Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Dynimically add step to linear gradient of an svg with javascript

I’m trying to add some step to a linear gradient tag inside an svg with js.

My code works, meaning the markup is correct after the script run, but the svg is not updated/re-rendered.

I start with something like this

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<svg
      id="animatedPath"
      width="552"
      height="61"
      viewBox="0 0 552 61"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path
        id="pathToAnimate"
        d="M-22.125 45.875C42.5625 54.3125 56.625 31.8119 98.8125 20.5625C129.589 12.3558 166.31 9.3125 183.188 17.7506C205.688 29 218.018 54.3125 239.438 54.3125C261.938 54.3125 284.438 34.625 312.562 20.5625C340.688 6.5 345.75 9.3125 377.25 9.3125C416.625 9.3125 470.062 45.875 489.75 54.3125C509.438 62.75 524.639 55.9499 529.125 40.25C534.75 20.5625 534.75 6.5 616.312 3.6875"
        stroke-width="5.625"
        stroke-linecap="round"
      />
      <defs>
        <linearGradient
          id="logoGradient"
          x1="3.18749"
          y1="14.9375"
          x2="548.812"
          y2="20.5625"
          gradientUnits="userSpaceOnUse"
        ></linearGradient>
      </defs>
    </svg>

and in my js code i do a simple loop on a color array

let linearGradient = document.querySelector(
  "#animatedPath defs linearGradient"
);

let gradient=["#FFE600", "#05FF00", "#00D1FF", "#FF0000"];

gradient.forEach((color, index) => {
  let stop = document.createElement("stop");
  stop.setAttribute("offset", index / 4);
  stop.setAttribute("stop-color", color);
  linearGradient.appendChild(stop);
});

The code works, i can see the step inside the linear gradient but the svg is not updated.
If i put the step manually in the svg it clearly works, and if later in the code i try to manipulate the steps whit js, the svg get updated.

I’ve read some stuff about suspendRedraw, but also that is deprecated and may not apply to this case.

Does anybody has any suggestion?

let linearGradient = document.querySelector(
  "#animatedPath defs linearGradient"
);

let gradient = ["#FFE600", "#05FF00", "#00D1FF", "#FF0000"]

gradient.forEach((color, index) => {
  let stop = document.createElement("stop");
  stop.setAttribute("offset", index / 4);
  stop.setAttribute("stop-color", color);
  linearGradient.appendChild(stop);
});
 <svg
      id="animatedPath"
      width="552"
      height="61"
      viewBox="0 0 552 61"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path
        id="pathToAnimate"
        d="M-22.125 45.875C42.5625 54.3125 56.625 31.8119 98.8125 20.5625C129.589 12.3558 166.31 9.3125 183.188 17.7506C205.688 29 218.018 54.3125 239.438 54.3125C261.938 54.3125 284.438 34.625 312.562 20.5625C340.688 6.5 345.75 9.3125 377.25 9.3125C416.625 9.3125 470.062 45.875 489.75 54.3125C509.438 62.75 524.639 55.9499 529.125 40.25C534.75 20.5625 534.75 6.5 616.312 3.6875"
        stroke-width="5.625"
        stroke-linecap="round"
      />
      <defs>
        <linearGradient
          id="logoGradient"
          x1="3.18749"
          y1="14.9375"
          x2="548.812"
          y2="20.5625"
          gradientUnits="userSpaceOnUse"
        ></linearGradient>
      </defs>
    </svg>

>Solution :

For SVG elements, you need to use Document.createElementNS() instead of createElement(). The correct namespace to pass in for the first param is 'http://www.w3.org/2000/svg'.

let linearGradient = document.querySelector(
  "#animatedPath defs linearGradient"
);

let gradient = ["#FFE600", "#05FF00", "#00D1FF", "#FF0000"]

gradient.forEach((color, index) => {
  let stop = document.createElementNS("http://www.w3.org/2000/svg", "stop");
  stop.setAttribute("offset", index / 4);
  stop.setAttribute("stop-color", color);
  linearGradient.appendChild(stop);
});
<svg
      id="animatedPath"
      width="552"
      height="61"
      viewBox="0 0 552 61"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path
        id="pathToAnimate"
        d="M-22.125 45.875C42.5625 54.3125 56.625 31.8119 98.8125 20.5625C129.589 12.3558 166.31 9.3125 183.188 17.7506C205.688 29 218.018 54.3125 239.438 54.3125C261.938 54.3125 284.438 34.625 312.562 20.5625C340.688 6.5 345.75 9.3125 377.25 9.3125C416.625 9.3125 470.062 45.875 489.75 54.3125C509.438 62.75 524.639 55.9499 529.125 40.25C534.75 20.5625 534.75 6.5 616.312 3.6875"
        stroke-width="5.625"
        stroke-linecap="round"
      />
      <defs>
        <linearGradient
          id="logoGradient"
          x1="3.18749"
          y1="14.9375"
          x2="548.812"
          y2="20.5625"
          gradientUnits="userSpaceOnUse"
        ></linearGradient>
      </defs>
    </svg>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading