1

I have a crazy problem with SVG rendering in chrome/chromium (firefox works as expected).

I want to render a circle with empty fill but stroke containing a template but for some reason once I try to change screen resolution, circle strokes start to being cut off mostly on bottom/right edge. I can't identify why it happens. I'd like to know what should I do to prevent stroke from being cut, any help is welcome

UPD I don't care about IE and other outdated browsers. Just modern ones

Link to reproduce: https://jsfiddle.net/k8cbq4dv/

Screenshot is attached enter image description here

The code itself:

<div id="root">
    <svg width="100%" viewBox="0 0 40 40" style="background-color: rgb(204, 255, 204);">
        <defs>
            <pattern id="greenglaze" patternUnits="userSpaceOnUse" width="5" height="5">
                <image href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSyiQU4yEPR1SIEF1mRiFOP1IMFoQ4s8y0vGJTRhRt4CbE4BaOuFEXrwEDWmI8ngIzbk_c&amp;usqp=CAU" width="5" height="5" preserveAspectRatio="none"></image>
            </pattern>
        </defs>
        <circle cx="20" cy="20" r="12.91549430918954" fill="transparent" transform-origin="center" stroke="url(#greenglaze)" stroke-width="7.9" stroke-dasharray="100 0" stroke-dashoffset="-0" transform="rotate(-90, 0, 0)"></circle>
    </svg>
</div>
enxaneta
  • 31,608
  • 5
  • 29
  • 42
Alex Antonov
  • 14,134
  • 7
  • 65
  • 142
  • Have you reported it to [Chrome's bugtracker](https://bugs.chromium.org/p/chromium/issues/list)? – Robert Longson Apr 29 '23 at 07:31
  • @RobertLongson do you think it's chrome bug? – Alex Antonov Apr 29 '23 at 08:02
  • Please try removing the `transform-origin="center"` and use `transform="rotate(-90, 20, 20)` instead – enxaneta Apr 29 '23 at 08:23
  • @enxaneta it doesn't work – Alex Antonov Apr 29 '23 at 10:04
  • When testing with Chromium 112/Linux Mint, the bug did show up only sometimes: the stack snippet was always correct, the jsFiddle did show it on initial load, but on resizing the output iframe the missing pattern parts became visible. – ccprog Apr 29 '23 at 13:27
  • I'm able to reproduce this when I set my screen to its highest resolution, but not at lower resolutions - and it only fails to fill the bottom segment correctly (Chrome 112/Win10/x64). Does this still reproduce when you reboot your machine at the new resolution (rather than changing resolution) - my guess is that some settings are getting cached on startup and don't get updated when resolution is updated. – Michael Mullany Apr 29 '23 at 15:18

3 Answers3

2

I was late, but after some time of checking. It was understood that your circle is making that cut on your donut.

Because your image was set to preserveAspectRatio="none", It will resize the content depend on the window size and it trigger that cut on the side of your image.

Maybe this could help or not, but using a stroke-miterlimit in your circle somehow fix the problem.

<div id="root">
  <svg viewBox="0 0 40 40" style="width: 100%; background-color: rgb(204, 255, 204);">
    <defs>
      <pattern id="greenglaze" patternUnits="userSpaceOnUse" width="5" height="5">
        <image href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSyiQU4yEPR1SIEF1mRiFOP1IMFoQ4s8y0vGJTRhRt4CbE4BaOuFEXrwEDWmI8ngIzbk_c&amp;usqp=CAU" width="5" height="5" preserveAspectRatio="none"></image>
      </pattern>
    </defs>
    <circle cx="20" cy="20" r="11" stroke="url(#greenglaze)" fill="transparent" transform-origin="center" stroke="url(#greenglaze)" stroke-miterlimit="30" stroke-width="7px" stroke-dasharray="100 0" stroke-dashoffset="-0" transform="rotate(-90, 0, 0)"/>
  </svg>
</div>
Newbee
  • 702
  • 1
  • 13
1

This is only a suspicion, so the answer might still be incorrect. At least for me, the jsFiddle error did disapear.

It could be that Chromium has a problem with identifying the bounding box of the final grafic because it has to take into acount the width of a stroke. If it somehow miscalulates at that point, it might decide that some of the repetitions of the pattern will always be outside of the effective clip path and just not render them.

The solution then would be to not use a stroke-width and instead draw two circular paths combined:

<div id="root">
  <svg width="100%" viewBox="0 0 40 40" style="background-color: rgb(204, 255, 204);">
    <defs>
      <pattern id="greenglaze" patternUnits="userSpaceOnUse" width="5" height="5">
        <image href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSyiQU4yEPR1SIEF1mRiFOP1IMFoQ4s8y0vGJTRhRt4CbE4BaOuFEXrwEDWmI8ngIzbk_c&amp;usqp=CAU" width="5" height="5" preserveAspectRatio="none"></image>
      </pattern>
    </defs>
    <path d="M 20 4.135
             A 15.865 15.865 0 0 0 20 35.865
             A 15.865 15.865 0 0 0 20 4.135 z
             M 20 10.035
             A 9.965 9.965 0 0 1 20 29.965
             A 9.965 9.965 0 0 1 20 10.035 z"
          fill="url(#greenglaze)" transform="rotate(-90, 20, 20)" />
    </svg>
</div>
ccprog
  • 20,308
  • 4
  • 27
  • 44
0

The previous code didn't really solve the problem.

My English is not one of the best.

I did several tests here and what I saw as a solution would be the use of css.

svg {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }
<div id="root">
  <svg width="100%" viewBox="0 0 40 40" style="background-color: rgb(204, 255, 204);">
    <defs>
      <pattern id="greenglaze" patternUnits="userSpaceOnUse" width="5" height="5">
        <image href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSyiQU4yEPR1SIEF1mRiFOP1IMFoQ4s8y0vGJTRhRt4CbE4BaOuFEXrwEDWmI8ngIzbk_c&amp;usqp=CAU" 
               width="5" 
               height="5" 
               preserveAspectRatio="none"></image>
      </pattern>
    </defs>
    <circle cx="20" 
            cy="20" 
            r="12.91549430918954" 
            fill="transparent" 
            transform-origin="center" 
            stroke="url(#greenglaze)" 
            stroke-width="7.9" 
            stroke-dasharray="100 0" 
            stroke-dashoffset="-0" 
            transform="rotate(-90, 0, 0)"></circle>
  </svg>
</div>