How is the getBBox() SVGRect calculated?

后端 未结 7 1633
再見小時候
再見小時候 2020-12-04 15:29

I have a g element that contains one or more path elements. As I mentioned in another question, I scale and translate the g element by

7条回答
  •  攒了一身酷
    2020-12-04 16:26

    The following code takes into account the transformations (matrix or otherwise) from parents, itself, as well as children. So, it will work on a element for example.

    You will normally want to pass the parent as the third argument—toElement—as to return the computed bounding box in the coordinate space of the (which is generally the coordinate space we care about).

    /**
     * @param {SVGElement} element - Element to get the bounding box for
     * @param {boolean} [withoutTransforms=false] - If true, transforms will not be calculated
     * @param {SVGElement} [toElement] - Element to calculate bounding box relative to
     * @returns {SVGRect} Coordinates and dimensions of the real bounding box
     */
    function getBBox(element, withoutTransforms, toElement) {
    
      var svg = element.ownerSVGElement;
    
      if (!svg) {
        return { x: 0, y: 0, cx: 0, cy: 0, width: 0, height: 0 };
      }
    
      var r = element.getBBox(); 
    
      if (withoutTransforms) {
        return {
          x: r.x,
          y: r.y,
          width: r.width,
          height: r.height,        
          cx: r.x + r.width / 2,
          cy: r.y + r.height / 2
        };
      }
    
      var p = svg.createSVGPoint(); 
    
      var matrix = (toElement || svg).getScreenCTM().inverse().multiply(element.getScreenCTM()); 
    
      p.x = r.x;
      p.y = r.y;
      var a = p.matrixTransform(matrix);
    
      p.x = r.x + r.width;
      p.y = r.y;
      var b = p.matrixTransform(matrix);
    
      p.x = r.x + r.width;
      p.y = r.y + r.height;
      var c = p.matrixTransform(matrix);
    
      p.x = r.x;
      p.y = r.y + r.height;
      var d = p.matrixTransform(matrix);
    
      var minX = Math.min(a.x, b.x, c.x, d.x);
      var maxX = Math.max(a.x, b.x, c.x, d.x);
      var minY = Math.min(a.y, b.y, c.y, d.y);
      var maxY = Math.max(a.y, b.y, c.y, d.y);
    
      var width = maxX - minX;
      var height = maxY - minY;
    
      return {
        x: minX,
        y: minY,
        width: width,
        height: height,        
        cx: minX + width / 2,
        cy: minY + height / 2
      };
    }
    

提交回复
热议问题