fix sketch tests, better trigger system
|
|
@ -14,6 +14,7 @@ import (
|
||||||
tassert "github.com/stretchr/testify/assert"
|
tassert "github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"oss.terrastruct.com/util-go/assert"
|
"oss.terrastruct.com/util-go/assert"
|
||||||
|
"oss.terrastruct.com/util-go/diff"
|
||||||
"oss.terrastruct.com/util-go/go2"
|
"oss.terrastruct.com/util-go/go2"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
|
"oss.terrastruct.com/d2/d2layouts/d2dagrelayout"
|
||||||
|
|
@ -558,4 +559,7 @@ func run(t *testing.T, tc testCase) {
|
||||||
var xmlParsed interface{}
|
var xmlParsed interface{}
|
||||||
err = xml.Unmarshal(svgBytes, &xmlParsed)
|
err = xml.Unmarshal(svgBytes, &xmlParsed)
|
||||||
assert.Success(t, err)
|
assert.Success(t, err)
|
||||||
|
|
||||||
|
err = diff.Testdata(filepath.Join(dataPath, "sketch"), ".svg", svgBytes)
|
||||||
|
assert.Success(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
d2renderers/d2sketch/streaks.txt
Normal file
|
Before Width: | Height: | Size: 386 KiB After Width: | Height: | Size: 298 KiB |
|
Before Width: | Height: | Size: 305 KiB After Width: | Height: | Size: 284 KiB |
|
Before Width: | Height: | Size: 405 KiB After Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 241 KiB After Width: | Height: | Size: 228 KiB |
|
Before Width: | Height: | Size: 296 KiB After Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 241 KiB After Width: | Height: | Size: 227 KiB |
|
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 301 KiB After Width: | Height: | Size: 333 KiB |
|
Before Width: | Height: | Size: 357 KiB After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 513 KiB After Width: | Height: | Size: 419 KiB |
|
|
@ -16,7 +16,7 @@ func classHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex
|
||||||
rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y
|
rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y
|
||||||
rectEl.Width, rectEl.Height = box.Width, box.Height
|
rectEl.Width, rectEl.Height = box.Width, box.Height
|
||||||
rectEl.Fill = shape.Fill
|
rectEl.Fill = shape.Fill
|
||||||
rectEl.Class = "class_header"
|
rectEl.ClassName = "class_header"
|
||||||
str := rectEl.Render()
|
str := rectEl.Render()
|
||||||
|
|
||||||
if text != "" {
|
if text != "" {
|
||||||
|
|
@ -31,7 +31,7 @@ func classHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex
|
||||||
textEl.X = tl.X + textWidth/2
|
textEl.X = tl.X + textWidth/2
|
||||||
textEl.Y = tl.Y + textHeight*3/4
|
textEl.Y = tl.Y + textHeight*3/4
|
||||||
textEl.Fill = shape.Stroke
|
textEl.Fill = shape.Stroke
|
||||||
textEl.Class = "text-mono"
|
textEl.ClassName = "text-mono"
|
||||||
textEl.Style = fmt.Sprintf(`text-anchor:%s;font-size:%vpx;`,
|
textEl.Style = fmt.Sprintf(`text-anchor:%s;font-size:%vpx;`,
|
||||||
"middle", 4+fontSize,
|
"middle", 4+fontSize,
|
||||||
)
|
)
|
||||||
|
|
@ -61,7 +61,7 @@ func classRow(shape d2target.Shape, box *geo.Box, prefix, nameText, typeText str
|
||||||
textEl.X = prefixTL.X
|
textEl.X = prefixTL.X
|
||||||
textEl.Y = prefixTL.Y + fontSize*3/4
|
textEl.Y = prefixTL.Y + fontSize*3/4
|
||||||
textEl.Fill = shape.PrimaryAccentColor
|
textEl.Fill = shape.PrimaryAccentColor
|
||||||
textEl.Class = "text-mono"
|
textEl.ClassName = "text-mono"
|
||||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "start", fontSize)
|
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "start", fontSize)
|
||||||
textEl.Content = prefix
|
textEl.Content = prefix
|
||||||
out := textEl.Render()
|
out := textEl.Render()
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ func arrowheadMarkerID(isTarget bool, connection d2target.Connection) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("mk-%s", hash(fmt.Sprintf("%s,%t,%d,%s",
|
return fmt.Sprintf("mk-%s", hash(fmt.Sprintf("%s,%t,%d,%s",
|
||||||
arrowhead, isTarget, connection.StrokeWidth, d2themes.ConnectionTheme(connection),
|
arrowhead, isTarget, connection.StrokeWidth, connection.Stroke,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,8 +131,8 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
switch arrowhead {
|
switch arrowhead {
|
||||||
case d2target.ArrowArrowhead:
|
case d2target.ArrowArrowhead:
|
||||||
polygonEl := d2themes.NewThemableElement("polygon")
|
polygonEl := d2themes.NewThemableElement("polygon")
|
||||||
polygonEl.Fill = d2themes.ConnectionTheme(connection)
|
polygonEl.Fill = connection.Stroke
|
||||||
polygonEl.Class = "connection"
|
polygonEl.ClassName = "connection"
|
||||||
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
|
|
||||||
if isTarget {
|
if isTarget {
|
||||||
|
|
@ -153,8 +153,8 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
path = polygonEl.Render()
|
path = polygonEl.Render()
|
||||||
case d2target.TriangleArrowhead:
|
case d2target.TriangleArrowhead:
|
||||||
polygonEl := d2themes.NewThemableElement("polygon")
|
polygonEl := d2themes.NewThemableElement("polygon")
|
||||||
polygonEl.Fill = d2themes.ConnectionTheme(connection)
|
polygonEl.Fill = connection.Stroke
|
||||||
polygonEl.Class = "connection"
|
polygonEl.ClassName = "connection"
|
||||||
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
|
|
||||||
if isTarget {
|
if isTarget {
|
||||||
|
|
@ -174,8 +174,8 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
case d2target.LineArrowhead:
|
case d2target.LineArrowhead:
|
||||||
polylineEl := d2themes.NewThemableElement("polyline")
|
polylineEl := d2themes.NewThemableElement("polyline")
|
||||||
polylineEl.Fill = color.None
|
polylineEl.Fill = color.None
|
||||||
polylineEl.Class = "connection"
|
polylineEl.ClassName = "connection"
|
||||||
polylineEl.Stroke = d2themes.ConnectionTheme(connection)
|
polylineEl.Stroke = connection.Stroke
|
||||||
polylineEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
polylineEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
|
|
||||||
if isTarget {
|
if isTarget {
|
||||||
|
|
@ -194,8 +194,8 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
path = polylineEl.Render()
|
path = polylineEl.Render()
|
||||||
case d2target.FilledDiamondArrowhead:
|
case d2target.FilledDiamondArrowhead:
|
||||||
polygonEl := d2themes.NewThemableElement("polygon")
|
polygonEl := d2themes.NewThemableElement("polygon")
|
||||||
polygonEl.Class = "connection"
|
polygonEl.ClassName = "connection"
|
||||||
polygonEl.Fill = d2themes.ConnectionTheme(connection)
|
polygonEl.Fill = connection.Stroke
|
||||||
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
|
|
||||||
if isTarget {
|
if isTarget {
|
||||||
|
|
@ -216,9 +216,9 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
path = polygonEl.Render()
|
path = polygonEl.Render()
|
||||||
case d2target.DiamondArrowhead:
|
case d2target.DiamondArrowhead:
|
||||||
polygonEl := d2themes.NewThemableElement("polygon")
|
polygonEl := d2themes.NewThemableElement("polygon")
|
||||||
polygonEl.Class = "connection"
|
polygonEl.ClassName = "connection"
|
||||||
polygonEl.Fill = bgColor
|
polygonEl.Fill = bgColor
|
||||||
polygonEl.Stroke = d2themes.ConnectionTheme(connection)
|
polygonEl.Stroke = connection.Stroke
|
||||||
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
|
|
||||||
if isTarget {
|
if isTarget {
|
||||||
|
|
@ -244,7 +244,7 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
circleEl.Cy = radius
|
circleEl.Cy = radius
|
||||||
circleEl.R = radius - strokeWidth/2 // @alixander says there maybe should be a plus sign instead
|
circleEl.R = radius - strokeWidth/2 // @alixander says there maybe should be a plus sign instead
|
||||||
circleEl.Fill = connection.Stroke
|
circleEl.Fill = connection.Stroke
|
||||||
circleEl.Class = "connection"
|
circleEl.ClassName = "connection"
|
||||||
circleEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
circleEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
|
|
||||||
if isTarget {
|
if isTarget {
|
||||||
|
|
@ -282,8 +282,8 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
offset, height,
|
offset, height,
|
||||||
)
|
)
|
||||||
modifierEl.Fill = bgColor
|
modifierEl.Fill = bgColor
|
||||||
modifierEl.Stroke = d2themes.ConnectionTheme(connection)
|
modifierEl.Stroke = connection.Stroke
|
||||||
modifierEl.Class = "connection"
|
modifierEl.ClassName = "connection"
|
||||||
modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
} else {
|
} else {
|
||||||
modifierEl = d2themes.NewThemableElement("circle")
|
modifierEl = d2themes.NewThemableElement("circle")
|
||||||
|
|
@ -291,8 +291,8 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
modifierEl.Cy = height / 2.0
|
modifierEl.Cy = height / 2.0
|
||||||
modifierEl.R = offset / 2.0
|
modifierEl.R = offset / 2.0
|
||||||
modifierEl.Fill = bgColor
|
modifierEl.Fill = bgColor
|
||||||
modifierEl.Stroke = d2themes.ConnectionTheme(connection)
|
modifierEl.Stroke = connection.Stroke
|
||||||
modifierEl.Class = "connection"
|
modifierEl.ClassName = "connection"
|
||||||
modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,8 +320,8 @@ func arrowheadMarker(isTarget bool, id string, bgColor string, connection d2targ
|
||||||
gEl.Transform = fmt.Sprintf("scale(-1) translate(-%f, -%f)", width, height)
|
gEl.Transform = fmt.Sprintf("scale(-1) translate(-%f, -%f)", width, height)
|
||||||
}
|
}
|
||||||
gEl.Fill = bgColor
|
gEl.Fill = bgColor
|
||||||
gEl.Stroke = d2themes.ConnectionTheme(connection)
|
gEl.Stroke = connection.Stroke
|
||||||
gEl.Class = "connection"
|
gEl.ClassName = "connection"
|
||||||
gEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
gEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth)
|
||||||
gEl.Content = fmt.Sprintf("%s%s",
|
gEl.Content = fmt.Sprintf("%s%s",
|
||||||
modifierEl.Render(), childPathEl.Render(),
|
modifierEl.Render(), childPathEl.Render(),
|
||||||
|
|
@ -545,8 +545,8 @@ func drawConnection(writer io.Writer, bgColor string, fgColor string, labelMaskI
|
||||||
pathEl := d2themes.NewThemableElement("path")
|
pathEl := d2themes.NewThemableElement("path")
|
||||||
pathEl.D = path
|
pathEl.D = path
|
||||||
pathEl.Fill = color.None
|
pathEl.Fill = color.None
|
||||||
pathEl.Stroke = d2themes.ConnectionTheme(connection)
|
pathEl.Stroke = connection.Stroke
|
||||||
pathEl.Class = fmt.Sprintf("connection%s", animatedClass)
|
pathEl.ClassName = fmt.Sprintf("connection%s", animatedClass)
|
||||||
pathEl.Style = connection.CSSStyle()
|
pathEl.Style = connection.CSSStyle()
|
||||||
pathEl.Attributes = fmt.Sprintf("%s%s%s", markerStart, markerEnd, mask)
|
pathEl.Attributes = fmt.Sprintf("%s%s%s", markerStart, markerEnd, mask)
|
||||||
fmt.Fprint(writer, pathEl.Render())
|
fmt.Fprint(writer, pathEl.Render())
|
||||||
|
|
@ -576,7 +576,7 @@ func drawConnection(writer io.Writer, bgColor string, fgColor string, labelMaskI
|
||||||
textEl.X = labelTL.X + float64(connection.LabelWidth)/2
|
textEl.X = labelTL.X + float64(connection.LabelWidth)/2
|
||||||
textEl.Y = labelTL.Y + float64(connection.FontSize)
|
textEl.Y = labelTL.Y + float64(connection.FontSize)
|
||||||
textEl.Fill = fontColor
|
textEl.Fill = fontColor
|
||||||
textEl.Class = fontClass
|
textEl.ClassName = fontClass
|
||||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", connection.FontSize)
|
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", connection.FontSize)
|
||||||
textEl.Content = RenderText(connection.Label, textEl.X, float64(connection.LabelHeight))
|
textEl.Content = RenderText(connection.Label, textEl.X, float64(connection.LabelHeight))
|
||||||
fmt.Fprint(writer, textEl.Render())
|
fmt.Fprint(writer, textEl.Render())
|
||||||
|
|
@ -612,7 +612,7 @@ func renderArrowheadLabel(fgColor string, connection d2target.Connection, text s
|
||||||
textEl.X = labelTL.X + width/2
|
textEl.X = labelTL.X + width/2
|
||||||
textEl.Y = labelTL.Y + float64(connection.FontSize)
|
textEl.Y = labelTL.Y + float64(connection.FontSize)
|
||||||
textEl.Fill = fgColor
|
textEl.Fill = fgColor
|
||||||
textEl.Class = "text-italic"
|
textEl.ClassName = "text-italic"
|
||||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", connection.FontSize)
|
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", connection.FontSize)
|
||||||
textEl.Content = RenderText(text, textEl.X, height)
|
textEl.Content = RenderText(text, textEl.X, height)
|
||||||
return textEl.Render()
|
return textEl.Render()
|
||||||
|
|
@ -625,7 +625,7 @@ func renderOval(tl *geo.Point, width, height float64, fill, stroke, style string
|
||||||
el.Cx = tl.X + el.Rx
|
el.Cx = tl.X + el.Rx
|
||||||
el.Cy = tl.Y + el.Ry
|
el.Cy = tl.Y + el.Ry
|
||||||
el.Fill, el.Stroke = fill, stroke
|
el.Fill, el.Stroke = fill, stroke
|
||||||
el.Class = "shape"
|
el.ClassName = "shape"
|
||||||
el.Style = style
|
el.Style = style
|
||||||
return el.Render()
|
return el.Render()
|
||||||
}
|
}
|
||||||
|
|
@ -707,7 +707,7 @@ func render3dRect(targetShape d2target.Shape) string {
|
||||||
mainShape.Y = float64(targetShape.Pos.Y)
|
mainShape.Y = float64(targetShape.Pos.Y)
|
||||||
mainShape.Width = float64(targetShape.Width)
|
mainShape.Width = float64(targetShape.Width)
|
||||||
mainShape.Height = float64(targetShape.Height)
|
mainShape.Height = float64(targetShape.Height)
|
||||||
mainShape.Mask = fmt.Sprintf("url(#%s)", maskID)
|
mainShape.SetMaskUrl(maskID)
|
||||||
mainShapeFill, _ := d2themes.ShapeTheme(targetShape)
|
mainShapeFill, _ := d2themes.ShapeTheme(targetShape)
|
||||||
mainShape.Fill = mainShapeFill
|
mainShape.Fill = mainShapeFill
|
||||||
mainShape.Stroke = color.None
|
mainShape.Stroke = color.None
|
||||||
|
|
@ -736,7 +736,7 @@ func render3dRect(targetShape d2target.Shape) string {
|
||||||
sideShape := d2themes.NewThemableElement("polygon")
|
sideShape := d2themes.NewThemableElement("polygon")
|
||||||
sideShape.Fill = darkerColor
|
sideShape.Fill = darkerColor
|
||||||
sideShape.Points = strings.Join(sidePoints, " ")
|
sideShape.Points = strings.Join(sidePoints, " ")
|
||||||
sideShape.Mask = fmt.Sprintf("url(#%s)", maskID)
|
sideShape.SetMaskUrl(maskID)
|
||||||
sideShape.Style = targetShape.CSSStyle()
|
sideShape.Style = targetShape.CSSStyle()
|
||||||
renderedSides := sideShape.Render()
|
renderedSides := sideShape.Render()
|
||||||
|
|
||||||
|
|
@ -1062,7 +1062,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
|
||||||
rectEl.Width = float64(targetShape.Width)
|
rectEl.Width = float64(targetShape.Width)
|
||||||
rectEl.Height = float64(targetShape.Height)
|
rectEl.Height = float64(targetShape.Height)
|
||||||
rectEl.Stroke = targetShape.Stroke
|
rectEl.Stroke = targetShape.Stroke
|
||||||
rectEl.Class = "shape"
|
rectEl.ClassName = "shape"
|
||||||
rectEl.Style = fmt.Sprintf(`fill:%s`, style.Get(chroma.Background).Background.String())
|
rectEl.Style = fmt.Sprintf(`fill:%s`, style.Get(chroma.Background).Background.String())
|
||||||
fmt.Fprint(writer, rectEl.Render())
|
fmt.Fprint(writer, rectEl.Render())
|
||||||
// Padding
|
// Padding
|
||||||
|
|
@ -1105,7 +1105,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
|
||||||
|
|
||||||
mdEl := d2themes.NewThemableElement("div")
|
mdEl := d2themes.NewThemableElement("div")
|
||||||
mdEl.Xmlns = "http://www.w3.org/1999/xhtml"
|
mdEl.Xmlns = "http://www.w3.org/1999/xhtml"
|
||||||
mdEl.Class = "md"
|
mdEl.ClassName = "md"
|
||||||
mdEl.Content = render
|
mdEl.Content = render
|
||||||
fmt.Fprint(writer, mdEl.Render())
|
fmt.Fprint(writer, mdEl.Render())
|
||||||
fmt.Fprint(writer, `</foreignObject></g>`)
|
fmt.Fprint(writer, `</foreignObject></g>`)
|
||||||
|
|
@ -1128,7 +1128,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
|
||||||
// text is vertically positioned at its baseline which is at labelTL+FontSize
|
// text is vertically positioned at its baseline which is at labelTL+FontSize
|
||||||
textEl.Y = labelTL.Y + float64(targetShape.FontSize)
|
textEl.Y = labelTL.Y + float64(targetShape.FontSize)
|
||||||
textEl.Fill = fontColor
|
textEl.Fill = fontColor
|
||||||
textEl.Class = fontClass
|
textEl.ClassName = fontClass
|
||||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", targetShape.FontSize)
|
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", targetShape.FontSize)
|
||||||
textEl.Content = RenderText(targetShape.Label, textEl.X, float64(targetShape.LabelHeight))
|
textEl.Content = RenderText(targetShape.Label, textEl.X, float64(targetShape.LabelHeight))
|
||||||
fmt.Fprint(writer, textEl.Render())
|
fmt.Fprint(writer, textEl.Render())
|
||||||
|
|
@ -1186,19 +1186,18 @@ func RenderText(text string, x, height float64) string {
|
||||||
return strings.Join(rendered, "")
|
return strings.Join(rendered, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
func embedFonts(buf *bytes.Buffer, source string, fontFamily *d2fonts.FontFamily) {
|
||||||
content := buf.String()
|
fmt.Fprint(buf, `<style type="text/css"><![CDATA[`)
|
||||||
out := `<style type="text/css"><![CDATA[`
|
|
||||||
|
|
||||||
triggers := []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text"`,
|
`class="text"`,
|
||||||
`class="text `,
|
`class="text `,
|
||||||
`class="md"`,
|
`class="md"`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += fmt.Sprintf(`
|
|
||||||
.text {
|
.text {
|
||||||
font-family: "font-regular";
|
font-family: "font-regular";
|
||||||
}
|
}
|
||||||
|
|
@ -1206,65 +1205,58 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-regular;
|
font-family: font-regular;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[fontFamily.Font(0, d2fonts.FONT_STYLE_REGULAR)])
|
d2fonts.FontEncodings[fontFamily.Font(0, d2fonts.FONT_STYLE_REGULAR)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`text-underline`,
|
`text-underline`,
|
||||||
}
|
},
|
||||||
|
`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += `
|
|
||||||
.text-underline {
|
.text-underline {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}`
|
}`,
|
||||||
break
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`animated-connection`,
|
`animated-connection`,
|
||||||
}
|
},
|
||||||
|
`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += `
|
|
||||||
@keyframes dashdraw {
|
@keyframes dashdraw {
|
||||||
from {
|
from {
|
||||||
stroke-dashoffset: 0;
|
stroke-dashoffset: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`,
|
||||||
break
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`appendix-icon`,
|
`appendix-icon`,
|
||||||
}
|
},
|
||||||
|
`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += `
|
|
||||||
.appendix-icon {
|
.appendix-icon {
|
||||||
filter: drop-shadow(0px 0px 32px rgba(31, 36, 58, 0.1));
|
filter: drop-shadow(0px 0px 32px rgba(31, 36, 58, 0.1));
|
||||||
}`
|
}`,
|
||||||
break
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text-bold`,
|
`class="text-bold`,
|
||||||
`<b>`,
|
`<b>`,
|
||||||
`<strong>`,
|
`<strong>`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += fmt.Sprintf(`
|
|
||||||
.text-bold {
|
.text-bold {
|
||||||
font-family: "font-bold";
|
font-family: "font-bold";
|
||||||
}
|
}
|
||||||
|
|
@ -1272,20 +1264,19 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-bold;
|
font-family: font-bold;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[fontFamily.Font(0, d2fonts.FONT_STYLE_BOLD)])
|
d2fonts.FontEncodings[fontFamily.Font(0, d2fonts.FONT_STYLE_BOLD)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text-italic`,
|
`class="text-italic`,
|
||||||
`<em>`,
|
`<em>`,
|
||||||
`<dfn>`,
|
`<dfn>`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += fmt.Sprintf(`
|
|
||||||
.text-italic {
|
.text-italic {
|
||||||
font-family: "font-italic";
|
font-family: "font-italic";
|
||||||
}
|
}
|
||||||
|
|
@ -1293,22 +1284,21 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-italic;
|
font-family: font-italic;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[fontFamily.Font(0, d2fonts.FONT_STYLE_ITALIC)])
|
d2fonts.FontEncodings[fontFamily.Font(0, d2fonts.FONT_STYLE_ITALIC)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text-mono`,
|
`class="text-mono`,
|
||||||
`<pre>`,
|
`<pre>`,
|
||||||
`<code>`,
|
`<code>`,
|
||||||
`<kbd>`,
|
`<kbd>`,
|
||||||
`<samp>`,
|
`<samp>`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += fmt.Sprintf(`
|
|
||||||
.text-mono {
|
.text-mono {
|
||||||
font-family: "font-mono";
|
font-family: "font-mono";
|
||||||
}
|
}
|
||||||
|
|
@ -1316,18 +1306,17 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-mono;
|
font-family: font-mono;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_REGULAR)])
|
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_REGULAR)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text-mono-bold"`,
|
`class="text-mono-bold"`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
fmt.Fprintf(buf, `
|
|
||||||
.text-mono-bold {
|
.text-mono-bold {
|
||||||
font-family: "font-mono-bold";
|
font-family: "font-mono-bold";
|
||||||
}
|
}
|
||||||
|
|
@ -1335,18 +1324,17 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-mono-bold;
|
font-family: font-mono-bold;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_BOLD)])
|
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_BOLD)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text-mono-italic"`,
|
`class="text-mono-italic"`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
fmt.Fprintf(buf, `
|
|
||||||
.text-mono-italic {
|
.text-mono-italic {
|
||||||
font-family: "font-mono-italic";
|
font-family: "font-mono-italic";
|
||||||
}
|
}
|
||||||
|
|
@ -1354,18 +1342,17 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-mono-italic;
|
font-family: font-mono-italic;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_ITALIC)])
|
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_ITALIC)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text-mono-bold"`,
|
`class="text-mono-bold"`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
fmt.Fprintf(buf, `
|
|
||||||
.text-mono-bold {
|
.text-mono-bold {
|
||||||
font-family: "font-mono-bold";
|
font-family: "font-mono-bold";
|
||||||
}
|
}
|
||||||
|
|
@ -1373,18 +1360,17 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-mono-bold;
|
font-family: font-mono-bold;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_BOLD)])
|
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_BOLD)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`class="text-mono-italic"`,
|
`class="text-mono-italic"`,
|
||||||
}
|
},
|
||||||
|
fmt.Sprintf(`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
fmt.Fprintf(buf, `
|
|
||||||
.text-mono-italic {
|
.text-mono-italic {
|
||||||
font-family: "font-mono-italic";
|
font-family: "font-mono-italic";
|
||||||
}
|
}
|
||||||
|
|
@ -1392,73 +1378,72 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) string {
|
||||||
font-family: font-mono-italic;
|
font-family: font-mono-italic;
|
||||||
src: url("%s");
|
src: url("%s");
|
||||||
}`,
|
}`,
|
||||||
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_ITALIC)])
|
d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_ITALIC)],
|
||||||
break
|
),
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`sketch-overlay-bright`,
|
`sketch-overlay-bright`,
|
||||||
}
|
},
|
||||||
|
`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += `
|
|
||||||
.sketch-overlay-bright {
|
.sketch-overlay-bright {
|
||||||
fill: url(#streaks-bright);
|
fill: url(#streaks-bright);
|
||||||
mix-blend-mode: darken;
|
mix-blend-mode: darken;
|
||||||
}`
|
}`,
|
||||||
break
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`sketch-overlay-normal`,
|
`sketch-overlay-normal`,
|
||||||
}
|
},
|
||||||
|
`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += `
|
|
||||||
.sketch-overlay-normal {
|
.sketch-overlay-normal {
|
||||||
fill: url(#streaks-normal);
|
fill: url(#streaks-normal);
|
||||||
mix-blend-mode: color-burn;
|
mix-blend-mode: color-burn;
|
||||||
}`
|
}`,
|
||||||
break
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`sketch-overlay-dark`,
|
`sketch-overlay-dark`,
|
||||||
}
|
},
|
||||||
|
`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += `
|
|
||||||
.sketch-overlay-dark {
|
.sketch-overlay-dark {
|
||||||
fill: url(#streaks-dark);
|
fill: url(#streaks-dark);
|
||||||
mix-blend-mode: overlay;
|
mix-blend-mode: overlay;
|
||||||
}`
|
}`,
|
||||||
break
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
triggers = []string{
|
appendOnTrigger(
|
||||||
|
buf,
|
||||||
|
source,
|
||||||
|
[]string{
|
||||||
`sketch-overlay-darker`,
|
`sketch-overlay-darker`,
|
||||||
}
|
},
|
||||||
|
`
|
||||||
for _, t := range triggers {
|
|
||||||
if strings.Contains(content, t) {
|
|
||||||
out += `
|
|
||||||
.sketch-overlay-darker {
|
.sketch-overlay-darker {
|
||||||
fill: url(#streaks-darker);
|
fill: url(#streaks-darker);
|
||||||
mix-blend-mode: lighten;
|
mix-blend-mode: lighten;
|
||||||
}`
|
}`,
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Fprint(buf, `]]></style>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendOnTrigger(buf *bytes.Buffer, source string, triggers []string, newContent string) {
|
||||||
|
for _, trigger := range triggers {
|
||||||
|
if strings.Contains(source, trigger) {
|
||||||
|
fmt.Fprint(buf, newContent)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out += `]]></style>`
|
|
||||||
return out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:embed fitToScreen.js
|
//go:embed fitToScreen.js
|
||||||
|
|
@ -1568,14 +1553,15 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
backgroundEl.Fill = color.N7
|
backgroundEl.Fill = color.N7
|
||||||
|
|
||||||
// generate elements that will be appended to the SVG tag
|
// generate elements that will be appended to the SVG tag
|
||||||
|
upperBuf := &bytes.Buffer{}
|
||||||
themeStylesheet, err := themeCSS(themeID, darkThemeID)
|
themeStylesheet, err := themeCSS(themeID, darkThemeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
svgOut := fmt.Sprintf(`<style type="text/css"><![CDATA[%s%s]]></style>`, baseStylesheet, themeStylesheet)
|
fmt.Fprintf(upperBuf, `<style type="text/css"><![CDATA[%s%s]]></style>`, baseStylesheet, themeStylesheet)
|
||||||
// this script won't run in --watch mode because script tags are ignored when added via el.innerHTML = element
|
// this script won't run in --watch mode because script tags are ignored when added via el.innerHTML = element
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
|
// https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
|
||||||
svgOut += fmt.Sprintf(`<script type="application/javascript"><![CDATA[%s]]></script>`, fitToScreenScript)
|
fmt.Fprintf(upperBuf, `<script type="application/javascript"><![CDATA[%s]]></script>`, fitToScreenScript)
|
||||||
hasMarkdown := false
|
hasMarkdown := false
|
||||||
for _, s := range diagram.Shapes {
|
for _, s := range diagram.Shapes {
|
||||||
if s.Label != "" && s.Type == d2target.ShapeText {
|
if s.Label != "" && s.Type == d2target.ShapeText {
|
||||||
|
|
@ -1584,17 +1570,16 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hasMarkdown {
|
if hasMarkdown {
|
||||||
svgOut += fmt.Sprintf(`<style type="text/css">%s</style>`, mdCSS)
|
fmt.Fprintf(upperBuf, `<style type="text/css">%s</style>`, mdCSS)
|
||||||
}
|
}
|
||||||
|
embedFonts(upperBuf, buf.String(), diagram.FontFamily) // embedFonts *must* run before d2sketch.DefineFillPatterns
|
||||||
if sketchRunner != nil {
|
if sketchRunner != nil {
|
||||||
svgOut += d2sketch.DefineFillPatterns()
|
d2sketch.DefineFillPatterns(upperBuf)
|
||||||
}
|
}
|
||||||
svgOut += embedFonts(buf, diagram.FontFamily)
|
|
||||||
|
|
||||||
// render the document
|
|
||||||
docRendered := fmt.Sprintf(`<?xml version="1.0" encoding="utf-8"?><svg id="d2-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="%d" height="%d" viewBox="%d %d %d %d">%s%s%s</svg>`,
|
docRendered := fmt.Sprintf(`<?xml version="1.0" encoding="utf-8"?><svg id="d2-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="%d" height="%d" viewBox="%d %d %d %d">%s%s%s</svg>`,
|
||||||
w, h, left, top, w, h,
|
w, h, left, top, w, h,
|
||||||
svgOut,
|
upperBuf.String(),
|
||||||
backgroundEl.Render(),
|
backgroundEl.Render(),
|
||||||
buf.String(),
|
buf.String(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ func tableHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex
|
||||||
rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y
|
rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y
|
||||||
rectEl.Width, rectEl.Height = box.Width, box.Height
|
rectEl.Width, rectEl.Height = box.Width, box.Height
|
||||||
rectEl.Fill = shape.Fill
|
rectEl.Fill = shape.Fill
|
||||||
rectEl.Class = "class_header"
|
rectEl.ClassName = "class_header"
|
||||||
str := rectEl.Render()
|
str := rectEl.Render()
|
||||||
|
|
||||||
if text != "" {
|
if text != "" {
|
||||||
|
|
@ -32,7 +32,7 @@ func tableHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex
|
||||||
textEl.X = tl.X
|
textEl.X = tl.X
|
||||||
textEl.Y = tl.Y + textHeight*3/4
|
textEl.Y = tl.Y + textHeight*3/4
|
||||||
textEl.Fill = shape.Stroke
|
textEl.Fill = shape.Stroke
|
||||||
textEl.Class = "text"
|
textEl.ClassName = "text"
|
||||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx",
|
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx",
|
||||||
"start", 4+fontSize,
|
"start", 4+fontSize,
|
||||||
)
|
)
|
||||||
|
|
@ -62,7 +62,7 @@ func tableRow(shape d2target.Shape, box *geo.Box, nameText, typeText, constraint
|
||||||
textEl.X = nameTL.X
|
textEl.X = nameTL.X
|
||||||
textEl.Y = nameTL.Y + fontSize*3/4
|
textEl.Y = nameTL.Y + fontSize*3/4
|
||||||
textEl.Fill = shape.PrimaryAccentColor
|
textEl.Fill = shape.PrimaryAccentColor
|
||||||
textEl.Class = "text"
|
textEl.ClassName = "text"
|
||||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "start", fontSize)
|
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "start", fontSize)
|
||||||
textEl.Content = svg.EscapeText(nameText)
|
textEl.Content = svg.EscapeText(nameText)
|
||||||
out := textEl.Render()
|
out := textEl.Render()
|
||||||
|
|
@ -89,7 +89,7 @@ func drawTable(writer io.Writer, targetShape d2target.Shape) {
|
||||||
rectEl.Width = float64(targetShape.Width)
|
rectEl.Width = float64(targetShape.Width)
|
||||||
rectEl.Height = float64(targetShape.Height)
|
rectEl.Height = float64(targetShape.Height)
|
||||||
rectEl.Fill, rectEl.Stroke = d2themes.ShapeTheme(targetShape)
|
rectEl.Fill, rectEl.Stroke = d2themes.ShapeTheme(targetShape)
|
||||||
rectEl.Class = "shape"
|
rectEl.ClassName = "shape"
|
||||||
rectEl.Style = targetShape.CSSStyle()
|
rectEl.Style = targetShape.CSSStyle()
|
||||||
fmt.Fprint(writer, rectEl.Render())
|
fmt.Fprint(writer, rectEl.Render())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,3 @@ func ShapeTheme(shape d2target.Shape) (fill, stroke string) {
|
||||||
}
|
}
|
||||||
return fill, stroke
|
return fill, stroke
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConnectionTheme(connection d2target.Connection) (stroke string) {
|
|
||||||
return connection.Stroke
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ type ThemableElement struct {
|
||||||
BackgroundColor string
|
BackgroundColor string
|
||||||
Color string
|
Color string
|
||||||
|
|
||||||
Class string
|
ClassName string
|
||||||
Style string
|
Style string
|
||||||
Attributes string
|
Attributes string
|
||||||
|
|
||||||
|
|
@ -84,6 +84,10 @@ func (el *ThemableElement) SetTranslate(x, y float64) {
|
||||||
el.Transform = fmt.Sprintf("translate(%f %f)", x, y)
|
el.Transform = fmt.Sprintf("translate(%f %f)", x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (el *ThemableElement) SetMaskUrl(url string) {
|
||||||
|
el.Mask = fmt.Sprintf("url(#%s)", url)
|
||||||
|
}
|
||||||
|
|
||||||
func (el *ThemableElement) Render() string {
|
func (el *ThemableElement) Render() string {
|
||||||
out := "<" + el.tag
|
out := "<" + el.tag
|
||||||
|
|
||||||
|
|
@ -146,7 +150,7 @@ func (el *ThemableElement) Render() string {
|
||||||
out += fmt.Sprintf(` xmlns="%s"`, el.Xmlns)
|
out += fmt.Sprintf(` xmlns="%s"`, el.Xmlns)
|
||||||
}
|
}
|
||||||
|
|
||||||
class := el.Class
|
class := el.ClassName
|
||||||
style := el.Style
|
style := el.Style
|
||||||
|
|
||||||
// Add class {property}-{theme color} if the color is from a theme, set the property otherwise
|
// Add class {property}-{theme color} if the color is from a theme, set the property otherwise
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ func NewThemableSketchOverlay(el *ThemableElement, fill string) *ThemableSketchO
|
||||||
// WARNING: Do not reuse the element afterwards as this function changes the Class propery
|
// WARNING: Do not reuse the element afterwards as this function changes the Class propery
|
||||||
func (o *ThemableSketchOverlay) Render() (string, error) {
|
func (o *ThemableSketchOverlay) Render() (string, error) {
|
||||||
if color.IsThemeColor(o.fill) {
|
if color.IsThemeColor(o.fill) {
|
||||||
o.el.Class += fmt.Sprintf(" sketch-overlay-%s", o.fill) // e.g. sketch-overlay-B3
|
o.el.ClassName += fmt.Sprintf(" sketch-overlay-%s", o.fill) // e.g. sketch-overlay-B3
|
||||||
} else {
|
} else {
|
||||||
lc, err := color.LuminanceCategory(o.fill)
|
lc, err := color.LuminanceCategory(o.fill)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
o.el.Class += fmt.Sprintf(" sketch-overlay-%s", lc) // e.g. sketch-overlay-dark
|
o.el.ClassName += fmt.Sprintf(" sketch-overlay-%s", lc) // e.g. sketch-overlay-dark
|
||||||
}
|
}
|
||||||
|
|
||||||
return o.el.Render(), nil
|
return o.el.Render(), nil
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 519 KiB After Width: | Height: | Size: 519 KiB |
|
Before Width: | Height: | Size: 519 KiB After Width: | Height: | Size: 519 KiB |
|
Before Width: | Height: | Size: 694 KiB After Width: | Height: | Size: 694 KiB |
|
Before Width: | Height: | Size: 694 KiB After Width: | Height: | Size: 694 KiB |
|
Before Width: | Height: | Size: 842 KiB After Width: | Height: | Size: 842 KiB |
|
Before Width: | Height: | Size: 842 KiB After Width: | Height: | Size: 842 KiB |
|
Before Width: | Height: | Size: 849 KiB After Width: | Height: | Size: 849 KiB |
|
Before Width: | Height: | Size: 849 KiB After Width: | Height: | Size: 849 KiB |
|
Before Width: | Height: | Size: 695 KiB After Width: | Height: | Size: 695 KiB |
|
Before Width: | Height: | Size: 694 KiB After Width: | Height: | Size: 694 KiB |
|
Before Width: | Height: | Size: 694 KiB After Width: | Height: | Size: 695 KiB |
|
Before Width: | Height: | Size: 694 KiB After Width: | Height: | Size: 694 KiB |
|
Before Width: | Height: | Size: 1 MiB After Width: | Height: | Size: 1 MiB |
|
Before Width: | Height: | Size: 1 MiB After Width: | Height: | Size: 1 MiB |