Added the possibilty to not only make quadratic items
This commit is contained in:
@@ -1,41 +1,77 @@
|
||||
package svgtemplate
|
||||
|
||||
import "math"
|
||||
|
||||
// Data holds dynamic values for the SVG mask template.
|
||||
type Data struct {
|
||||
Size float64
|
||||
Bleed float64
|
||||
Margin float64
|
||||
Padding float64
|
||||
ViewBoxMin float64
|
||||
ViewBoxSize float64
|
||||
MaskSize float64
|
||||
OuterSize float64
|
||||
OuterOffset float64
|
||||
InnerSize float64
|
||||
InnerOffset float64
|
||||
MarkLength float64
|
||||
Width, Height float64
|
||||
CornerRadius float64
|
||||
Bleed float64
|
||||
Margin float64
|
||||
Padding float64
|
||||
ViewBoxMin float64
|
||||
ViewBoxWidth float64
|
||||
ViewBoxHeight float64
|
||||
MaskWidth float64
|
||||
MaskHeight float64
|
||||
OuterWidth float64
|
||||
OuterHeight float64
|
||||
OuterOffsetX float64
|
||||
OuterOffsetY float64
|
||||
InnerWidth float64
|
||||
InnerHeight float64
|
||||
InnerOffsetX float64
|
||||
InnerOffsetY float64
|
||||
InnerRadius float64
|
||||
MarkLength float64
|
||||
}
|
||||
|
||||
const defaultMarkLength = 6.0 // mm
|
||||
|
||||
// Build computes template data from product dimensions.
|
||||
func Build(size, bleed, margin, padding float64) Data {
|
||||
func Build(width, height, bleed, margin, padding, cornerRadius float64) Data {
|
||||
offset := bleed + margin + defaultMarkLength
|
||||
viewBoxMin := -offset
|
||||
viewBoxSize := size + (offset * 2)
|
||||
viewBoxW := width + (offset * 2)
|
||||
viewBoxH := height + (offset * 2)
|
||||
|
||||
innerW := width - (padding * 2)
|
||||
innerH := height - (padding * 2)
|
||||
if innerW < 0 {
|
||||
innerW = 0
|
||||
}
|
||||
if innerH < 0 {
|
||||
innerH = 0
|
||||
}
|
||||
innerR := cornerRadius - padding
|
||||
if innerR < 0 {
|
||||
innerR = 0
|
||||
}
|
||||
maxInnerR := math.Min(innerW, innerH) / 2
|
||||
if innerR > maxInnerR && maxInnerR > 0 {
|
||||
innerR = maxInnerR
|
||||
}
|
||||
|
||||
return Data{
|
||||
Size: size,
|
||||
Bleed: bleed,
|
||||
Margin: margin,
|
||||
Padding: padding,
|
||||
ViewBoxMin: viewBoxMin,
|
||||
ViewBoxSize: viewBoxSize,
|
||||
MarkLength: defaultMarkLength,
|
||||
MaskSize: size,
|
||||
OuterSize: size + (bleed * 2),
|
||||
OuterOffset: -bleed,
|
||||
InnerSize: size - (padding * 2),
|
||||
InnerOffset: padding,
|
||||
Width: width,
|
||||
Height: height,
|
||||
CornerRadius: cornerRadius,
|
||||
Bleed: bleed,
|
||||
Margin: margin,
|
||||
Padding: padding,
|
||||
ViewBoxMin: -offset,
|
||||
ViewBoxWidth: viewBoxW,
|
||||
ViewBoxHeight: viewBoxH,
|
||||
MarkLength: defaultMarkLength,
|
||||
MaskWidth: width,
|
||||
MaskHeight: height,
|
||||
OuterWidth: width + (bleed * 2),
|
||||
OuterHeight: height + (bleed * 2),
|
||||
OuterOffsetX: -bleed,
|
||||
OuterOffsetY: -bleed,
|
||||
InnerWidth: innerW,
|
||||
InnerHeight: innerH,
|
||||
InnerOffsetX: padding,
|
||||
InnerOffsetY: padding,
|
||||
InnerRadius: innerR,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,35 +10,35 @@ import (
|
||||
)
|
||||
|
||||
const svgTemplate = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="{{.Size}}mm" height="{{.Size}}mm" viewBox="{{.ViewBoxMin}} {{.ViewBoxMin}} {{.ViewBoxSize}} {{.ViewBoxSize}}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="{{.ViewBoxWidth}}mm" height="{{.ViewBoxHeight}}mm" viewBox="{{.ViewBoxMin}} {{.ViewBoxMin}} {{.ViewBoxWidth}} {{.ViewBoxHeight}}">
|
||||
<defs>
|
||||
<clipPath id="item-mask">
|
||||
<rect x="0" y="0" width="{{.MaskSize}}" height="{{.MaskSize}}" rx="5" ry="5" />
|
||||
<rect x="0" y="0" width="{{.MaskWidth}}" height="{{.MaskHeight}}" rx="{{.CornerRadius}}" ry="{{.CornerRadius}}" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<rect x="{{.ViewBoxMin}}" y="{{.ViewBoxMin}}" width="{{.ViewBoxSize}}" height="{{.ViewBoxSize}}" fill="#f9f9f9" />
|
||||
<rect x="{{.ViewBoxMin}}" y="{{.ViewBoxMin}}" width="{{.ViewBoxWidth}}" height="{{.ViewBoxHeight}}" fill="#f9f9f9" />
|
||||
|
||||
<g clip-path="url(#item-mask)">
|
||||
<rect x="{{.OuterOffset}}" y="{{.OuterOffset}}" width="{{.OuterSize}}" height="{{.OuterSize}}" fill="#00FF00" opacity="0.7" />
|
||||
<rect x="{{.OuterOffsetX}}" y="{{.OuterOffsetY}}" width="{{.OuterWidth}}" height="{{.OuterHeight}}" fill="#00FF00" opacity="0.7" />
|
||||
</g>
|
||||
|
||||
<rect x="{{.InnerOffset}}" y="{{.InnerOffset}}" width="{{.InnerSize}}" height="{{.InnerSize}}" fill="none" stroke="#0000FF" stroke-width="0.3" stroke-dasharray="1,1" />
|
||||
<rect x="{{.InnerOffsetX}}" y="{{.InnerOffsetY}}" width="{{.InnerWidth}}" height="{{.InnerHeight}}" rx="{{.InnerRadius}}" ry="{{.InnerRadius}}" fill="none" stroke="#0000FF" stroke-width="0.3" stroke-dasharray="1,1" />
|
||||
|
||||
<rect x="0" y="0" width="{{.MaskSize}}" height="{{.MaskSize}}" fill="none" stroke="#ccc" stroke-width="0.2" stroke-dasharray="2,2" />
|
||||
<rect x="0" y="0" width="{{.MaskWidth}}" height="{{.MaskHeight}}" rx="{{.CornerRadius}}" ry="{{.CornerRadius}}" fill="none" stroke="#ccc" stroke-width="0.2" stroke-dasharray="2,2" />
|
||||
|
||||
<g stroke="#000000" stroke-width="0.3">
|
||||
<line x1="0" y1="-{{.Bleed}}" x2="0" y2="-{{appendBleed .Bleed .MarkLength}}" />
|
||||
<line x1="-{{.Bleed}}" y1="0" x2="-{{appendBleed .Bleed .MarkLength}}" y2="0" />
|
||||
|
||||
<line x1="{{.Size}}" y1="-{{.Bleed}}" x2="{{.Size}}" y2="-{{appendBleed .Bleed .MarkLength}}" />
|
||||
<line x1="{{add .Size .Bleed}}" y1="0" x2="{{addThree .Size .Bleed .MarkLength}}" y2="0" />
|
||||
<line x1="{{.Width}}" y1="-{{.Bleed}}" x2="{{.Width}}" y2="-{{appendBleed .Bleed .MarkLength}}" />
|
||||
<line x1="{{add .Width .Bleed}}" y1="0" x2="{{addThree .Width .Bleed .MarkLength}}" y2="0" />
|
||||
|
||||
<line x1="0" y1="{{add .Size .Bleed}}" x2="0" y2="{{addThree .Size .Bleed .MarkLength}}" />
|
||||
<line x1="-{{.Bleed}}" y1="{{.Size}}" x2="-{{appendBleed .Bleed .MarkLength}}" y2="{{.Size}}" />
|
||||
<line x1="0" y1="{{add .Height .Bleed}}" x2="0" y2="{{addThree .Height .Bleed .MarkLength}}" />
|
||||
<line x1="-{{.Bleed}}" y1="{{.Height}}" x2="-{{appendBleed .Bleed .MarkLength}}" y2="{{.Height}}" />
|
||||
|
||||
<line x1="{{.Size}}" y1="{{add .Size .Bleed}}" x2="{{.Size}}" y2="{{addThree .Size .Bleed .MarkLength}}" />
|
||||
<line x1="{{add .Size .Bleed}}" y1="{{.Size}}" x2="{{addThree .Size .Bleed .MarkLength}}" y2="{{.Size}}" />
|
||||
<line x1="{{.Width}}" y1="{{add .Height .Bleed}}" x2="{{.Width}}" y2="{{addThree .Height .Bleed .MarkLength}}" />
|
||||
<line x1="{{add .Width .Bleed}}" y1="{{.Height}}" x2="{{addThree .Width .Bleed .MarkLength}}" y2="{{.Height}}" />
|
||||
</g>
|
||||
</svg>
|
||||
`
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package svgtemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBuildSVGRootMatchesViewBox(t *testing.T) {
|
||||
data := Build(10, 80, 1, 1, 1, 1)
|
||||
var buf bytes.Buffer
|
||||
if err := Write(&buf, data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s := buf.String()
|
||||
want := `width="26mm" height="96mm" viewBox="-8 -8 26 96"`
|
||||
if !strings.Contains(s, want) {
|
||||
t.Fatalf("expected root %q in:\n%s", want, s)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user