diff --git a/README.md b/README.md index 71761ce..4c2de00 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,29 @@ konstrukt gen interlocking --color1 "#f7f1e3" --color2 "#40407a" --color3 "#33d9 +### Whitegold + +The pattern and default implementation is [MarcelMues](https://github.com/MarcelMue) work titled `whitegold`. + +
+Usage examples + +The default can be generated with: +``` +konstrukt gen whitegold +``` + +![Whitegold](samples/whitegold.svg) + +Changing the colors can be easily done like this: +``` +konstrukt gen whitegold --color1 "#dff9fb" --color2 "#6ab04c" --filename whitegold-au.svg +``` + +![Whitegold AU color inspiration](samples/whitegold-au.svg) + +
+ ## Guidelines Additions to this project should follow these guidelines: diff --git a/cmd/gen/command.go b/cmd/gen/command.go index 7e42e69..591436e 100644 --- a/cmd/gen/command.go +++ b/cmd/gen/command.go @@ -17,6 +17,7 @@ import ( "github.com/marcelmue/konstrukt/cmd/gen/quadrat" "github.com/marcelmue/konstrukt/cmd/gen/shining" "github.com/marcelmue/konstrukt/cmd/gen/swiss16" + "github.com/marcelmue/konstrukt/cmd/gen/whitegold" ) const ( @@ -169,6 +170,20 @@ func New(config Config) (*cobra.Command, error) { } } + var whitegoldCmd *cobra.Command + { + c := whitegold.Config{ + Logger: config.Logger, + Stderr: config.Stderr, + Stdout: config.Stdout, + } + + whitegoldCmd, err = whitegold.New(c) + if err != nil { + return nil, microerror.Mask(err) + } + } + f := &flag{} r := &runner{ @@ -196,6 +211,7 @@ func New(config Config) (*cobra.Command, error) { c.AddCommand(modernhiveCmd) c.AddCommand(swiss16Cmd) c.AddCommand(interlockingCmd) + c.AddCommand(whitegoldCmd) return c, nil } diff --git a/cmd/gen/whitegold/command.go b/cmd/gen/whitegold/command.go new file mode 100644 index 0000000..b3a9e36 --- /dev/null +++ b/cmd/gen/whitegold/command.go @@ -0,0 +1,53 @@ +package whitegold + +import ( + "io" + "os" + + "github.com/giantswarm/microerror" + "github.com/giantswarm/micrologger" + "github.com/spf13/cobra" +) + +const ( + name = "whitegold" + description = "Draws MarcelMues 'whitegold'." +) + +type Config struct { + Logger micrologger.Logger + Stderr io.Writer + Stdout io.Writer +} + +func New(config Config) (*cobra.Command, error) { + if config.Logger == nil { + return nil, microerror.Maskf(invalidConfigError, "%T.Logger must not be empty", config) + } + if config.Stderr == nil { + config.Stderr = os.Stderr + } + if config.Stdout == nil { + config.Stdout = os.Stdout + } + + f := &flag{} + + r := &runner{ + flag: f, + logger: config.Logger, + stderr: config.Stderr, + stdout: config.Stdout, + } + + c := &cobra.Command{ + Use: name, + Short: description, + Long: description, + RunE: r.Run, + } + + f.Init(c) + + return c, nil +} diff --git a/cmd/gen/whitegold/command_test.go b/cmd/gen/whitegold/command_test.go new file mode 100644 index 0000000..f938a1d --- /dev/null +++ b/cmd/gen/whitegold/command_test.go @@ -0,0 +1,88 @@ +package whitegold + +import ( + "fmt" + "strconv" + "testing" + + "github.com/giantswarm/micrologger" +) + +func Test_command(t *testing.T) { + testCases := []struct { + name string + c1 string + c2 string + filename string + height int + width int + }{ + { + name: "case 0: default pattern", + filename: "whitegold", + }, + { + name: "case 1: au color pattern", + filename: "whitegold-au", + c1: "#dff9fb", + c2: "#6ab04c", + }, + { + name: "case 2: banner resize", + filename: "whitegold-wide", + width: 2000, + height: 400, + }, + } + + for i, tc := range testCases { + t.Run(strconv.Itoa(i), func(t *testing.T) { + t.Log(tc.name) + + var err error + + var logger micrologger.Logger + { + c := micrologger.Config{} + + logger, err = micrologger.New(c) + if err != nil { + t.Fatal("expected", nil, "got", err) + } + } + + c := Config{ + Logger: logger, + } + + testCommand, err := New(c) + if err != nil { + t.Fatal("expected", nil, "got", err) + } + + args := []string{} + if tc.filename != "" { + args = append(args, []string{"--filename", fmt.Sprintf("../../../samples/%s.svg", tc.filename)}...) + } + if tc.c1 != "" { + args = append(args, []string{"--color1", tc.c1}...) + } + if tc.c2 != "" { + args = append(args, []string{"--color2", tc.c2}...) + } + if tc.height != 0 { + args = append(args, []string{"--height", strconv.Itoa(tc.height)}...) + } + if tc.width != 0 { + args = append(args, []string{"--width", strconv.Itoa(tc.width)}...) + } + + testCommand.SetArgs(args) + + err = testCommand.Execute() + if err != nil { + t.Fatal("expected", nil, "got", err) + } + }) + } +} diff --git a/cmd/gen/whitegold/error.go b/cmd/gen/whitegold/error.go new file mode 100644 index 0000000..f3eeb7d --- /dev/null +++ b/cmd/gen/whitegold/error.go @@ -0,0 +1,21 @@ +package whitegold + +import "github.com/giantswarm/microerror" + +var invalidConfigError = µerror.Error{ + Kind: "invalidConfigError", +} + +// IsInvalidConfig asserts invalidConfigError. +func IsInvalidConfig(err error) bool { + return microerror.Cause(err) == invalidConfigError +} + +var invalidFlagError = µerror.Error{ + Kind: "invalidFlagError", +} + +// IsInvalidFlag asserts invalidFlagError. +func IsInvalidFlag(err error) bool { + return microerror.Cause(err) == invalidFlagError +} diff --git a/cmd/gen/whitegold/flag.go b/cmd/gen/whitegold/flag.go new file mode 100644 index 0000000..ecd319c --- /dev/null +++ b/cmd/gen/whitegold/flag.go @@ -0,0 +1,65 @@ +package whitegold + +import ( + "github.com/giantswarm/microerror" + "github.com/spf13/cobra" + + "github.com/marcelmue/konstrukt/pkg/validate" +) + +const ( + flagFilename = "filename" + + flagHeight = "height" + flagWidth = "width" + + flagColor1 = "color1" + flagColor2 = "color2" + + flagRandomize = "randomize" +) + +type flag struct { + Filename string + + Height int + Width int + + Color1 string + Color2 string + + Randomize bool +} + +func (f *flag) Init(cmd *cobra.Command) { + cmd.Flags().StringVar(&f.Filename, flagFilename, "whitegold.svg", `Name of the output file.`) + + cmd.Flags().IntVar(&f.Height, flagHeight, 500, `Height of the output file in pixels.`) + cmd.Flags().IntVar(&f.Width, flagWidth, 500, `Width of the output file in pixels.`) + + cmd.Flags().StringVar(&f.Color1, flagColor1, "#130f40", `First color.`) + cmd.Flags().StringVar(&f.Color2, flagColor2, "#ffd32a", `Second color.`) + + cmd.Flags().BoolVar(&f.Randomize, flagRandomize, false, "Randomize all colors in the pattern, ignore other color flags.") +} + +func (f *flag) Validate() error { + if !validate.Color(f.Color1) { + validate.PrintFailure(flagColor1) + return microerror.Mask(invalidFlagError) + } + if !validate.Color(f.Color2) { + validate.PrintFailure(flagColor2) + return microerror.Mask(invalidFlagError) + } + if !validate.Size(f.Height) { + validate.PrintFailure(flagHeight) + return microerror.Mask(invalidFlagError) + } + if !validate.Size(f.Width) { + validate.PrintFailure(flagWidth) + return microerror.Mask(invalidFlagError) + } + + return nil +} diff --git a/cmd/gen/whitegold/runner.go b/cmd/gen/whitegold/runner.go new file mode 100644 index 0000000..afa76e9 --- /dev/null +++ b/cmd/gen/whitegold/runner.go @@ -0,0 +1,102 @@ +package whitegold + +import ( + "context" + "fmt" + "io" + "os" + + svg "github.com/ajstarks/svgo" + "github.com/giantswarm/microerror" + "github.com/giantswarm/micrologger" + "github.com/spf13/cobra" + + "github.com/marcelmue/konstrukt/pkg/color" + "github.com/marcelmue/konstrukt/pkg/project" +) + +type runner struct { + flag *flag + logger micrologger.Logger + stdout io.Writer + stderr io.Writer +} + +func (r *runner) Run(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + err := r.flag.Validate() + if err != nil { + return microerror.Mask(err) + } + + if r.flag.Randomize { + r.flag.Color1 = color.Random() + r.flag.Color2 = color.Random() + fmt.Printf("Set Color1:%s Color2:%s\n", r.flag.Color1, r.flag.Color2) + } + + err = r.run(ctx, cmd, args) + if err != nil { + return microerror.Mask(err) + } + + return nil +} + +func (r *runner) run(ctx context.Context, cmd *cobra.Command, args []string) error { + f, err := os.Create(r.flag.Filename) + if err != nil { + return microerror.Mask(err) + } + width, height := r.flag.Width, r.flag.Height + c1, c2 := r.flag.Color1, r.flag.Color2 + + canvas := svg.New(f) + canvas.Start(width, height) + canvas.Desc(project.PatternDesc()) + canvas.Rect(0, 0, width, height, "fill:"+c1) + + // Polygon. + xp := []int{25, 10, 30, 10, 25, 55} + yp := []int{0, 15, 45, 80, 90, 45} + + // Diamond 1. + xd := []int{0, 11, 0} + yd := []int{2, -7, -22} + + // Diamond 2. + xq := []int{0, 11, 0} + yq := []int{57, 48, 33} + + canvas.Def() + canvas.Gid("unit") + canvas.Polygon(xp, yp) + canvas.Polygon(xd, yd) + canvas.Polygon(xq, yq) + canvas.Gend() + canvas.Gid("runit") + canvas.ScaleXY(-1, 1) + canvas.Use(0, 0, "#unit") + canvas.Gend() + canvas.Gend() + canvas.DefEnd() + + ypositioncounter := 0 + for y := -112; y < height+200; y += 56 { + for x := -200; x < width+200; x += 200 { + if ypositioncounter%2 == 0 { + canvas.Use(x, y, "#unit", "fill:"+c2) + canvas.Use(x, y, "#runit", "fill:"+c2) + } + if ypositioncounter%2 == 1 { + canvas.Use(x+100, y, "#unit", "fill:"+c2) + canvas.Use(x+100, y, "#runit", "fill:"+c2) + } + } + ypositioncounter++ + } + canvas.End() + + return nil +} diff --git a/samples/whitegold-au.svg b/samples/whitegold-au.svg new file mode 100644 index 0000000..593b604 --- /dev/null +++ b/samples/whitegold-au.svg @@ -0,0 +1,170 @@ + + + +Generated with https://github.com/marcelmue/konstrukt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/whitegold-wide.svg b/samples/whitegold-wide.svg new file mode 100644 index 0000000..1a13fd2 --- /dev/null +++ b/samples/whitegold-wide.svg @@ -0,0 +1,332 @@ + + + +Generated with https://github.com/marcelmue/konstrukt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/whitegold.svg b/samples/whitegold.svg new file mode 100644 index 0000000..5000302 --- /dev/null +++ b/samples/whitegold.svg @@ -0,0 +1,170 @@ + + + +Generated with https://github.com/marcelmue/konstrukt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +