Added Generator for Template SVG

This commit is contained in:
simon 2026-05-26 15:43:54 +02:00
parent 3465dfc95f
commit 48f62500d5
5 changed files with 161 additions and 23 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
svg_template/

View File

@ -1,23 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var generateCmd = &cobra.Command{
Use: "generate",
Short: "Generate project artifacts",
}
var generateTemplateCmd = &cobra.Command{
Use: "template",
Short: "Generate a template",
Run: func(cmd *cobra.Command, args []string) {
// TODO: implement template generation
},
}
func init() {
generateCmd.AddCommand(generateTemplateCmd)
rootCmd.AddCommand(generateCmd)
}

42
cmd/generate_template.go Normal file
View File

@ -0,0 +1,42 @@
package cmd
import (
"fmt"
"path/filepath"
"github.com/spf13/cobra"
"printer.backend/internal/svgtemplate"
)
var (
sizeFlag float64
bleedFlag float64
marginFlag float64
paddingFlag float64
outputFlag string
)
var generateTemplateCmd = &cobra.Command{
Use: "template",
Short: "Generate a square SVG mask template with bleed and margins",
RunE: func(cmd *cobra.Command, args []string) error {
data := svgtemplate.Build(sizeFlag, bleedFlag, marginFlag, paddingFlag)
outPath := filepath.Join(svgtemplate.OutputDir, filepath.Base(outputFlag))
if err := svgtemplate.WriteFile(outputFlag, data); err != nil {
return fmt.Errorf("write svg: %w", err)
}
cmd.Printf("Template erfolgreich generiert: %s\n", outPath)
return nil
},
}
func init() {
rootCmd.AddCommand(generateTemplateCmd)
generateTemplateCmd.Flags().Float64VarP(&sizeFlag, "size", "s", 100.0, "Size of the final square product in mm")
generateTemplateCmd.Flags().Float64VarP(&bleedFlag, "bleed", "b", 2.0, "Bleed (Überdruck) in mm")
generateTemplateCmd.Flags().Float64VarP(&marginFlag, "margin", "m", 5.0, "Margin to the outer elements in mm")
generateTemplateCmd.Flags().Float64VarP(&paddingFlag, "padding", "p", 3.0, "Inner padding (safety margin) in mm")
generateTemplateCmd.Flags().StringVarP(&outputFlag, "output", "o", "mask_template.svg", "Output file path")
}

View File

@ -0,0 +1,41 @@
package svgtemplate
// 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
}
const defaultMarkLength = 6.0 // mm
// Build computes template data from product dimensions.
func Build(size, bleed, margin, padding float64) Data {
offset := bleed + margin + defaultMarkLength
viewBoxMin := -offset
viewBoxSize := size + (offset * 2)
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,
}
}

View File

@ -0,0 +1,77 @@
package svgtemplate
import (
"io"
"os"
"path/filepath"
"text/template"
)
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}}">
<defs>
<clipPath id="item-mask">
<rect x="0" y="0" width="{{.MaskSize}}" height="{{.MaskSize}}" rx="5" ry="5" />
</clipPath>
</defs>
<rect x="{{.ViewBoxMin}}" y="{{.ViewBoxMin}}" width="{{.ViewBoxSize}}" height="{{.ViewBoxSize}}" fill="#f9f9f9" />
<g clip-path="url(#item-mask)">
<rect x="{{.OuterOffset}}" y="{{.OuterOffset}}" width="{{.OuterSize}}" height="{{.OuterSize}}" 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="0" y="0" width="{{.MaskSize}}" height="{{.MaskSize}}" 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="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="{{.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}}" />
</g>
</svg>
`
var tmpl = template.Must(
template.New("svg").Funcs(template.FuncMap{
"appendBleed": func(bleed, mark float64) float64 { return bleed + mark },
"add": func(a, b float64) float64 { return a + b },
"addThree": func(a, b, c float64) float64 { return a + b + c },
}).Parse(svgTemplate),
)
// Write renders the SVG template to w.
func Write(w io.Writer, data Data) error {
return tmpl.Execute(w, data)
}
// OutputDir is the directory where generated SVG files are written.
const OutputDir = "svg_template"
// WriteFile renders the SVG template into OutputDir.
func WriteFile(path string, data Data) error {
outPath := filepath.Join(OutputDir, filepath.Base(filepath.Clean(path)))
if err := os.MkdirAll(OutputDir, 0o755); err != nil {
return err
}
file, err := os.Create(outPath)
if err != nil {
return err
}
defer file.Close()
if err := Write(file, data); err != nil {
return err
}
return file.Close()
}