...
1 package shape
2
3 import (
4 "math"
5
6 "oss.terrastruct.com/d2/lib/geo"
7 "oss.terrastruct.com/d2/lib/svg"
8 "oss.terrastruct.com/util-go/go2"
9 )
10
11 type shapePackage struct {
12 *baseShape
13 }
14
15 const (
16 packageTopMinHeight = 34.
17 packageTopMaxHeight = 55.
18 packageTopMinWidth = 50.
19 packageTopMaxWidth = 150.
20 packageHorizontalScalar = 0.5
21 packageVerticalScalar = 0.2
22 )
23
24 func NewPackage(box *geo.Box) Shape {
25 shape := shapePackage{
26 baseShape: &baseShape{
27 Type: PACKAGE_TYPE,
28 Box: box,
29 },
30 }
31 shape.FullShape = go2.Pointer(Shape(shape))
32 return shape
33 }
34
35 func (s shapePackage) GetInnerBox() *geo.Box {
36 tl := s.Box.TopLeft.Copy()
37 height := s.Box.Height
38
39 _, topHeight := getTopDimensions(s.Box)
40 tl.Y += topHeight
41 height -= topHeight
42 return geo.NewBox(tl, s.Box.Width, height)
43 }
44
45 func getTopDimensions(box *geo.Box) (width, height float64) {
46 width = box.Width * packageHorizontalScalar
47 if box.Width >= 2*packageTopMinWidth {
48 width = math.Min(packageTopMaxWidth, math.Max(packageTopMinWidth, width))
49 }
50 height = math.Min(packageTopMaxHeight, box.Height*packageVerticalScalar)
51 return width, height
52 }
53
54 func packagePath(box *geo.Box) *svg.SvgPathContext {
55 topWidth, topHeight := getTopDimensions(box)
56
57 pc := svg.NewSVGPathContext(box.TopLeft, 1, 1)
58 pc.StartAt(pc.Absolute(0, 0))
59 pc.L(false, topWidth, 0)
60 pc.L(false, topWidth, topHeight)
61 pc.L(false, box.Width, topHeight)
62 pc.L(false, box.Width, box.Height)
63 pc.L(false, 0, box.Height)
64 pc.Z()
65 return pc
66 }
67
68 func (s shapePackage) Perimeter() []geo.Intersectable {
69 return packagePath(s.Box).Path
70 }
71
72 func (s shapePackage) GetSVGPathData() []string {
73 return []string{
74 packagePath(s.Box).PathData(),
75 }
76 }
77
78 func (s shapePackage) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) {
79 innerHeight := height + paddingY
80
81
82
83 topHeight := innerHeight * packageVerticalScalar / (1. - packageVerticalScalar)
84 totalHeight := innerHeight + math.Min(topHeight, packageTopMaxHeight)
85
86 return math.Ceil(width + paddingX), math.Ceil(totalHeight)
87 }
88
89 func (s shapePackage) GetDefaultPadding() (paddingX, paddingY float64) {
90 return defaultPadding, .8 * defaultPadding
91 }
92
View as plain text