geo_pattern 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +30 -0
- data/.gitignore +1 -0
- data/.simplecov +1 -0
- data/Gemfile +17 -19
- data/README.md +35 -12
- data/Rakefile +45 -49
- data/geo_pattern.gemspec +18 -22
- data/lib/geo_pattern/background.rb +9 -7
- data/lib/geo_pattern/background_generators/solid_generator.rb +4 -2
- data/lib/geo_pattern/color.rb +3 -1
- data/lib/geo_pattern/color_generators/base_color_generator.rb +12 -10
- data/lib/geo_pattern/color_generators/simple_generator.rb +2 -0
- data/lib/geo_pattern/color_preset.rb +7 -1
- data/lib/geo_pattern/errors.rb +2 -0
- data/lib/geo_pattern/geo_pattern_task.rb +11 -9
- data/lib/geo_pattern/helpers.rb +7 -5
- data/lib/geo_pattern/pattern.rb +6 -4
- data/lib/geo_pattern/pattern_generator.rb +14 -12
- data/lib/geo_pattern/pattern_helpers.rb +11 -8
- data/lib/geo_pattern/pattern_preset.rb +3 -1
- data/lib/geo_pattern/pattern_sieve.rb +5 -3
- data/lib/geo_pattern/pattern_store.rb +20 -18
- data/lib/geo_pattern/pattern_validator.rb +4 -2
- data/lib/geo_pattern/rake_task.rb +19 -16
- data/lib/geo_pattern/roles/comparable_metadata.rb +2 -0
- data/lib/geo_pattern/roles/named_generator.rb +3 -1
- data/lib/geo_pattern/seed.rb +2 -0
- data/lib/geo_pattern/structure.rb +9 -7
- data/lib/geo_pattern/structure_generators/base_generator.rb +17 -14
- data/lib/geo_pattern/structure_generators/chevrons_generator.rb +19 -17
- data/lib/geo_pattern/structure_generators/concentric_circles_generator.rb +19 -17
- data/lib/geo_pattern/structure_generators/diamonds_generator.rb +23 -17
- data/lib/geo_pattern/structure_generators/hexagons_generator.rb +25 -23
- data/lib/geo_pattern/structure_generators/mosaic_squares_generator.rb +35 -35
- data/lib/geo_pattern/structure_generators/nested_squares_generator.rb +23 -21
- data/lib/geo_pattern/structure_generators/octagons_generator.rb +12 -11
- data/lib/geo_pattern/structure_generators/overlapping_circles_generator.rb +13 -11
- data/lib/geo_pattern/structure_generators/overlapping_rings_generator.rb +15 -13
- data/lib/geo_pattern/structure_generators/plaid_generator.rb +18 -18
- data/lib/geo_pattern/structure_generators/plus_signs_generator.rb +24 -18
- data/lib/geo_pattern/structure_generators/sine_waves_generator.rb +17 -15
- data/lib/geo_pattern/structure_generators/squares_generator.rb +10 -9
- data/lib/geo_pattern/structure_generators/tessellation_generator.rb +36 -34
- data/lib/geo_pattern/structure_generators/triangles_generator.rb +22 -19
- data/lib/geo_pattern/structure_generators/xes_generator.rb +26 -19
- data/lib/geo_pattern/svg_image.rb +10 -8
- data/lib/geo_pattern/version.rb +3 -1
- data/lib/geo_pattern.rb +53 -51
- data/script/console +4 -3
- data/spec/background_generators/solid_generator_spec.rb +16 -14
- data/spec/background_spec.rb +13 -11
- data/spec/color_generators/base_color_generator_spec.rb +10 -8
- data/spec/color_generators/simple_generator_spec.rb +5 -3
- data/spec/color_preset_spec.rb +17 -15
- data/spec/color_spec.rb +8 -6
- data/spec/geo_pattern_spec.rb +59 -58
- data/spec/helpers_spec.rb +30 -28
- data/spec/pattern_preset_spec.rb +15 -13
- data/spec/pattern_sieve_spec.rb +13 -11
- data/spec/pattern_spec.rb +20 -18
- data/spec/pattern_store_spec.rb +21 -19
- data/spec/pattern_validator_spec.rb +11 -9
- data/spec/seed_spec.rb +6 -4
- data/spec/spec_helper.rb +9 -8
- data/spec/structure_generators/chevrons_generator_spec.rb +4 -2
- data/spec/structure_generators/concentric_circles_generator_spec.rb +4 -2
- data/spec/structure_generators/diamonds_generator_spec.rb +4 -2
- data/spec/structure_generators/hexagons_generator_spec.rb +4 -2
- data/spec/structure_generators/mosaic_squares_generator_spec.rb +4 -2
- data/spec/structure_generators/nested_squares_generator_spec.rb +4 -2
- data/spec/structure_generators/octagons_generator_spec.rb +4 -2
- data/spec/structure_generators/overlapping_circles_generator_spec.rb +4 -2
- data/spec/structure_generators/overlapping_rings_generator_spec.rb +4 -2
- data/spec/structure_generators/plaid_generator_spec.rb +4 -2
- data/spec/structure_generators/plus_signs_generator_spec.rb +4 -2
- data/spec/structure_generators/sine_waves_generator_spec.rb +4 -2
- data/spec/structure_generators/squares_generator_spec.rb +4 -2
- data/spec/structure_generators/tessellation_generator_spec.rb +4 -2
- data/spec/structure_generators/triangles_generator_spec.rb +4 -2
- data/spec/structure_generators/xes_generator_spec.rb +4 -2
- data/spec/structure_spec.rb +18 -16
- data/spec/support/aruba.rb +6 -6
- data/spec/support/helpers/fixtures.rb +3 -1
- data/spec/support/kernel.rb +8 -2
- data/spec/support/matchers/image.rb +4 -2
- data/spec/support/matchers/name.rb +3 -1
- data/spec/support/rspec.rb +4 -2
- data/spec/support/shared_examples/generator.rb +12 -10
- data/spec/support/shared_examples/pattern.rb +7 -5
- data/spec/support/shared_examples/pattern_name.rb +4 -2
- data/spec/support/shared_examples/structure.rb +12 -10
- data/spec/support/string.rb +3 -2
- data/spec/svg_spec.rb +5 -3
- metadata +11 -59
- data/.rubocop.yml +0 -71
- data/.travis.yml +0 -12
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
class PatternGenerator
|
3
5
|
private
|
@@ -7,37 +9,37 @@ module GeoPattern
|
|
7
9
|
public
|
8
10
|
|
9
11
|
def initialize(string, generator: nil, patterns: nil, base_color: nil, color: nil)
|
10
|
-
|
12
|
+
warn "Using generator key is deprecated as of 1.3.1" if generator
|
11
13
|
|
12
14
|
requested_patterns = (Array(generator) | Array(patterns)).flatten.compact
|
13
15
|
|
14
16
|
pattern_preset = PatternPreset.new(
|
15
|
-
fill_color_dark:
|
16
|
-
fill_color_light:
|
17
|
-
stroke_color:
|
17
|
+
fill_color_dark: "#222",
|
18
|
+
fill_color_light: "#ddd",
|
19
|
+
stroke_color: "#000",
|
18
20
|
stroke_opacity: 0.02,
|
19
21
|
opacity_min: 0.02,
|
20
22
|
opacity_max: 0.15
|
21
23
|
)
|
22
24
|
|
23
25
|
color_preset = ColorPreset.new(
|
24
|
-
base_color:
|
26
|
+
base_color: "#933c3c"
|
25
27
|
)
|
26
|
-
color_preset.color
|
28
|
+
color_preset.color = color if color
|
27
29
|
color_preset.base_color = base_color if base_color
|
28
30
|
|
29
31
|
seed = Seed.new(string)
|
30
32
|
|
31
|
-
pattern_validator
|
33
|
+
pattern_validator = PatternValidator.new
|
32
34
|
pattern_validator.validate(requested_patterns)
|
33
35
|
|
34
|
-
pattern_sieve
|
36
|
+
pattern_sieve = PatternSieve.new(requested_patterns, seed)
|
35
37
|
|
36
38
|
@background_generator = BackgroundGenerators::SolidGenerator.new(seed, color_preset)
|
37
|
-
@structure_generator
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
@structure_generator = begin
|
40
|
+
generator_klass = pattern_sieve.fetch
|
41
|
+
generator_klass.new(seed, pattern_preset)
|
42
|
+
end
|
41
43
|
end
|
42
44
|
|
43
45
|
def generate
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module PatternHelpers
|
3
5
|
def hex_val(hash, index, length)
|
@@ -6,7 +8,8 @@ module GeoPattern
|
|
6
8
|
|
7
9
|
# Ruby implementation of Processing's map function
|
8
10
|
# http://processing.org/reference/map_.html
|
9
|
-
|
11
|
+
# v for value, d for desired
|
12
|
+
def map(value, v_min, v_max, d_min, d_max)
|
10
13
|
v_value = value.to_f # so it returns float
|
11
14
|
|
12
15
|
v_range = v_max - v_min
|
@@ -19,15 +22,15 @@ module GeoPattern
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def html_to_rgb_for_string(seed, base_color)
|
22
|
-
hue_offset
|
23
|
-
sat_offset
|
24
|
-
base_color
|
25
|
+
hue_offset = map(seed.to_i(14, 3), 0, 4095, 0, 359)
|
26
|
+
sat_offset = seed.to_i(17, 1)
|
27
|
+
base_color = ::Color::RGB.from_html(base_color).to_hsl
|
25
28
|
base_color.hue = base_color.hue - hue_offset
|
26
29
|
|
27
|
-
if
|
28
|
-
base_color.saturation
|
30
|
+
base_color.saturation = if sat_offset % 2 == 0
|
31
|
+
base_color.saturation + sat_offset
|
29
32
|
else
|
30
|
-
base_color.saturation
|
33
|
+
base_color.saturation - sat_offset
|
31
34
|
end
|
32
35
|
|
33
36
|
generate_rgb_string(base_color.to_rgb)
|
@@ -38,7 +41,7 @@ module GeoPattern
|
|
38
41
|
g = (rgb.g * 255).round
|
39
42
|
b = (rgb.b * 255).round
|
40
43
|
|
41
|
-
format(
|
44
|
+
format("rgb(%<r>d, %<g>d, %<b>d)", r: r, g: g, b: b)
|
42
45
|
end
|
43
46
|
|
44
47
|
module_function :hex_val, :map, :html_to_rgb, :html_to_rgb_for_string, :generate_rgb_string
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
class PatternPreset
|
3
5
|
private
|
@@ -10,7 +12,7 @@ module GeoPattern
|
|
10
12
|
@options = options
|
11
13
|
end
|
12
14
|
|
13
|
-
[
|
15
|
+
%i[fill_color_dark fill_color_light stroke_color stroke_opacity opacity_min opacity_max].each do |m|
|
14
16
|
define_method m do
|
15
17
|
options[m]
|
16
18
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
class PatternSieve
|
3
5
|
private
|
@@ -8,11 +10,11 @@ module GeoPattern
|
|
8
10
|
|
9
11
|
def initialize(requested_patterns, seed, pattern_store = PatternStore.new)
|
10
12
|
@requested_patterns = requested_patterns
|
11
|
-
@seed
|
12
|
-
@pattern_store
|
13
|
+
@seed = seed
|
14
|
+
@pattern_store = pattern_store
|
13
15
|
|
14
16
|
@available_patterns = determine_available_patterns
|
15
|
-
@index
|
17
|
+
@index = determine_index
|
16
18
|
end
|
17
19
|
|
18
20
|
def fetch
|
@@ -1,22 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
|
-
# rubocop:disable
|
3
|
-
ChevronPattern
|
4
|
-
ConcentricCirclesPattern
|
5
|
-
DiamondPattern
|
6
|
-
HexagonPattern
|
7
|
-
MosaicSquaresPattern
|
8
|
-
NestedSquaresPattern
|
9
|
-
OctagonPattern
|
4
|
+
# rubocop:disable Naming/ConstantName
|
5
|
+
ChevronPattern = :chevrons
|
6
|
+
ConcentricCirclesPattern = :concentric_circles
|
7
|
+
DiamondPattern = :diamonds
|
8
|
+
HexagonPattern = :hexagons
|
9
|
+
MosaicSquaresPattern = :mosaic_squares
|
10
|
+
NestedSquaresPattern = :nested_squares
|
11
|
+
OctagonPattern = :octagons
|
10
12
|
OverlappingCirclesPattern = :overlapping_circles
|
11
|
-
OverlappingRingsPattern
|
12
|
-
PlaidPattern
|
13
|
-
PlusSignPattern
|
14
|
-
SineWavePattern
|
15
|
-
SquarePattern
|
16
|
-
TessellationPattern
|
17
|
-
TrianglePattern
|
18
|
-
XesPattern
|
19
|
-
# rubocop:enable
|
13
|
+
OverlappingRingsPattern = :overlapping_rings
|
14
|
+
PlaidPattern = :plaid
|
15
|
+
PlusSignPattern = :plus_signs
|
16
|
+
SineWavePattern = :sine_waves
|
17
|
+
SquarePattern = :squares
|
18
|
+
TessellationPattern = :tessellation
|
19
|
+
TrianglePattern = :triangles
|
20
|
+
XesPattern = :xes
|
21
|
+
# rubocop:enable Naming/ConstantName
|
20
22
|
|
21
23
|
class PatternStore
|
22
24
|
private
|
@@ -47,7 +49,7 @@ module GeoPattern
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def [](pattern)
|
50
|
-
|
52
|
+
warn "String pattern references are deprecated as of 1.3.0" if pattern.is_a?(String)
|
51
53
|
|
52
54
|
store[pattern.to_s.to_sym]
|
53
55
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
class PatternValidator
|
3
5
|
private
|
@@ -11,9 +13,9 @@ module GeoPattern
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def validate(requested_patterns)
|
14
|
-
message = "Error: At least one of the requested patterns \"#{requested_patterns.join(
|
16
|
+
message = "Error: At least one of the requested patterns \"#{requested_patterns.join(", ")}\" is invalid"
|
15
17
|
|
16
|
-
|
18
|
+
raise InvalidPatternError, message unless valid?(requested_patterns)
|
17
19
|
|
18
20
|
self
|
19
21
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rake"
|
4
|
+
require "rake/tasklib"
|
5
|
+
require "logger"
|
4
6
|
|
5
7
|
module GeoPattern
|
6
8
|
# Rake Task
|
@@ -47,7 +49,7 @@ module GeoPattern
|
|
47
49
|
def initialize(opts = {}, &task_block)
|
48
50
|
@options = {
|
49
51
|
description: nil,
|
50
|
-
name: GeoPattern::Helpers.underscore(self.class.to_s.split(
|
52
|
+
name: GeoPattern::Helpers.underscore(self.class.to_s.split("::").slice(-2..-1).join(":").gsub(/Task$/, "")),
|
51
53
|
arguments: [],
|
52
54
|
logger: ::Logger.new($stderr),
|
53
55
|
working_directory: Dir.getwd
|
@@ -55,31 +57,31 @@ module GeoPattern
|
|
55
57
|
|
56
58
|
before_initialize
|
57
59
|
|
58
|
-
|
60
|
+
raise ArgumentError, :description if @options[:description].nil?
|
59
61
|
|
60
|
-
@description
|
61
|
-
@task_arguments
|
62
|
-
@task_block
|
63
|
-
@logger
|
62
|
+
@description = @options[:description]
|
63
|
+
@task_arguments = Array(@options[:arguments])
|
64
|
+
@task_block = task_block
|
65
|
+
@logger = @options[:logger]
|
64
66
|
@working_directory = @options[:working_directory]
|
65
|
-
@name
|
67
|
+
@name = @options[:name]
|
66
68
|
|
67
69
|
after_initialize
|
68
70
|
|
69
71
|
define_task
|
70
72
|
end
|
71
73
|
|
72
|
-
private
|
73
|
-
|
74
74
|
# Run code after initialize
|
75
|
-
def after_initialize
|
75
|
+
def after_initialize
|
76
|
+
end
|
76
77
|
|
77
78
|
# Run code before initialize
|
78
|
-
def before_initialize
|
79
|
+
def before_initialize
|
80
|
+
end
|
79
81
|
|
80
82
|
# Define task
|
81
83
|
def define_task
|
82
|
-
desc description unless ::Rake.application.
|
84
|
+
desc description unless ::Rake.application.last_description
|
83
85
|
|
84
86
|
task name, *task_arguments do |_, task_args|
|
85
87
|
RakeFileUtils.__send__(:verbose, verbose) do
|
@@ -90,7 +92,8 @@ module GeoPattern
|
|
90
92
|
end
|
91
93
|
|
92
94
|
# Run code if task is executed
|
93
|
-
def run_task(_verbose)
|
95
|
+
def run_task(_verbose)
|
96
|
+
end
|
94
97
|
|
95
98
|
public
|
96
99
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module Roles
|
3
5
|
module NamedGenerator
|
@@ -6,7 +8,7 @@ module GeoPattern
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def name
|
9
|
-
Helpers.underscore(Helpers.demodulize(self.class).gsub(/Generator/,
|
11
|
+
Helpers.underscore(Helpers.demodulize(self.class).gsub(/Generator/, "")).to_sym
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/lib/geo_pattern/seed.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
class Structure
|
3
5
|
include Roles::ComparableMetadata
|
@@ -9,15 +11,15 @@ module GeoPattern
|
|
9
11
|
def_delegators :@preset, :fill_color_dark, :fill_color_light, :stroke_color, :stroke_opacity, :opacity_min, :opacity_max
|
10
12
|
|
11
13
|
def initialize(options)
|
12
|
-
@image
|
13
|
-
@preset
|
14
|
-
@name
|
14
|
+
@image = options[:image]
|
15
|
+
@preset = options[:preset]
|
16
|
+
@name = options[:name]
|
15
17
|
@generator = options[:generator]
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
raise ArgumentError, "Argument name is missing" if @name.nil?
|
20
|
+
raise ArgumentError, "Argument image is missing" if @image.nil?
|
21
|
+
raise ArgumentError, "Argument preset is missing" if @preset.nil?
|
22
|
+
raise ArgumentError, "Argument generator is missing" if @generator.nil?
|
21
23
|
end
|
22
24
|
|
23
25
|
def_comparators :name, :fill_color_dark, :fill_color_light, :stroke_color, :stroke_opacity, :opacity_min, :opacity_max
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module StructureGenerators
|
3
5
|
class BaseGenerator
|
@@ -11,19 +13,19 @@ module GeoPattern
|
|
11
13
|
public
|
12
14
|
|
13
15
|
def initialize(seed, preset, svg = SvgImage.new)
|
14
|
-
@svg
|
15
|
-
@seed
|
16
|
+
@svg = svg
|
17
|
+
@seed = seed
|
16
18
|
@preset = preset
|
17
19
|
|
18
|
-
@fill_color_dark
|
20
|
+
@fill_color_dark = @preset.fill_color_dark
|
19
21
|
@fill_color_light = @preset.fill_color_light
|
20
|
-
@stroke_color
|
21
|
-
@stroke_opacity
|
22
|
-
@opacity_min
|
23
|
-
@opacity_max
|
22
|
+
@stroke_color = @preset.stroke_color
|
23
|
+
@stroke_opacity = @preset.stroke_opacity
|
24
|
+
@opacity_min = @preset.opacity_min
|
25
|
+
@opacity_max = @preset.opacity_max
|
24
26
|
|
25
27
|
@height = 100
|
26
|
-
@width
|
28
|
+
@width = 100
|
27
29
|
|
28
30
|
after_initialize
|
29
31
|
end
|
@@ -31,8 +33,8 @@ module GeoPattern
|
|
31
33
|
def generate(pattern)
|
32
34
|
pattern.structure = Structure.new(image: svg_image, preset: preset, generator: self.class, name: name)
|
33
35
|
|
34
|
-
pattern.height
|
35
|
-
pattern.width
|
36
|
+
pattern.height = height
|
37
|
+
pattern.width = width
|
36
38
|
|
37
39
|
self
|
38
40
|
end
|
@@ -43,17 +45,18 @@ module GeoPattern
|
|
43
45
|
def svg_image
|
44
46
|
image = generate_structure
|
45
47
|
image.height = height
|
46
|
-
image.width
|
48
|
+
image.width = width
|
47
49
|
|
48
50
|
image
|
49
51
|
end
|
50
52
|
|
51
53
|
# Hook for generators
|
52
|
-
def after_initialize
|
54
|
+
def after_initialize
|
55
|
+
end
|
53
56
|
|
54
57
|
# Generate the structure
|
55
58
|
def generate_structure
|
56
|
-
|
59
|
+
raise NotImplementedError
|
57
60
|
end
|
58
61
|
|
59
62
|
def hex_val(index, len)
|
@@ -61,7 +64,7 @@ module GeoPattern
|
|
61
64
|
end
|
62
65
|
|
63
66
|
def fill_color(val)
|
64
|
-
|
67
|
+
val.even? ? fill_color_light : fill_color_dark
|
65
68
|
end
|
66
69
|
|
67
70
|
def opacity(val)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module StructureGenerators
|
3
5
|
class ChevronsGenerator < BaseGenerator
|
@@ -6,35 +8,35 @@ module GeoPattern
|
|
6
8
|
attr_reader :chevron_height, :chevron_width, :chevron
|
7
9
|
|
8
10
|
def after_initialize
|
9
|
-
@chevron_width
|
11
|
+
@chevron_width = map(hex_val(0, 1), 0, 15, 30, 80)
|
10
12
|
@chevron_height = map(hex_val(0, 1), 0, 15, 30, 80)
|
11
|
-
@chevron
|
13
|
+
@chevron = build_chevron_shape(chevron_width, chevron_height)
|
12
14
|
|
13
15
|
self.height = chevron_height * 6 * 0.66
|
14
|
-
self.width
|
16
|
+
self.width = chevron_width * 6
|
15
17
|
end
|
16
18
|
|
17
19
|
def generate_structure
|
18
20
|
i = 0
|
19
|
-
|
20
|
-
|
21
|
-
val
|
21
|
+
6.times do |y|
|
22
|
+
6.times do |x|
|
23
|
+
val = hex_val(i, 1)
|
22
24
|
opacity = opacity(val)
|
23
|
-
fill
|
24
|
-
|
25
|
-
styles
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
fill = fill_color(val)
|
26
|
+
|
27
|
+
styles = {
|
28
|
+
"stroke" => stroke_color,
|
29
|
+
"stroke-opacity" => stroke_opacity,
|
30
|
+
"fill" => fill,
|
31
|
+
"fill-opacity" => opacity,
|
32
|
+
"stroke-width" => 1
|
31
33
|
}
|
32
34
|
|
33
|
-
svg.group(chevron, styles.merge(
|
35
|
+
svg.group(chevron, styles.merge("transform" => "translate(#{x * chevron_width},#{y * chevron_height * 0.66 - chevron_height / 2})"))
|
34
36
|
|
35
37
|
# Add an extra row at the end that matches the first row, for tiling.
|
36
|
-
if
|
37
|
-
svg.group(chevron, styles.merge(
|
38
|
+
if y == 0
|
39
|
+
svg.group(chevron, styles.merge("transform" => "translate(#{x * chevron_width},#{6 * chevron_height * 0.66 - chevron_height / 2})"))
|
38
40
|
end
|
39
41
|
i += 1
|
40
42
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module StructureGenerators
|
3
5
|
class ConcentricCirclesGenerator < BaseGenerator
|
@@ -6,8 +8,8 @@ module GeoPattern
|
|
6
8
|
attr_reader :scale, :ring_size, :stroke_width
|
7
9
|
|
8
10
|
def after_initialize
|
9
|
-
@scale
|
10
|
-
@ring_size
|
11
|
+
@scale = hex_val(0, 1)
|
12
|
+
@ring_size = map(scale, 0, 15, 10, 60)
|
11
13
|
@stroke_width = ring_size / 5
|
12
14
|
|
13
15
|
self.width = self.height = (ring_size + stroke_width) * 6
|
@@ -15,35 +17,35 @@ module GeoPattern
|
|
15
17
|
|
16
18
|
def generate_structure
|
17
19
|
i = 0
|
18
|
-
|
19
|
-
|
20
|
-
val
|
20
|
+
6.times do |y|
|
21
|
+
6.times do |x|
|
22
|
+
val = hex_val(i, 1)
|
21
23
|
opacity = opacity(val)
|
22
|
-
fill
|
24
|
+
fill = fill_color(val)
|
23
25
|
|
24
26
|
svg.circle(
|
25
27
|
x * ring_size + x * stroke_width + (ring_size + stroke_width) / 2,
|
26
28
|
y * ring_size + y * stroke_width + (ring_size + stroke_width) / 2,
|
27
29
|
ring_size / 2,
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
"fill" => "none",
|
31
|
+
"stroke" => fill,
|
32
|
+
"style" => {
|
33
|
+
"opacity" => opacity,
|
34
|
+
"stroke-width" => "#{stroke_width}px"
|
33
35
|
}
|
34
|
-
|
36
|
+
)
|
35
37
|
|
36
|
-
val
|
38
|
+
val = hex_val(39 - i, 1)
|
37
39
|
opacity = opacity(val)
|
38
|
-
fill
|
40
|
+
fill = fill_color(val)
|
39
41
|
|
40
42
|
svg.circle(
|
41
43
|
x * ring_size + x * stroke_width + (ring_size + stroke_width) / 2,
|
42
44
|
y * ring_size + y * stroke_width + (ring_size + stroke_width) / 2,
|
43
45
|
ring_size / 4,
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
"fill" => fill,
|
47
|
+
"fill-opacity" => opacity
|
48
|
+
)
|
47
49
|
|
48
50
|
i += 1
|
49
51
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module StructureGenerators
|
3
5
|
class DiamondsGenerator < BaseGenerator
|
@@ -6,50 +8,54 @@ module GeoPattern
|
|
6
8
|
attr_reader :diamond_height, :diamond_width, :diamond
|
7
9
|
|
8
10
|
def after_initialize
|
9
|
-
@diamond_width
|
11
|
+
@diamond_width = map(hex_val(0, 1), 0, 15, 10, 50)
|
10
12
|
@diamond_height = map(hex_val(1, 1), 0, 15, 10, 50)
|
11
|
-
@diamond
|
13
|
+
@diamond = build_diamond_shape(diamond_width, diamond_height)
|
12
14
|
|
13
15
|
self.height = diamond_height * 3
|
14
|
-
self.width
|
16
|
+
self.width = diamond_width * 6
|
15
17
|
end
|
16
18
|
|
17
19
|
def generate_structure
|
18
20
|
i = 0
|
19
|
-
|
20
|
-
|
21
|
-
val
|
21
|
+
6.times do |y|
|
22
|
+
6.times do |x|
|
23
|
+
val = hex_val(i, 1)
|
22
24
|
opacity = opacity(val)
|
23
|
-
fill
|
25
|
+
fill = fill_color(val)
|
24
26
|
|
25
27
|
styles = {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
"fill" => fill,
|
29
|
+
"fill-opacity" => opacity,
|
30
|
+
"stroke" => stroke_color,
|
31
|
+
"stroke-opacity" => stroke_opacity
|
30
32
|
}
|
31
33
|
|
32
34
|
dx = (y % 2 == 0) ? 0 : diamond_width / 2
|
33
35
|
|
34
36
|
svg.polyline(diamond, styles.merge(
|
35
|
-
|
37
|
+
"transform" => "translate(#{x * diamond_width - diamond_width / 2 + dx}, #{diamond_height / 2 * y - diamond_height / 2})"
|
38
|
+
))
|
36
39
|
|
37
40
|
# Add an extra one at top-right, for tiling.
|
38
|
-
if
|
41
|
+
if x == 0
|
39
42
|
svg.polyline(diamond, styles.merge(
|
40
|
-
|
43
|
+
"transform" => "translate(#{6 * diamond_width - diamond_width / 2 + dx}, #{diamond_height / 2 * y - diamond_height / 2})"
|
44
|
+
))
|
41
45
|
end
|
42
46
|
|
43
47
|
# Add an extra row at the end that matches the first row, for tiling.
|
44
|
-
if
|
48
|
+
if y == 0
|
45
49
|
svg.polyline(diamond, styles.merge(
|
46
|
-
|
50
|
+
"transform" => "translate(#{x * diamond_width - diamond_width / 2 + dx}, #{diamond_height / 2 * 6 - diamond_height / 2})"
|
51
|
+
))
|
47
52
|
end
|
48
53
|
|
49
54
|
# Add an extra one at bottom-right, for tiling.
|
50
55
|
if x == 0 && y == 0
|
51
56
|
svg.polyline(diamond, styles.merge(
|
52
|
-
|
57
|
+
"transform" => "translate(#{6 * diamond_width - diamond_width / 2 + dx}, #{diamond_height / 2 * 6 - diamond_height / 2})"
|
58
|
+
))
|
53
59
|
end
|
54
60
|
i += 1
|
55
61
|
end
|