0

This relates to this bug: https://code.google.com/p/svg-edit/wiki/BrowserBugs#getBBox_on_paths_with_curves_includes_control_points

Given an arc (center, radius, startAngle, endAngle), I am able to calculate points along the path then their bounding box, however, in safari and chrome there is a bug that includes control points of the arc in the bounding box. Since gradient fills are applied to a shape's bounding box, this results in the gradient covering the shape slightly different depending on whether the browser has this bug or not.

My question is: without using the actual API (getBBox()) how can I mathematically calculate the extra control points of an arc in a path to adjust for the safari/chrome bug given these parameters (center, radius, startAngle, endAngle)?

This doesnt have to work with bezier curves or even ellipses, just a simple circular arc.

Thank You!

  • possible duplicate of [Geometrical Arc to Bezier Curve](http://stackoverflow.com/questions/734076/geometrical-arc-to-bezier-curve) – Paul LeBeau Oct 18 '14 at 03:19
  • Yes. Thank you.. Though that does answer the question on the mathematical level, I was interested in a simple JavaScript function that would take those parameters and give the answer, but perhaps I need to do some work on this. – Arthur Puszynski Oct 29 '14 at 16:08
  • Well I have some (Java) code in my SVG library (AndroidSVG) that does this. But it doesn't necessarily calculate the same bezier control points as Chrome and Safari do. – Paul LeBeau Oct 30 '14 at 03:13

2 Answers2

2

I wrote a getBBox shim for webkit browsers. Demo here

//webkit(safari, chrome) path element getBBox bug
if(navigator.userAgent.indexOf('AppleWebKit')>0){
    SVGPathElement.prototype.getBBox = function (precision){
        var path = this;
        var total = path.getTotalLength();
        if(total <= 0){
            return {x:0,y:0,width:0,height:0};
        }
        var segLen = precision || 1;
        var len = 0, pt, xarr = [], yarr = [];
        while(len < total){
            pt = path.getPointAtLength(len);
            xarr.push(pt.x);
            yarr.push(pt.y);
            len += segLen;
        }
        pt = path.getPointAtLength(total);
        xarr.push(pt.x);
        yarr.push(pt.y);
        var b = {};
        b.x = Math.min.apply(0,xarr);
        b.y = Math.min.apply(0,yarr);
        b.width = Math.max.apply(0,xarr) - b.x;
        b.height = Math.max.apply(0,yarr) - b.y;
        return b;
    };
}
cuixiping
  • 24,167
  • 8
  • 82
  • 93
1

For a hint on how you might implement a shim for getBBox(), take a look at what Snap.svg is doing here: https://github.com/adobe-webplatform/Snap.svg/blob/master/src/path.js#L414

In fact, for a <path> DOM element, you can get a correct BBox by calling:

Snap.path.getBBox(pathElement.getAttribute('d'))
Dan
  • 9,912
  • 18
  • 49
  • 70