From 6632740fb19282d0cd36cd1339cd5d22c959cb9e Mon Sep 17 00:00:00 2001 From: Antoine Poivey Date: Thu, 9 Mar 2023 17:10:12 +0100 Subject: [PATCH] feat: add possiblity to set shape border-radius with percentage value --- d2exporter/export.go | 2 +- d2graph/d2graph.go | 5 ++++- d2renderers/d2svg/d2svg.go | 4 ++-- d2target/d2target.go | 2 +- d2themes/element.go | 11 +++++++++-- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/d2exporter/export.go b/d2exporter/export.go index bc84f4246..1c1dd2ecc 100644 --- a/d2exporter/export.go +++ b/d2exporter/export.go @@ -76,7 +76,7 @@ func applyStyles(shape *d2target.Shape, obj *d2graph.Object) { shape.Multiple, _ = strconv.ParseBool(obj.Attributes.Style.Multiple.Value) } if obj.Attributes.Style.BorderRadius != nil { - shape.BorderRadius, _ = strconv.Atoi(obj.Attributes.Style.BorderRadius.Value) + shape.BorderRadius, _ = strconv.ParseFloat(obj.Attributes.Style.BorderRadius.Value, 64) } if obj.Attributes.Style.FontColor != nil { diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 83f6faa6d..c50ee617b 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -216,10 +216,13 @@ func (s *Style) Apply(key, value string) error { if s.BorderRadius == nil { break } - f, err := strconv.Atoi(value) + f, err := strconv.ParseFloat(value, 64) if err != nil || (f < 0 || f > 20) { return errors.New(`expected "border-radius" to be a number between 0 and 20`) } + if hasDecimalValue := math.Mod(f, 1) != 0; f > 1 && hasDecimalValue { + return errors.New(`expected "border-radius" to be an integer if superior to 1`) + } s.BorderRadius.Value = value case "shadow": if s.Shadow == nil { diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 2846c7587..0f6c57905 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -987,7 +987,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske // DO rx := "" if targetShape.BorderRadius != 0 { - rx = fmt.Sprintf(` rx="%d"`, targetShape.BorderRadius) + rx = fmt.Sprintf(` rx="%s"`, d2themes.FormatRxRy(targetShape.BorderRadius)) } if targetShape.ThreeDee { fmt.Fprint(writer, render3dRect(targetShape)) @@ -1735,7 +1735,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { backgroundEl.Height = float64(h) backgroundEl.Fill = diagram.Root.Fill backgroundEl.Stroke = diagram.Root.Stroke - backgroundEl.Rx = float64(diagram.Root.BorderRadius) + backgroundEl.Rx = diagram.Root.BorderRadius if diagram.Root.StrokeDash != 0 { dashSize, gapSize := svg.GetStrokeDashAttributes(float64(diagram.Root.StrokeWidth), diagram.Root.StrokeDash) backgroundEl.StrokeDashArray = fmt.Sprintf("%f, %f", dashSize, gapSize) diff --git a/d2target/d2target.go b/d2target/d2target.go index 9d79eaa4c..a94e831f9 100644 --- a/d2target/d2target.go +++ b/d2target/d2target.go @@ -174,7 +174,7 @@ type Shape struct { StrokeDash float64 `json:"strokeDash"` StrokeWidth int `json:"strokeWidth"` - BorderRadius int `json:"borderRadius"` + BorderRadius float64 `json:"borderRadius"` Fill string `json:"fill"` Stroke string `json:"stroke"` diff --git a/d2themes/element.go b/d2themes/element.go index e881c0d78..b222187b5 100644 --- a/d2themes/element.go +++ b/d2themes/element.go @@ -135,10 +135,10 @@ func (el *ThemableElement) Render() string { out += fmt.Sprintf(` r="%f"`, el.R) } if el.Rx != math.MaxFloat64 { - out += fmt.Sprintf(` rx="%f"`, el.Rx) + out += fmt.Sprintf(` rx="%s"`, FormatRxRy(el.Rx)) } if el.Ry != math.MaxFloat64 { - out += fmt.Sprintf(` ry="%f"`, el.Ry) + out += fmt.Sprintf(` ry="%s"`, FormatRxRy(el.Ry)) } if el.Cx != math.MaxFloat64 { out += fmt.Sprintf(` cx="%f"`, el.Cx) @@ -206,3 +206,10 @@ func (el *ThemableElement) Render() string { } return out + " />" } + +func FormatRxRy(value float64) string { + if 0 < value && value < 1 { + return fmt.Sprintf(`%v%%`, int(value*100)) + } + return fmt.Sprintf(`%f`, value) +}