61 lines
1.2 KiB
Go
61 lines
1.2 KiB
Go
package shape
|
|
|
|
import (
|
|
"oss.terrastruct.com/d2/lib/geo"
|
|
"oss.terrastruct.com/d2/lib/svg"
|
|
)
|
|
|
|
type shapeCallout struct {
|
|
*baseShape
|
|
}
|
|
|
|
func NewCallout(box *geo.Box) Shape {
|
|
return shapeCallout{
|
|
baseShape: &baseShape{
|
|
Type: CALLOUT_TYPE,
|
|
Box: box,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (s shapeCallout) GetInnerBox() *geo.Box {
|
|
height := s.Box.Height
|
|
tipHeight := 45.0
|
|
if height < tipHeight*2 {
|
|
tipHeight = height / 2.0
|
|
}
|
|
height -= tipHeight
|
|
return geo.NewBox(s.Box.TopLeft.Copy(), s.Box.Width, height)
|
|
}
|
|
|
|
func calloutPath(box *geo.Box) *svg.SvgPathContext {
|
|
tipWidth := 30.0
|
|
if box.Width < tipWidth*2 {
|
|
tipWidth = box.Width / 2.0
|
|
}
|
|
tipHeight := 45.0
|
|
if box.Height < tipHeight*2 {
|
|
tipHeight = box.Height / 2.0
|
|
}
|
|
pc := svg.NewSVGPathContext(box.TopLeft, 1, 1)
|
|
pc.StartAt(pc.Absolute(0, 0))
|
|
pc.V(true, box.Height-tipHeight)
|
|
pc.H(true, box.Width/2.0)
|
|
pc.V(true, tipHeight)
|
|
pc.L(true, tipWidth, -tipHeight)
|
|
pc.H(true, box.Width/2.0-tipWidth)
|
|
pc.V(true, -(box.Height - tipHeight))
|
|
pc.H(true, -box.Width)
|
|
pc.Z()
|
|
return pc
|
|
}
|
|
|
|
func (s shapeCallout) Perimeter() []geo.Intersectable {
|
|
return calloutPath(s.Box).Path
|
|
}
|
|
|
|
func (s shapeCallout) GetSVGPathData() []string {
|
|
return []string{
|
|
calloutPath(s.Box).PathData(),
|
|
}
|
|
}
|