Search code examples
htmlsvgstroke-dasharray

First Svg stroke Dasharray affecting the other dasharrays


I have two circle svg on a page which should dynamically change it's stroke-dasharray based on the data passed in. However, the first value passed to the dash-array affects the subsequent ones.

For example If I pass 2 to the first and 4 to the second stroke-dasharray respectively, I expect them to have different strokes on the page, But they kept having the same strokes based on the first value passed.

Here is the codepen example

<div class="dashed-circle-progress">
      <div>
        <svg
          class="progress-radial"
          width="100px"
          height="100px"
          viewBox="0 0 120 120"
          shape-rendering="geometricPrecision"
        >
          <defs>
            <mask
              id="circle_mask"
              x="0"
              y="0"
              width="100"
              height="100"
              maskUnits="userSpaceOnUse"
            >
              <circle
                cx="50"
                cy="50"
                r="51"
                stroke-width="0"
                fill="black"
                opacity="1"
              />
              <circle
                id="bar"
                r="50"
                cx="50"
                cy="50"
                fill="transparent"
                stroke-dasharray="4"
                stroke-dashoffset="100"
                stroke="white"
                stroke-width="9"
                ref="progressBar"
              ></circle>
              <circle
                class="progress-radial-mask-inner"
                cx="50"
                cy="50"
                r="40"
                stroke-width="0"
                fill="black"
                opacity="1"
              />
            </mask>
          </defs>
          <g mask="url(#circle_mask)">
            <circle
              class="progress-radial-track"
              cx="50"
              cy="50"
              r="50"
              opacity="1"
              fill="#BDBDBD"
            />
            <path
              class="progress-radial-bar"
              transform="translate(50, 50)"
              d="M 0 0"
              fill="#F7AC2F"
              ref="progressRadialBar"
            ></path>
          </g>
        </svg>

      </div>
    </div>


<div class="dashed-circle-progress">
      <div>
        <svg
          class="progress-radial"
          width="100px"
          height="100px"
          viewBox="0 0 120 120"
          shape-rendering="geometricPrecision"
        >
          <defs>
            <mask
              id="circle_mask"
              x="0"
              y="0"
              width="100"
              height="100"
              maskUnits="userSpaceOnUse"
            >
              <circle
                cx="50"
                cy="50"
                r="51"
                stroke-width="0"
                fill="black"
                opacity="1"
              />
              <circle
                id="bar"
                r="50"
                cx="50"
                cy="50"
                fill="transparent"
                stroke-dasharray="16"
                stroke-dashoffset="100"
                stroke="white"
                stroke-width="9"
                ref="progressBar"
              ></circle>
              <circle
                class="progress-radial-mask-inner"
                cx="50"
                cy="50"
                r="40"
                stroke-width="0"
                fill="black"
                opacity="1"
              />
            </mask>
          </defs>
          <g mask="url(#circle_mask)">
            <circle
              class="progress-radial-track"
              cx="50"
              cy="50"
              r="50"
              opacity="1"
              fill="#BDBDBD"
            />
            <path
              class="progress-radial-bar"
              transform="translate(50, 50)"
              d="M 0 0"
              fill="#F7AC2F"
              ref="progressRadialBar"
            ></path>
          </g>
        </svg>
      </div>
    </div>

Solution

  • You're using the same IDs for the masks of both circles.

    If you use different IDs, everything works correctly:

    <div class="dashed-circle-progress">
      <div>
        <svg class="progress-radial" width="100px" height="100px" viewBox="0 0 120 120" shape-rendering="geometricPrecision">
              <defs>
                <mask
                  id="circle_mask_1"
                  x="0"
                  y="0"
                  width="100"
                  height="100"
                  maskUnits="userSpaceOnUse"
                >
                  <circle
                    cx="50"
                    cy="50"
                    r="51"
                    stroke-width="0"
                    fill="black"
                    opacity="1"
                  />
                  <circle
                    id="bar_1"
                    r="50"
                    cx="50"
                    cy="50"
                    fill="transparent"
                    stroke-dasharray="4"
                    stroke-dashoffset="100"
                    stroke="white"
                    stroke-width="9"
                    ref="progressBar"
                  ></circle>
                  <circle
                    class="progress-radial-mask-inner"
                    cx="50"
                    cy="50"
                    r="40"
                    stroke-width="0"
                    fill="black"
                    opacity="1"
                  />
                </mask>
              </defs>
              <g mask="url(#circle_mask_1)">
                <circle
                  class="progress-radial-track"
                  cx="50"
                  cy="50"
                  r="50"
                  opacity="1"
                  fill="#BDBDBD"
                />
                <path
                  class="progress-radial-bar"
                  transform="translate(50, 50)"
                  d="M 0 0"
                  fill="#F7AC2F"
                  ref="progressRadialBar"
                ></path>
              </g>
            </svg>
      </div>
    </div>
    
    
    <div class="dashed-circle-progress">
      <div>
        <svg class="progress-radial" width="100px" height="100px" viewBox="0 0 120 120" shape-rendering="geometricPrecision">
              <defs>
                <mask
                  id="circle_mask_2"
                  x="0"
                  y="0"
                  width="100"
                  height="100"
                  maskUnits="userSpaceOnUse"
                >
                  <circle
                    cx="50"
                    cy="50"
                    r="51"
                    stroke-width="0"
                    fill="black"
                    opacity="1"
                  />
                  <circle
                    id="bar_2"
                    r="50"
                    cx="50"
                    cy="50"
                    fill="transparent"
                    stroke-dasharray="16"
                    stroke-dashoffset="100"
                    stroke="white"
                    stroke-width="9"
                    ref="progressBar"
                  ></circle>
                  <circle
                    class="progress-radial-mask-inner"
                    cx="50"
                    cy="50"
                    r="40"
                    stroke-width="0"
                    fill="black"
                    opacity="1"
                  />
                </mask>
              </defs>
              <g mask="url(#circle_mask_2)">
                <circle
                  class="progress-radial-track"
                  cx="50"
                  cy="50"
                  r="50"
                  opacity="1"
                  fill="#BDBDBD"
                />
                <path
                  class="progress-radial-bar"
                  transform="translate(50, 50)"
                  d="M 0 0"
                  fill="#F7AC2F"
                  ref="progressRadialBar"
                ></path>
              </g>
            </svg>
      </div>
    </div>