diff --git a/README.md b/README.md index 775f014..b522afc 100644 --- a/README.md +++ b/README.md @@ -343,6 +343,29 @@ konstrukt gen fallingdaggers --color1 "#e55039" --color2 "#f39c12" --filename f +### Whitegold2 + +The pattern and default implementation is [MarcelMues](https://github.com/MarcelMue) work titled `whitegold2`. + +
+Usage examples + +The default can be generated with: +``` +konstrukt gen whitegold2 +``` + +![Whitegold2](samples/whitegold2.svg) + +Changing the colors can be easily done like this: +``` +konstrukt gen whitegold2 --color1 "#1e272e" --color2 "#f53b57" --filename whitegold2-se.svg +``` + +![Whitegold2 SE color inspiration](samples/whitegold2-se.svg) + +
+ ## Guidelines Additions to this project should follow these guidelines: diff --git a/cmd/gen/command.go b/cmd/gen/command.go index f8b33ee..5096f8c 100644 --- a/cmd/gen/command.go +++ b/cmd/gen/command.go @@ -19,6 +19,7 @@ import ( "github.com/marcelmue/konstrukt/cmd/gen/shining" "github.com/marcelmue/konstrukt/cmd/gen/swiss16" "github.com/marcelmue/konstrukt/cmd/gen/whitegold" + "github.com/marcelmue/konstrukt/cmd/gen/whitegold2" ) const ( @@ -199,6 +200,20 @@ func New(config Config) (*cobra.Command, error) { } } + var whitegold2Cmd *cobra.Command + { + c := whitegold2.Config{ + Logger: config.Logger, + Stderr: config.Stderr, + Stdout: config.Stdout, + } + + whitegold2Cmd, err = whitegold2.New(c) + if err != nil { + return nil, microerror.Mask(err) + } + } + f := &flag{} r := &runner{ @@ -228,6 +243,7 @@ func New(config Config) (*cobra.Command, error) { c.AddCommand(interlockingCmd) c.AddCommand(whitegoldCmd) c.AddCommand(fallingdaggersCmd) + c.AddCommand(whitegold2Cmd) return c, nil } diff --git a/cmd/gen/whitegold2/command.go b/cmd/gen/whitegold2/command.go new file mode 100644 index 0000000..f354dcd --- /dev/null +++ b/cmd/gen/whitegold2/command.go @@ -0,0 +1,53 @@ +package whitegold2 + +import ( + "io" + "os" + + "github.com/giantswarm/microerror" + "github.com/giantswarm/micrologger" + "github.com/spf13/cobra" +) + +const ( + name = "whitegold2" + description = "Draws MarcelMues 'whitegold2'." +) + +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/whitegold2/command_test.go b/cmd/gen/whitegold2/command_test.go new file mode 100644 index 0000000..e203ec5 --- /dev/null +++ b/cmd/gen/whitegold2/command_test.go @@ -0,0 +1,88 @@ +package whitegold2 + +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: "whitegold2", + }, + { + name: "case 1: se color pattern", + filename: "whitegold2-se", + c1: "#1e272e", + c2: "#f53b57", + }, + { + name: "case 2: banner resize", + filename: "whitegold2-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/whitegold2/error.go b/cmd/gen/whitegold2/error.go new file mode 100644 index 0000000..99369eb --- /dev/null +++ b/cmd/gen/whitegold2/error.go @@ -0,0 +1,21 @@ +package whitegold2 + +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/whitegold2/flag.go b/cmd/gen/whitegold2/flag.go new file mode 100644 index 0000000..a1151b6 --- /dev/null +++ b/cmd/gen/whitegold2/flag.go @@ -0,0 +1,65 @@ +package whitegold2 + +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, "whitegold2.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, "#95a5a6", `First color.`) + cmd.Flags().StringVar(&f.Color2, flagColor2, "#ecf0f1", `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/whitegold2/runner.go b/cmd/gen/whitegold2/runner.go new file mode 100644 index 0000000..4a27154 --- /dev/null +++ b/cmd/gen/whitegold2/runner.go @@ -0,0 +1,96 @@ +package whitegold2 + +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 + stylefmt := "stroke:%s;stroke-width:%d;fill:none" + + canvas := svg.New(f) + canvas.Start(width, height) + canvas.Desc(project.PatternDesc()) + canvas.Rect(0, 0, width, height, "fill:"+c1) + + // Polygon. + xp := []int{40, 0, 40, 80} + yp := []int{0, 40, 80, 40} + + // Polyline. + xl := []int{70, 40, 70} + yl := []int{10, 40, 70} + + canvas.Def() + canvas.Gid("unit") + canvas.Polygon(xp, yp, "fill:"+c2) + canvas.Polyline(xl, yl, fmt.Sprintf(stylefmt, c1, 10)) + canvas.Gend() + canvas.Gid("runit") + canvas.ScaleXY(-1, 1) + canvas.Use(0, 0, "#unit") + canvas.Gend() + canvas.Gend() + canvas.DefEnd() + + ypositioncounter := 0 + for y := -100; y < height+200; y += 50 { + for x := -200; x < width+200; x += 100 { + if ypositioncounter%2 == 0 { + canvas.Use(x, y, "#unit") + } + if ypositioncounter%2 == 1 { + canvas.Use(x+30, y, "#runit") + } + } + ypositioncounter++ + } + canvas.End() + + return nil +} diff --git a/samples/whitegold2-se.svg b/samples/whitegold2-se.svg new file mode 100644 index 0000000..911500f --- /dev/null +++ b/samples/whitegold2-se.svg @@ -0,0 +1,163 @@ + + + +Generated with https://github.com/marcelmue/konstrukt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/whitegold2-wide.svg b/samples/whitegold2-wide.svg new file mode 100644 index 0000000..56b8758 --- /dev/null +++ b/samples/whitegold2-wide.svg @@ -0,0 +1,355 @@ + + + +Generated with https://github.com/marcelmue/konstrukt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/whitegold2.svg b/samples/whitegold2.svg new file mode 100644 index 0000000..3c25013 --- /dev/null +++ b/samples/whitegold2.svg @@ -0,0 +1,163 @@ + + + +Generated with https://github.com/marcelmue/konstrukt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +