Search code examples
cssangularjssvg

The calculation behind progress circle using dasharray and dashoffset


I'm building a small angularjs directive which will display a progress circle(I don't want animation) and there will be a text in the middle of it indicating the percentage of completion. The html code of the circle is:

   <path fill="none" stroke="rgb(0,51,117)" stroke-width="5" stroke-linecap="square" d="M25,2.5A22.5,22.5 0 1 1 2.5,25A22.5,22.5 0 0 1 25,2.5" stroke-dasharray="105" stroke-dashoffset="{{circle.percentage*(-140)/100 + 105 }}">
    </path>

I don't know the calculation behind the dasharray and dashoffset, I get the calculation {{circle.percentage*(-140)/100 + 105 }} by adjusting the dashoffset and guessing.

I have a fiddle http://jsfiddle.net/ADukg/10992/

As you can see, it only works for the circles from 30% to 70%. Does anyone know the correct calculation of it? I use the CSS tag as one of the tags of my question because the calculation should also work in CSS. Thank you in advance


Solution

  • You could have two circles that overlay each other. The first circle being the gray outline and the second circle being the progress overlay. Then change the stroke-dasharray and stroke-dashoffset values of just the second circle and rotate the svg by 90 degrees:

    html:

    <circle cx="25" cy="25" r="22.5" stroke="rgb(188,188,188)" stroke-width="5" fill="none"></circle>
    <circle cx="25" cy="25" r="22.5" stroke="rgb(0,51,117)" stroke-width="5" fill="none" stroke-dasharray="{{circle.circumference}}" stroke-dashoffset="{{circle.circumference * (1 - circle.percentage/100)}}"></circle>
    

    js:

    function MyCtrl($scope) {
        var radius = 22.5;
        var circumference = Math.PI*(radius*2);
        $scope.circles = [];
        for(var i=0; i<=10; i++){
            var circle = {
                percentage : i* 10,
                circumference: circumference
          };
          $scope.circles.push(circle);
        }
    }
    

    css:

    .progress {
        transform: rotate(-90deg);
    }
    

    Link to jsfiddle

    I found this tutorial helpful.