0

I have a SVG timer. There is a path to show the current state. But the path overlaps badly as you can see in my attached screenshot:

screenshot

The code out of the inspector for this screenshot is:

<svg class="ion-timer-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" style="width: 100%; height: 100%;">
<circle fill="none" cx="60" cy="60" r="55" style="stroke: rgb(255, 255, 255); stroke-width: 10;"></circle>
<path fill="none" transform="scale(-1, 1) translate(-120 0)" d="M 114.89147163068816 63.4534536651529 A 55 55 0 0 0 60 5" style="stroke: rgb(0, 0, 0); stroke-width: 10; stroke-linecap: butt;"></path>
<g ng-transclude=""></g>
</svg>

This is how the SVG is generated:

// credit to http://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle
    // inspired by: https://github.com/crisbeto/angular-svg-round-progressbar
    var updateState = function(ring, val, total, options) {
      var polarToCartesian = function(centerX, centerY, radius, angleInDegrees) {
        var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
        return {
          x: centerX + (radius * Math.cos(angleInRadians)),
          y: centerY + (radius * Math.sin(angleInRadians))
        };
      };

      var R           = options.progressCircle.radius - (options.progressCircle.strokeWidth / 2);
      var size        = options.progressCircle.radius * 2;
      var value       = val >= total ? total - 0.00001 : val;
      var type        = 359.9999;
      var perc        = total === 0 ? 0 : (value / total) * type;
      var x           = size/2;
      var start       = polarToCartesian(x, x, R, perc); // in this case x and y are the same
      var end         = polarToCartesian(x, x, R, 0);
      var arcSweep    = (perc <= 180 ? '0' : '1');
      var d           = ['M', start.x, start.y, 'A', R, R, 0, arcSweep, 0, end.x, end.y].join(' ');

      return ring.attr('d', d);

This ugly white line outside the black path sucks. How to get rid of this? Is there any antializing?

Another option would be to do margin-top:-1px at the black path. But where to do this?

EDIT: This is the timer after the suggestions from ccprog:

http://imgur.com/a/m1hjw

<svg class="ion-timer-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" style="width: 100%; height: 100%;">
    <mask id="mask">
        <circle id="ring" fill="none" cx="60" cy="60" r="55" style="stroke: rgb(255, 255, 255); stroke-width: 10;"></circle>
    </mask>
    <g mask="url(#mask)">
        <circle fill="rgb(255, 255, 255)" cx="60" cy="60" r="61"></circle>
        <path fill="none" style="stroke-width: 12; stroke: rgb(0, 0, 0); stroke-linecap: butt;" transform="scale(-1, 1) translate(-120 0)" d="M 112.6047821265274 76.0541862895814 A 55 55 0 0 0 60 5"></path>
    </g>
    <g ng-transclude=""></g>
</svg>
m1crdy
  • 1,371
  • 2
  • 25
  • 58

1 Answers1

2

Use the full circle as a mask:

<svg class="ion-timer-svg"
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 120 120" style="width: 100%; height: 100%;">
  <mask id="mask">
    <circle id="ring" fill="none" cx="60" cy="60" r="55"
            style="stroke: rgb(255, 255, 255); stroke-width: 10;"></circle>
  </mask>
  <g mask="url(#mask)">
    <circle fill="rgb(255, 255, 255)" cx="60" cy="60" r="61" />
    <path fill="none" transform="scale(-1, 1) translate(-120 0)"
          d="M 114.89147163068816 63.4534536651529 A 55 55 0 0 0 60 5"
          style="stroke: rgb(0, 0, 0); stroke-width: 12; stroke-linecap: butt;"></path>
  </g>
 <g ng-transclude=""></g>
</svg>

Note that this works because the color of the circle stroke is white. Any other color would give you some transparency.

ccprog
  • 20,308
  • 4
  • 27
  • 44
  • That´s a great idea but does not really correct the bad line issue... Is there no way to scale the circle down for 2px? Then the path would overlap the circle and the issue is gone. – m1crdy Jun 14 '17 at 07:17
  • Did you see that I widened the stroke-width of the black arc? Everything that remains after that is an ephemeral effect that you will only observe at one specific size in one application on one specific hardware. - Otherwise, if you leave the circle and the arc independent, there is no reason not to draw them at a slightly different stroke-width. 0.5 to 1px should be enough in my experience. – ccprog Jun 14 '17 at 11:37
  • I've updated my proposal to make it even more robust. – ccprog Jun 14 '17 at 12:05
  • Thank you very much. Unfortunately it´s still bad. I have edited my question. I think i need to go with another background color... – m1crdy Jun 16 '17 at 13:28
  • This is suprising. Are there other grafic elements thet get rendered in this region? How does your background get rendered? What is the content that is transcluded by angular? – ccprog Jun 16 '17 at 14:45
  • The background-color of the SVG is set with background:#59C1D2 at the element. There are no other rendered elements in this region. I have removed the ng-transclude. It was transcluding nothing. – m1crdy Jun 19 '17 at 06:52
  • I have now used a image instead of background color which is a little bit smaller as the circle. This works now. But is there any possibility the get rid of the transparency? http://imgur.com/a/oIYki THANK YOU FOR HELPING! – m1crdy Jun 19 '17 at 07:13