0
votes

I have problem with svg file. I have put svg file to src in img

SVG loader.svg:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<circle cx="50" cy="50" fill="none" stroke="#000" stroke-width="4" r="17" stroke-dasharray="80.11061266653974 28.703537555513243" transform="rotate(46.7215 50 50)">
  <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1"></animateTransform>
</circle>
</svg>

img in html

<img src="loader.svg" />

loader img This loader has width: 200px and height: 200px and circle inside width: 100px and height: 100px. Unfortunately when I change size of img circle inside is also change size because whole svg size is changed.

I would like to get result: To fix pernamently size circle inside svg - it could change size of background but circle insiede should be always 100x100px.

Is it possible to fix this size in svg?

1
What if you remove viewBox?MaximLensky
when I remove viewBox it is not in center and it is oval not circleGrzegorz

1 Answers

0
votes

Because your viewBox is always a 100x100 grid (not pixels!),
if you display the SVG at another scale it stretches SVG vectors

To maintain a 50 PIXEL RADIUS Circle you have to dynamically change the Circle SVG.

An experienced SVGer would do it by TRANSFORMing the SCALE of the Circle with a MATRIX

Easier is to calculate the 3 parameters for your circle:

RADIUS, but also the STROKEWIDTH (to keep the same width in every instance) and the GAP (25% of the circumference)

(and center the circle with a percentage!)

<circle cx="50%" cy="50%" stroke-width="STROKEWIDTH" r="RADIUS" stroke-dasharray="GAP">

Easiest to wrap the JavaScript in a modern W3C standard custom element, so you can use Semantic HTML:

<svg-loader width=6 color=red id=loader_1></svg-loader>
<svg-loader width=6 color=blue id=loader_2></svg-loader>
<svg-loader width=6 color=green id=loader_3></svg-loader>

<template id="SVG-LOADER">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
    <circle cx="50%" cy="50%" fill="none" stroke="COLOR" stroke-width="STROKEWIDTH" r="RADIUS" stroke-dasharray="GAP" transform="rotate(0 50 50)">
      <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1"></animateTransform>
    </circle>
  </svg>
</template>
<script>
  customElements.define('svg-loader', class extends HTMLElement {
    connectedCallback() {
      let svgTemplate = document.getElementById(this.nodeName).innerHTML;
      this.hostIMG = this.appendChild(document.createElement("IMG"));
      let { width } = getComputedStyle(this.hostIMG);
      width = Number(width.replace(/px/, ''));
      if (width === 0) width = 100;
      let strokewidth = Number(this.getAttribute("width"));
      let radius = (100 / width * (50 - (strokewidth / 2)));
      let gap = 2 * 3.14 * radius * 3 / 4; //25% gap
      strokewidth = (100 / width * strokewidth)
      this.hostIMG.src = `data:image/svg+xml,` +
        svgTemplate.replace(/"/g, "'").replace(/#/g, "%23")
        .replace(/RADIUS/g, radius).replace(/STROKEWIDTH/g, strokewidth)
        .replace(/GAP/g, gap).replace(/COLOR/g, this.getAttribute("color"));
    }
  });
</script>
<style>
  svg-loader img {    background: lightblue;  }
  #loader_1 img {    width: 100px;  }
  #loader_2 img {    width: 175px;  }
  #loader_3 img {    width: 80px;  }
</style>
<svg-loader width=6 color=red id=loader_1></svg-loader>
<svg-loader width=6 color=blue id=loader_2></svg-loader>
<svg-loader width=6 color=green id=loader_3></svg-loader>