且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在HTML SVG元素中使用`element.offsetParent`?

更新时间:2023-09-18 09:25:40

在SVG中不存在offsetParent。

offsetParent does not exist in SVG.

要获取SVG节点的边界框坐标,通常会在SVG元素上使用getBBox方法。这将返回该元素的本地坐标系中的bbox。要确定屏幕坐标中SVG元素的位置,然后在元素上使用getScreenCTM来获取将该元素的本地坐标转换为屏幕坐标的变换矩阵。然后,您可以通过返回的转换矩阵转换返回的bbox。下面是一些代码:

To get the bounding box coordinates of an SVG node, you would typically use the getBBox method on the SVG element. This returns a bbox in the local coordinate system of that element. To determine the location of the SVG element in screen coordinates, then, you use getScreenCTM on the element to get a transformation matrix that will transform that element's local coordinates to screen coordinates. You then transform the returned bbox by the returned transformation matrix. Here's some code to do this:

function getBoundingBoxInArbitrarySpace(element,mat){
    var svgRoot = element.ownerSVGElement;
    var bbox = element.getBBox();

    var cPt1 =  svgRoot.createSVGPoint();
    cPt1.x = bbox.x;
    cPt1.y = bbox.y;
    cPt1 = cPt1.matrixTransform(mat);

    // repeat for other corner points and the new bbox is
    // simply the minX/minY  to maxX/maxY of the four points.
    var cPt2 = svgRoot.createSVGPoint();
    cPt2.x = bbox.x + bbox.width;
    cPt2.y = bbox.y;
    cPt2 = cPt2.matrixTransform(mat);

    var cPt3 = svgRoot.createSVGPoint();
    cPt3.x = bbox.x;
    cPt3.y = bbox.y + bbox.height;
    cPt3 = cPt3.matrixTransform(mat);

    var cPt4 = svgRoot.createSVGPoint();
    cPt4.x = bbox.x + bbox.width;
    cPt4.y = bbox.y + bbox.height;
    cPt4 = cPt4.matrixTransform(mat);

    var points = [cPt1,cPt2,cPt3,cPt4]

    //find minX,minY,maxX,maxY
    var minX=Number.MAX_VALUE;
    var minY=Number.MAX_VALUE;
    var maxX=0
    var maxY=0
    for(i=0;i<points.length;i++)
    {
        if (points[i].x < minX)
        {
            minX = points[i].x
        }
        if (points[i].y < minY)
        {
            minY = points[i].y
        }
        if (points[i].x > maxX)
        {
            maxX = points[i].x
        }
        if (points[i].y > maxY)
        {
            maxY = points[i].y
        }
    }

    //instantiate new object that is like an SVGRect
    var newBBox = {"x":minX,"y":minY,"width":maxX-minX,"height":maxY-minY}
    return newBBox; 
}   

function getBBoxInScreenSpace(element){
    return getBoundingBoxInArbitrarySpace(element,element.getScreenCTM());
}

此代码取自这里,是Apache授权。 getBoundingBoxInArbitrarySpace已经过测试,但是getBBoxInScreenSpace还没有(但我认为它应该可行)。

This code was taken from here, and is Apache-licensed. getBoundingBoxInArbitrarySpace has been tested, but getBBoxInScreenSpace hasn't (but I think it should work).