diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 489a520f2..4d0ab566d 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,5 +1,7 @@ #### Features ๐Ÿš€ +- `animated` keyword implemented for connections. [#652](https://github.com/terrastruct/d2/pull/652) + #### Improvements ๐Ÿงน - ELK layouts tuned to have better defaults. [#627](https://github.com/terrastruct/d2/pull/627) diff --git a/d2renderers/d2sketch/sketch.go b/d2renderers/d2sketch/sketch.go index 4c4913a2b..13beb9b97 100644 --- a/d2renderers/d2sketch/sketch.go +++ b/d2renderers/d2sketch/sketch.go @@ -63,26 +63,6 @@ func DefineFillPattern() string { `, fillPattern) } -func shapeStyle(shape d2target.Shape) string { - out := "" - - if shape.Type == d2target.ShapeSQLTable || shape.Type == d2target.ShapeClass { - out += fmt.Sprintf(`fill:%s;`, shape.Stroke) - out += fmt.Sprintf(`stroke:%s;`, shape.Fill) - } else { - out += fmt.Sprintf(`fill:%s;`, shape.Fill) - out += fmt.Sprintf(`stroke:%s;`, shape.Stroke) - } - out += fmt.Sprintf(`opacity:%f;`, shape.Opacity) - out += fmt.Sprintf(`stroke-width:%d;`, shape.StrokeWidth) - if shape.StrokeDash != 0 { - dashSize, gapSize := svg.GetStrokeDashAttributes(float64(shape.StrokeWidth), shape.StrokeDash) - out += fmt.Sprintf(`stroke-dasharray:%f,%f;`, dashSize, gapSize) - } - - return out -} - func Rect(r *Runner, shape d2target.Shape) (string, error) { js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, { fill: "%s", @@ -98,7 +78,7 @@ func Rect(r *Runner, shape d2target.Shape) (string, error) { for _, p := range paths { output += fmt.Sprintf( ``, - shape.Pos.X, shape.Pos.Y, p, shapeStyle(shape), + shape.Pos.X, shape.Pos.Y, p, shape.CSSStyle(), ) } output += fmt.Sprintf( @@ -123,7 +103,7 @@ func Oval(r *Runner, shape d2target.Shape) (string, error) { for _, p := range paths { output += fmt.Sprintf( ``, - shape.Pos.X, shape.Pos.Y, p, shapeStyle(shape), + shape.Pos.X, shape.Pos.Y, p, shape.CSSStyle(), ) } output += fmt.Sprintf( @@ -150,7 +130,7 @@ func Paths(r *Runner, shape d2target.Shape, paths []string) (string, error) { for _, p := range sketchPaths { output += fmt.Sprintf( ``, - p, shapeStyle(shape), + p, shape.CSSStyle(), ) } for _, p := range sketchPaths { @@ -163,20 +143,6 @@ func Paths(r *Runner, shape d2target.Shape, paths []string) (string, error) { return output, nil } -func connectionStyle(connection d2target.Connection) string { - out := "" - - out += fmt.Sprintf(`stroke:%s;`, connection.Stroke) - out += fmt.Sprintf(`opacity:%f;`, connection.Opacity) - out += fmt.Sprintf(`stroke-width:%d;`, connection.StrokeWidth) - if connection.StrokeDash != 0 { - dashSize, gapSize := svg.GetStrokeDashAttributes(float64(connection.StrokeWidth), connection.StrokeDash) - out += fmt.Sprintf(`stroke-dasharray:%f,%f;`, dashSize, gapSize) - } - - return out -} - func Connection(r *Runner, connection d2target.Connection, path, attrs string) (string, error) { roughness := 1.0 js := fmt.Sprintf(`node = rc.path("%s", {roughness: %f, seed: 1});`, path, roughness) @@ -185,10 +151,14 @@ func Connection(r *Runner, connection d2target.Connection, path, attrs string) ( return "", err } output := "" + animatedClass := "" + if connection.Animated { + animatedClass = " animated-connection" + } for _, p := range paths { output += fmt.Sprintf( - ``, - p, connectionStyle(connection), attrs, + ``, + animatedClass, p, connection.CSSStyle(), attrs, ) } return output, nil @@ -210,7 +180,7 @@ func Table(r *Runner, shape d2target.Shape) (string, error) { for _, p := range paths { output += fmt.Sprintf( ``, - shape.Pos.X, shape.Pos.Y, p, shapeStyle(shape), + shape.Pos.X, shape.Pos.Y, p, shape.CSSStyle(), ) } @@ -338,7 +308,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) { for _, p := range paths { output += fmt.Sprintf( ``, - shape.Pos.X, shape.Pos.Y, p, shapeStyle(shape), + shape.Pos.X, shape.Pos.Y, p, shape.CSSStyle(), ) } diff --git a/d2renderers/d2sketch/sketch_test.go b/d2renderers/d2sketch/sketch_test.go index c2b8dadea..f35eb1be7 100644 --- a/d2renderers/d2sketch/sketch_test.go +++ b/d2renderers/d2sketch/sketch_test.go @@ -39,6 +39,11 @@ func TestSketch(t *testing.T) { script: `winter.snow -> summer.sun `, }, + { + name: "animated", + script: `winter.snow -> summer.sun -> trees -> winter.snow: { style.animated: true } + `, + }, { name: "connection label", script: `a -> b: hello diff --git a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg new file mode 100644 index 000000000..25a6c8c99 --- /dev/null +++ b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg @@ -0,0 +1,77 @@ + + + + + + +wintersummertreessnowsun + + + \ No newline at end of file diff --git a/d2renderers/d2svg/class.go b/d2renderers/d2svg/class.go index 85205db32..200264054 100644 --- a/d2renderers/d2svg/class.go +++ b/d2renderers/d2svg/class.go @@ -80,7 +80,7 @@ func classRow(shape d2target.Shape, box *geo.Box, prefix, nameText, typeText str func drawClass(writer io.Writer, targetShape d2target.Shape) { fmt.Fprintf(writer, ``, - targetShape.Pos.X, targetShape.Pos.Y, targetShape.Width, targetShape.Height, shapeStyle(targetShape)) + targetShape.Pos.X, targetShape.Pos.Y, targetShape.Width, targetShape.Height, targetShape.CSSStyle()) box := geo.NewBox( geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y)), diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 2ff96d2eb..87bfff9a2 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -461,8 +461,12 @@ func drawConnection(writer io.Writer, labelMaskID string, connection d2target.Co } fmt.Fprintf(writer, out) } else { - fmt.Fprintf(writer, ``, - path, connectionStyle(connection), attrs) + animatedClass := "" + if connection.Animated { + animatedClass = " animated-connection" + } + fmt.Fprintf(writer, ``, + path, animatedClass, connection.CSSStyle(), attrs) } if connection.Label != "" { @@ -582,7 +586,7 @@ func render3dRect(targetShape d2target.Shape) string { ) border := targetShape border.Fill = "none" - borderStyle := shapeStyle(border) + borderStyle := border.CSSStyle() renderedBorder := fmt.Sprintf(``, strings.Join(borderSegments, " "), borderStyle) @@ -603,7 +607,7 @@ func render3dRect(targetShape d2target.Shape) string { mainShape := targetShape mainShape.Stroke = "none" mainRect := fmt.Sprintf(``, - targetShape.Pos.X, targetShape.Pos.Y, targetShape.Width, targetShape.Height, shapeStyle(mainShape), maskID, + targetShape.Pos.X, targetShape.Pos.Y, targetShape.Width, targetShape.Height, mainShape.CSSStyle(), maskID, ) // render the side shapes in the darkened color without stroke and the border mask @@ -628,7 +632,7 @@ func render3dRect(targetShape d2target.Shape) string { sideShape.Fill = darkerColor sideShape.Stroke = "none" renderedSides := fmt.Sprintf(``, - strings.Join(sidePoints, " "), shapeStyle(sideShape), maskID) + strings.Join(sidePoints, " "), sideShape.CSSStyle(), maskID) return borderMask + mainRect + renderedSides + renderedBorder } @@ -643,7 +647,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y)) width := float64(targetShape.Width) height := float64(targetShape.Height) - style := shapeStyle(targetShape) + style := targetShape.CSSStyle() shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[targetShape.Type] s := shape.NewShape(shapeType, geo.NewBox(tl, width, height)) @@ -939,43 +943,6 @@ func RenderText(text string, x, height float64) string { return strings.Join(rendered, "") } -func shapeStyle(shape d2target.Shape) string { - out := "" - - if shape.Type == d2target.ShapeSQLTable || shape.Type == d2target.ShapeClass { - // Fill is used for header fill in these types - // This fill property is just background of rows - out += fmt.Sprintf(`fill:%s;`, shape.Stroke) - // Stroke (border) of these shapes should match the header fill - out += fmt.Sprintf(`stroke:%s;`, shape.Fill) - } else { - out += fmt.Sprintf(`fill:%s;`, shape.Fill) - out += fmt.Sprintf(`stroke:%s;`, shape.Stroke) - } - out += fmt.Sprintf(`opacity:%f;`, shape.Opacity) - out += fmt.Sprintf(`stroke-width:%d;`, shape.StrokeWidth) - if shape.StrokeDash != 0 { - dashSize, gapSize := svg.GetStrokeDashAttributes(float64(shape.StrokeWidth), shape.StrokeDash) - out += fmt.Sprintf(`stroke-dasharray:%f,%f;`, dashSize, gapSize) - } - - return out -} - -func connectionStyle(connection d2target.Connection) string { - out := "" - - out += fmt.Sprintf(`stroke:%s;`, connection.Stroke) - out += fmt.Sprintf(`opacity:%f;`, connection.Opacity) - out += fmt.Sprintf(`stroke-width:%d;`, connection.StrokeWidth) - if connection.StrokeDash != 0 { - dashSize, gapSize := svg.GetStrokeDashAttributes(float64(connection.StrokeWidth), connection.StrokeDash) - out += fmt.Sprintf(`stroke-dasharray:%f,%f;`, dashSize, gapSize) - } - - return out -} - func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) { content := buf.String() buf.WriteString(`your love life will behappyharmoniousboredomimmortalityFridayMondayInsomniaSleepWakeDreamListenTalk hear + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/animated/elk/board.exp.json b/e2etests/testdata/stable/animated/elk/board.exp.json new file mode 100644 index 000000000..92badcbf0 --- /dev/null +++ b/e2etests/testdata/stable/animated/elk/board.exp.json @@ -0,0 +1,864 @@ +{ + "name": "", + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "your love life will be", + "type": "", + "pos": { + "x": 111, + "y": 12 + }, + "width": 247, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "your love life will be", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 147, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "happy", + "type": "", + "pos": { + "x": 12, + "y": 238 + }, + "width": 149, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "happy", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 49, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "harmonious", + "type": "", + "pos": { + "x": 181, + "y": 238 + }, + "width": 190, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "harmonious", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 90, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "boredom", + "type": "", + "pos": { + "x": 402, + "y": 12 + }, + "width": 168, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "boredom", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 68, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "immortality", + "type": "", + "pos": { + "x": 391, + "y": 238 + }, + "width": 191, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "immortality", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 91, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Friday", + "type": "", + "pos": { + "x": 607, + "y": 12 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Friday", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 50, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Monday", + "type": "", + "pos": { + "x": 602, + "y": 238 + }, + "width": 161, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Monday", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 61, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Insomnia", + "type": "", + "pos": { + "x": 935, + "y": 12 + }, + "width": 170, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Insomnia", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 70, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Sleep", + "type": "", + "pos": { + "x": 783, + "y": 238 + }, + "width": 145, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Sleep", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 45, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Wake", + "type": "", + "pos": { + "x": 948, + "y": 238 + }, + "width": 144, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Wake", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 44, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Dream", + "type": "", + "pos": { + "x": 1112, + "y": 238 + }, + "width": 151, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Dream", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Listen", + "type": "", + "pos": { + "x": 1225, + "y": 12 + }, + "width": 148, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Listen", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 48, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "Talk", + "type": "", + "pos": { + "x": 1231, + "y": 464 + }, + "width": 136, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Talk", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(your love life will be -> happy)[0]", + "src": "your love life will be", + "srcArrow": "none", + "srcLabel": "", + "dst": "happy", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 193.66666666666652, + "y": 138 + }, + { + "x": 193.66666666666652, + "y": 188 + }, + { + "x": 86.5, + "y": 188 + }, + { + "x": 86.5, + "y": 238 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(your love life will be -> harmonious)[0]", + "src": "your love life will be", + "srcArrow": "none", + "srcLabel": "", + "dst": "harmonious", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 275.9999999999999, + "y": 138 + }, + { + "x": 276, + "y": 238 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(boredom <- immortality)[0]", + "src": "boredom", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "immortality", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 486.5, + "y": 138 + }, + { + "x": 486.5, + "y": 238 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(Friday <-> Monday)[0]", + "src": "Friday", + "srcArrow": "triangle", + "srcLabel": "", + "dst": "Monday", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 682.5, + "y": 138 + }, + { + "x": 682.5, + "y": 238 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(Insomnia -- Sleep)[0]", + "src": "Insomnia", + "srcArrow": "none", + "srcLabel": "", + "dst": "Sleep", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 977.5, + "y": 138 + }, + { + "x": 977.5, + "y": 188 + }, + { + "x": 855.5, + "y": 188 + }, + { + "x": 855.5, + "y": 238 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(Insomnia -- Wake)[0]", + "src": "Insomnia", + "srcArrow": "none", + "srcLabel": "", + "dst": "Wake", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1020, + "y": 138 + }, + { + "x": 1020, + "y": 238 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(Insomnia -- Dream)[0]", + "src": "Insomnia", + "srcArrow": "none", + "srcLabel": "", + "dst": "Dream", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 8, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 1062.5, + "y": 138 + }, + { + "x": 1062.5, + "y": 188 + }, + { + "x": 1187.5, + "y": 188 + }, + { + "x": 1187.5, + "y": 238 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(Listen <-> Talk)[0]", + "src": "Listen", + "srcArrow": "cf-one", + "srcLabel": "", + "dst": "Talk", + "dstArrow": "diamond", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "hear", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 32, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 1299, + "y": 138 + }, + { + "x": 1299, + "y": 464 + } + ], + "animated": true, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] +} diff --git a/e2etests/testdata/stable/animated/elk/sketch.exp.svg b/e2etests/testdata/stable/animated/elk/sketch.exp.svg new file mode 100644 index 000000000..5d3c01de3 --- /dev/null +++ b/e2etests/testdata/stable/animated/elk/sketch.exp.svg @@ -0,0 +1,65 @@ + +your love life will behappyharmoniousboredomimmortalityFridayMondayInsomniaSleepWakeDreamListenTalk hear + + + \ No newline at end of file