...
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 shapeCallout struct {
12 *baseShape
13 }
14
15 const (
16 defaultTipWidth = 30.
17 defaultTipHeight = 45.
18 )
19
20 func NewCallout(box *geo.Box) Shape {
21 shape := shapeCallout{
22 baseShape: &baseShape{
23 Type: CALLOUT_TYPE,
24 Box: box,
25 },
26 }
27 shape.FullShape = go2.Pointer(Shape(shape))
28 return shape
29 }
30
31 func getTipWidth(box *geo.Box) float64 {
32 tipWidth := defaultTipWidth
33 if box.Width < tipWidth*2 {
34 tipWidth = box.Width / 2.0
35 }
36 return tipWidth
37 }
38
39 func getTipHeight(box *geo.Box) float64 {
40 tipHeight := defaultTipHeight
41 if box.Height < tipHeight*2 {
42 tipHeight = box.Height / 2.0
43 }
44 return tipHeight
45 }
46
47 func (s shapeCallout) GetInnerBox() *geo.Box {
48 tipHeight := getTipHeight(s.Box)
49 height := s.Box.Height - tipHeight
50 return geo.NewBox(s.Box.TopLeft.Copy(), s.Box.Width, height)
51 }
52
53 func calloutPath(box *geo.Box) *svg.SvgPathContext {
54 tipWidth := getTipWidth(box)
55 tipHeight := getTipHeight(box)
56 pc := svg.NewSVGPathContext(box.TopLeft, 1, 1)
57 pc.StartAt(pc.Absolute(0, 0))
58 pc.V(true, box.Height-tipHeight)
59 pc.H(true, box.Width/2.0)
60 pc.V(true, tipHeight)
61 pc.L(true, tipWidth, -tipHeight)
62 pc.H(true, box.Width/2.0-tipWidth)
63 pc.V(true, -(box.Height - tipHeight))
64 pc.H(true, -box.Width)
65 pc.Z()
66 return pc
67 }
68
69 func (s shapeCallout) Perimeter() []geo.Intersectable {
70 return calloutPath(s.Box).Path
71 }
72
73 func (s shapeCallout) GetSVGPathData() []string {
74 return []string{
75 calloutPath(s.Box).PathData(),
76 }
77 }
78
79 func (s shapeCallout) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) {
80
81
82 baseHeight := height + paddingY
83 if baseHeight < defaultTipHeight {
84 baseHeight *= 2
85 } else {
86 baseHeight += defaultTipHeight
87 }
88 return math.Ceil(width + paddingX), math.Ceil(baseHeight)
89 }
90
91 func (s shapeCallout) GetDefaultPadding() (paddingX, paddingY float64) {
92 return defaultPadding, defaultPadding / 2
93 }
94
View as plain text