Skip to content

Commit

Permalink
Use multVecMatrix in getBoundingBoxByChildren
Browse files Browse the repository at this point in the history
Try to apply transformation matrix to all 4 corners of the element
and then define rectangular bonding box
  • Loading branch information
linev committed Oct 31, 2024
1 parent 8f117ea commit 7cbd41e
Showing 1 changed file with 18 additions and 14 deletions.
32 changes: 18 additions & 14 deletions src/utils/bbox.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Context } from '../context/context'
import { getAttribute } from './node'
import { SvgNode } from '../nodes/svgnode'
import { Rect } from './geometry'
import { Rect, multVecMatrix } from './geometry'

export function getBoundingBoxByChildren(context: Context, svgnode: SvgNode): number[] {
if (getAttribute(svgnode.element, context.styleSheets, 'display') === 'none') {
Expand All @@ -12,22 +12,26 @@ export function getBoundingBoxByChildren(context: Context, svgnode: SvgNode): nu
const nodeBox = child.getBoundingBox(context)
if ((nodeBox[0] === 0) && (nodeBox[1] === 0) && (nodeBox[2] === 0) && (nodeBox[3] === 0))
return
const transform = child.computeNodeTransform(context)
// TODO: take into account rotation matrix
nodeBox[0] = nodeBox[0] * transform.sx + transform.tx
nodeBox[1] = nodeBox[1] * transform.sy + transform.ty
nodeBox[2] = nodeBox[2] * transform.sx
nodeBox[3] = nodeBox[3] * transform.sy
const transform = child.computeNodeTransform(context),
p1 = multVecMatrix([nodeBox[0], nodeBox[1]], transform),
p2 = multVecMatrix([nodeBox[0] + nodeBox[2], nodeBox[1]], transform),
p3 = multVecMatrix([nodeBox[0], nodeBox[1] + nodeBox[3]], transform),
p4 = multVecMatrix([nodeBox[0] + nodeBox[2], nodeBox[1] + nodeBox[3]], transform),
minx = Math.min(p1[0], p2[0], p3[0], p4[0]),
miny = Math.min(p1[1], p2[1], p3[1], p4[1]),
maxx = Math.max(p1[0], p2[0], p3[0], p4[0]),
maxy = Math.max(p1[1], p2[1], p3[1], p4[1]);

if (boundingBox.length === 0)
boundingBox = nodeBox
boundingBox = [minx, miny, maxx - minx, maxy - miny]
else
boundingBox = [
Math.min(boundingBox[0], nodeBox[0]),
Math.min(boundingBox[1], nodeBox[1]),
Math.max(boundingBox[0] + boundingBox[2], nodeBox[0] + nodeBox[2]) -
Math.min(boundingBox[0], nodeBox[0]),
Math.max(boundingBox[1] + boundingBox[3], nodeBox[1] + nodeBox[3]) -
Math.min(boundingBox[1], nodeBox[1])
Math.min(boundingBox[0], minx),
Math.min(boundingBox[1], miny),
Math.max(boundingBox[0] + boundingBox[2], maxx) -
Math.min(boundingBox[0], minx),
Math.max(boundingBox[1] + boundingBox[3], maxy) -
Math.min(boundingBox[1], miny)
]
})
return boundingBox.length === 0 ? [0, 0, 0, 0] : boundingBox
Expand Down

0 comments on commit 7cbd41e

Please sign in to comment.