Hi Robert,

> You could get the bounding box of the clip path and then just work out the
> intersection of the two rectangles. See the answer here for more details
>
>
http://stackoverflow.com/questions/10430518/getting-a-display-bounding-box-for-a\
-clipped-object/10433013#10433013<http://stackoverflow.com/questions/10430518/getting-a-display-bounding-box-for-a-clipped-object/10433013#10433013>

Thanks - that's a good trick for getting the bbox of the clip-path area.
I'll use that.
I realised I was actually after something a bit more general - an
equivalent of getBBox() that takes into account clip-paths and svg bounding
boxes of all the children.

I ended up implementing it as:

 // Get the bounding box, taking into account svg bounding windows
function getVisualBBox(el)
{
    var cloneEl = el.cloneNode(true);
    cloneEl = replaceClipPaths(cloneEl);

    // Do that trick of appending to the tree, so Firefox's getBBox doesn't
barf
    cloneEl.setAttribute("visibility", "hidden");
    document.documentElement.appendChild(cloneEl);
    var bbox = cloneEl.getBBox();
    document.documentElement.removeChild(cloneEl);
    return bbox;
}

// Replace any clip-paths in this element and its children with equivalent
rectangles
function replaceClipPaths(el)
{
    if (el.nodeType != 1)
        return;

    // Handle children first
    for (var i = 0; i < el.children.length; i++)
    {
        var testEl = el.children[i];
        var newChild = replaceClipPaths(testEl);
        if (newChild != testEl)
        {
            // Replace child
            el.insertBefore(newChild, testEl);
            el.removeChild(testEl);
        }
    }

    // Replace any clipping node and its children with a single rectangle
    // TODO: currently does only svg bounding box clip-paths.
    // TODO: currently creates a rect around the clip-path, regardless of
what's in the
    // visible area. This suits my use-case, but if you want the actual
bbox, you'll have
    // to further trim this rect according to what's inside it.
    if (el.nodeName == "svg" && el.width != null && el.height != null)
    {
        var replacementEl = document.createElementNS(svgns, "rect");
        replacementEl.setAttribute("x", el.getAttribute("x"));
        replacementEl.setAttribute("y", el.getAttribute("y"));
        replacementEl.setAttribute("width", el.getAttribute("width"));
        replacementEl.setAttribute("height", el.getAttribute("height"));
        replacementEl.setAttribute("stroke", "none");
        return replacementEl;
    }

    return el;
}

---

As you can see, it needs a little more work to be completely general
(including implementing your suggestion).
It's a pretty expensive solution - it clones the entire tree - but it's the
only way I could see of doing it properly. I considered iterating through
the tree and summing the bboxes of the child nodes, but I'm pretty sure
that won't work - you have to take into account the transforms on each
node, and that means the bboxes could be rotated, which means they don't
work as bboxes (as David D. mentions).

I'll post the result if I ever get around to implementing the TODO bits
above.

Thanks for your help!

Andrew.


[Non-text portions of this message have been removed]



------------------------------------

-----
To unsubscribe send a message to: svg-developers-unsubscr...@yahoogroups.com
-or-
visit http://groups.yahoo.com/group/svg-developers and click "edit my 
membership"
----Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/svg-developers/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/svg-developers/join
    (Yahoo! ID required)

<*> To change settings via email:
    svg-developers-dig...@yahoogroups.com 
    svg-developers-fullfeatu...@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
    svg-developers-unsubscr...@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

Reply via email to