kartograph-maps/pkg/generator/svg.go

101 lines
3.4 KiB
Go

package generator
import (
"math"
"os"
"github.com/ajstarks/svgo"
)
func (w World) SVG(filename string) {
// DIN-A5
width := 148 * 3
height := 210 * 3
hPadding := 10
vPadding := 60
gridsize := int(math.Floor(float64(width-2*hPadding) / float64(w.Size)))
boardsize := gridsize * w.Size
file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
panic(err)
}
defer file.Close()
canvas := svg.New(file)
canvas.Start(width, height)
canvas.Def()
canvas.Pattern("hatch00", 0, 0, 10, 10, "user")
canvas.Gstyle("fill:none; stroke:black; stroke-width:1.5")
canvas.Path("M0,0 l10,10")
canvas.Path("M10,0 l-10,10")
canvas.Gend()
canvas.PatternEnd()
canvas.DefEnd()
canvas.Rect(0, 0, width, height, "fill:none; stroke:black")
// Name, date
canvas.Rect(hPadding, 13, 170, 32, "fill:none; stroke:black")
canvas.Rect(hPadding+180, 13, 120, 32, "fill:none; stroke:black")
// Final score
canvas.Roundrect(348, 10, 80, 40, 8, 8, "fill:none; stroke:black")
// Grid
for i := 1; i < w.Size; i++ {
canvas.Line(hPadding, i*gridsize+vPadding, boardsize+hPadding, i*gridsize+vPadding, "fill:none; stroke:gray; stroke-dasharray:5,5")
canvas.Line(i*gridsize+hPadding, vPadding, i*gridsize+hPadding, boardsize+vPadding, "fill:none; stroke:gray; stroke-dasharray:5,5")
}
// Terrain
for pos, tile := range w.World {
x, y := w.ToXY(pos)
switch tile.Territory {
case RuinsTerritory:
canvas.Text(hPadding+x*gridsize+3, vPadding+(y*gridsize)+16, "R", "stroke:lightgrey;fill:lightgrey")
case MountainTerritory:
canvas.Rect(hPadding+x*gridsize, vPadding+y*gridsize, gridsize, gridsize, "fill:white; stroke:black")
canvas.Circle(hPadding+x*gridsize+gridsize/2, vPadding+y*gridsize+gridsize/2, gridsize/2-8, "fill:white; stroke:black")
case WastelandTerritory:
canvas.Rect(hPadding+x*gridsize, vPadding+y*gridsize, gridsize, gridsize, "fill:white")
canvas.Rect(hPadding+x*gridsize, vPadding+y*gridsize, gridsize, gridsize, "fill:url(#hatch00)")
}
}
canvas.Rect(hPadding, vPadding, boardsize, boardsize, "fill:none; stroke:black; stroke-width:2")
// Money bar
for i := 0; i < 14; i++ {
canvas.Circle(hPadding+i*30+12, vPadding+boardsize+30, 12, "fill:none; stroke:black")
}
// Point boxes
for i := 0; i < 4; i++ {
startX := hPadding + i*95 + i*13
startY := vPadding + boardsize + 80
canvas.Roundrect(startX, startY, 95, 60, 8, 8, "fill:none; stroke:black")
canvas.Line(startX, startY+30, startX+60, startY+30, "fill:none; stroke:black")
canvas.Line(startX+30, startY, startX+30, startY+60, "fill:none; stroke:black")
canvas.Line(startX+60, startY, startX+60, startY+60, "fill:none; stroke:black")
}
// Labels
canvas.Text(hPadding+11, vPadding+boardsize+74, "A", "stroke:black;fill:black;font-size:14px")
canvas.Text(hPadding+41, vPadding+boardsize+74, "B", "stroke:black;fill:black;font-size:14px")
canvas.Text(hPadding+118, vPadding+boardsize+74, "B", "stroke:black;fill:black;font-size:14px")
canvas.Text(hPadding+148, vPadding+boardsize+74, "C", "stroke:black;fill:black;font-size:14px")
canvas.Text(hPadding+225, vPadding+boardsize+74, "C", "stroke:black;fill:black;font-size:14px")
canvas.Text(hPadding+255, vPadding+boardsize+74, "D", "stroke:black;fill:black;font-size:14px")
canvas.Text(hPadding+334, vPadding+boardsize+74, "D", "stroke:black;fill:black;font-size:14px")
canvas.Text(hPadding+364, vPadding+boardsize+74, "A", "stroke:black;fill:black;font-size:14px")
canvas.End()
}