diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 7e106eb0a..14df29c5d 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -124,8 +124,7 @@ func Layout(ctx context.Context, g *d2graph.Graph) error { innerTL := s.GetInsidePlacement(totalWidth, totalHeight, 0, 0) // depending on the shape innerBox may be larger than totalWidth, totalHeight // if this is the case, we want to center the cells within the larger innerBox - innerBox := s.GetInnerBox() - + innerBox := s.GetInnerBoxForContent(totalWidth, totalHeight) var resizeDx, resizeDy float64 if innerBox.Width > totalWidth { resizeDx = (innerBox.Width - totalWidth) / 2 diff --git a/lib/shape/shape.go b/lib/shape/shape.go index 29bbdc36e..a7f5ad594 100644 --- a/lib/shape/shape.go +++ b/lib/shape/shape.go @@ -45,6 +45,7 @@ type Shape interface { GetBox() *geo.Box GetInnerBox() *geo.Box + GetInnerBoxForContent(width, height float64) *geo.Box // placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point @@ -88,6 +89,11 @@ func (s baseShape) GetInnerBox() *geo.Box { return s.Box } +// only cloud shape needs this right now +func (s baseShape) GetInnerBoxForContent(width, height float64) *geo.Box { + return (*s.FullShape).GetInnerBox() +} + func (s baseShape) GetInsidePlacement(_, _, paddingX, paddingY float64) geo.Point { innerTL := (*s.FullShape).GetInnerBox().TopLeft return *geo.NewPoint(innerTL.X+paddingX/2, innerTL.Y+paddingY/2) diff --git a/lib/shape/shape_cloud.go b/lib/shape/shape_cloud.go index 11a34e6bc..0f224bf8b 100644 --- a/lib/shape/shape_cloud.go +++ b/lib/shape/shape_cloud.go @@ -43,12 +43,16 @@ func NewCloud(box *geo.Box) Shape { return shape } -// TODO this isn't always accurate since the content aspect ratio might be different from the final shape's https://github.com/terrastruct/d2/issues/1735 func (s shapeCloud) GetInnerBox() *geo.Box { - width := s.Box.Width - height := s.Box.Height + return s.GetInnerBoxForContent(s.Box.Width, s.Box.Height) +} + +// we need this since the content's aspect ratio determines which placement is used +func (s shapeCloud) GetInnerBoxForContent(width, height float64) *geo.Box { insideTL := s.GetInsidePlacement(width, height, 0, 0) aspectRatio := width / height + // aspect ratio and position are computed with given dimensions, but final box size is determined by shape size + width, height = s.Box.Width, s.Box.Height if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY { width *= CLOUD_WIDE_INNER_WIDTH height *= CLOUD_WIDE_INNER_HEIGHT