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
|
module StructureGenerators
|
3
5
|
class SquaresGenerator < BaseGenerator
|
@@ -13,18 +15,17 @@ module GeoPattern
|
|
13
15
|
|
14
16
|
def generate_structure
|
15
17
|
i = 0
|
16
|
-
|
17
|
-
|
18
|
-
val
|
18
|
+
6.times do |y|
|
19
|
+
6.times do |x|
|
20
|
+
val = hex_val(i, 1)
|
19
21
|
opacity = opacity(val)
|
20
|
-
fill
|
22
|
+
fill = fill_color(val)
|
21
23
|
|
22
24
|
svg.rect(x * square_size, y * square_size, square_size, square_size,
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
)
|
25
|
+
"fill" => fill,
|
26
|
+
"fill-opacity" => opacity,
|
27
|
+
"stroke" => stroke_color,
|
28
|
+
"stroke-opacity" => stroke_opacity)
|
28
29
|
i += 1
|
29
30
|
end
|
30
31
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module StructureGenerators
|
3
5
|
class TessellationGenerator < BaseGenerator
|
@@ -7,30 +9,30 @@ module GeoPattern
|
|
7
9
|
|
8
10
|
def after_initialize
|
9
11
|
# 3.4.6.4 semi-regular tessellation
|
10
|
-
@side_length
|
11
|
-
@hex_height
|
12
|
-
@hex_width
|
12
|
+
@side_length = map(hex_val(0, 1), 0, 15, 5, 40)
|
13
|
+
@hex_height = side_length * Math.sqrt(3)
|
14
|
+
@hex_width = side_length * 2
|
13
15
|
@triangle_height = side_length / 2 * Math.sqrt(3)
|
14
|
-
@triangle
|
15
|
-
@tile_width
|
16
|
-
@tile_height
|
16
|
+
@triangle = build_rotated_triangle_shape(side_length, triangle_height)
|
17
|
+
@tile_width = side_length * 3 + triangle_height * 2
|
18
|
+
@tile_height = (hex_height * 2) + (side_length * 2)
|
17
19
|
|
18
20
|
self.height = tile_height
|
19
|
-
self.width
|
21
|
+
self.width = tile_width
|
20
22
|
end
|
21
23
|
|
22
24
|
def generate_structure
|
23
|
-
|
24
|
-
val
|
25
|
+
20.times do |i|
|
26
|
+
val = hex_val(i, 1)
|
25
27
|
opacity = opacity(val)
|
26
|
-
fill
|
28
|
+
fill = fill_color(val)
|
27
29
|
|
28
|
-
styles
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
styles = {
|
31
|
+
"stroke" => stroke_color,
|
32
|
+
"stroke-opacity" => stroke_opacity,
|
33
|
+
"fill" => fill,
|
34
|
+
"fill-opacity" => opacity,
|
35
|
+
"stroke-width" => 1
|
34
36
|
}
|
35
37
|
|
36
38
|
case i
|
@@ -47,47 +49,47 @@ module GeoPattern
|
|
47
49
|
when 3 # center / bottom square
|
48
50
|
svg.rect(hex_width / 2 + triangle_height, hex_height * 1.5 + side_length, side_length, side_length, styles)
|
49
51
|
when 4 # left top / bottom triangle
|
50
|
-
svg.polyline(triangle, styles.merge(
|
51
|
-
svg.polyline(triangle, styles.merge(
|
52
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{side_length / 2}, #{-side_length / 2}) rotate(0, #{side_length / 2}, #{triangle_height / 2})"))
|
53
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{side_length / 2}, #{tile_height - -side_length / 2}) rotate(0, #{side_length / 2}, #{triangle_height / 2}) scale(1, -1)"))
|
52
54
|
when 5 # right top / bottom triangle
|
53
|
-
svg.polyline(triangle, styles.merge(
|
54
|
-
svg.polyline(triangle, styles.merge(
|
55
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{tile_width - side_length / 2}, #{-side_length / 2}) rotate(0, #{side_length / 2}, #{triangle_height / 2}) scale(-1, 1)"))
|
56
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{tile_width - side_length / 2}, #{tile_height + side_length / 2}) rotate(0, #{side_length / 2}, #{triangle_height / 2}) scale(-1, -1)"))
|
55
57
|
when 6 # center / top / right triangle
|
56
|
-
svg.polyline(triangle, styles.merge(
|
58
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{tile_width / 2 + side_length / 2}, #{hex_height / 2})"))
|
57
59
|
when 7 # center / top / left triangle
|
58
|
-
svg.polyline(triangle, styles.merge(
|
60
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{tile_width - tile_width / 2 - side_length / 2}, #{hex_height / 2}) scale(-1, 1)"))
|
59
61
|
when 8 # center / bottom / right triangle
|
60
|
-
svg.polyline(triangle, styles.merge(
|
62
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{tile_width / 2 + side_length / 2}, #{tile_height - hex_height / 2}) scale(1, -1)"))
|
61
63
|
when 9 # center / bottom / left triangle
|
62
|
-
svg.polyline(triangle, styles.merge(
|
64
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{tile_width - tile_width / 2 - side_length / 2}, #{tile_height - hex_height / 2}) scale(-1, -1)"))
|
63
65
|
when 10 # left / middle triangle
|
64
|
-
svg.polyline(triangle, styles.merge(
|
66
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{side_length / 2}, #{tile_height / 2 - side_length / 2})"))
|
65
67
|
when 11 # right / middle triangle
|
66
|
-
svg.polyline(triangle, styles.merge(
|
68
|
+
svg.polyline(triangle, styles.merge("transform" => "translate(#{tile_width - side_length / 2}, #{tile_height / 2 - side_length / 2}) scale(-1, 1)"))
|
67
69
|
when 12 # left / top square
|
68
70
|
svg.rect(0, 0, side_length, side_length,
|
69
|
-
|
71
|
+
styles.merge("transform" => "translate(#{side_length / 2}, #{side_length / 2}) rotate(-30, 0, 0)"))
|
70
72
|
when 13 # right / top square
|
71
73
|
svg.rect(0, 0, side_length, side_length,
|
72
|
-
|
74
|
+
styles.merge("transform" => "scale(-1, 1) translate(#{-tile_width + side_length / 2}, #{side_length / 2}) rotate(-30, 0, 0)"))
|
73
75
|
when 14 # left / center-top square
|
74
76
|
svg.rect(0, 0, side_length, side_length,
|
75
|
-
|
77
|
+
styles.merge("transform" => "translate(#{side_length / 2}, #{tile_height / 2 - side_length / 2 - side_length}) rotate(30, 0, #{side_length})"))
|
76
78
|
when 15 # right / center-top square
|
77
79
|
svg.rect(0, 0, side_length, side_length,
|
78
|
-
|
80
|
+
styles.merge("transform" => "scale(-1, 1) translate(#{-tile_width + side_length / 2}, #{tile_height / 2 - side_length / 2 - side_length}) rotate(30, 0, #{side_length})"))
|
79
81
|
when 16 # left / center-top square
|
80
82
|
svg.rect(0, 0, side_length, side_length,
|
81
|
-
|
83
|
+
styles.merge("transform" => "scale(1, -1) translate(#{side_length / 2}, #{-tile_height + tile_height / 2 - side_length / 2 - side_length}) rotate(30, 0, #{side_length})"))
|
82
84
|
when 17 # right / center-bottom square
|
83
85
|
svg.rect(0, 0, side_length, side_length,
|
84
|
-
|
86
|
+
styles.merge("transform" => "scale(-1, -1) translate(#{-tile_width + side_length / 2}, #{-tile_height + tile_height / 2 - side_length / 2 - side_length}) rotate(30, 0, #{side_length})"))
|
85
87
|
when 18 # left / bottom square
|
86
88
|
svg.rect(0, 0, side_length, side_length,
|
87
|
-
|
89
|
+
styles.merge("transform" => "scale(1, -1) translate(#{side_length / 2}, #{-tile_height + side_length / 2}) rotate(-30, 0, 0)"))
|
88
90
|
when 19 # right / bottom square
|
89
91
|
svg.rect(0, 0, side_length, side_length,
|
90
|
-
|
92
|
+
styles.merge("transform" => "scale(-1, -1) translate(#{-tile_width + side_length / 2}, #{-tile_height + side_length / 2}) rotate(-30, 0, 0)"))
|
91
93
|
end
|
92
94
|
end
|
93
95
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module StructureGenerators
|
3
5
|
class TrianglesGenerator < BaseGenerator
|
@@ -6,44 +8,45 @@ module GeoPattern
|
|
6
8
|
attr_reader :scale, :side_length, :triangle_height, :triangle
|
7
9
|
|
8
10
|
def after_initialize
|
9
|
-
@scale
|
10
|
-
@side_length
|
11
|
+
@scale = hex_val(0, 1)
|
12
|
+
@side_length = map(scale, 0, 15, 15, 80)
|
11
13
|
@triangle_height = side_length / 2 * Math.sqrt(3)
|
12
|
-
@triangle
|
14
|
+
@triangle = build_triangle_shape(side_length, triangle_height)
|
13
15
|
|
14
|
-
self.width
|
16
|
+
self.width = side_length * 3
|
15
17
|
self.height = triangle_height * 6
|
16
18
|
end
|
17
19
|
|
18
20
|
def generate_structure
|
19
21
|
i = 0
|
20
|
-
|
21
|
-
|
22
|
-
val
|
22
|
+
6.times do |y|
|
23
|
+
6.times do |x|
|
24
|
+
val = hex_val(i, 1)
|
23
25
|
opacity = opacity(val)
|
24
|
-
fill
|
26
|
+
fill = fill_color(val)
|
25
27
|
|
26
28
|
styles = {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
"fill" => fill,
|
30
|
+
"fill-opacity" => opacity,
|
31
|
+
"stroke" => stroke_color,
|
32
|
+
"stroke-opacity" => stroke_opacity
|
31
33
|
}
|
32
34
|
|
33
|
-
rotation =
|
34
|
-
|
35
|
-
rotation = x % 2 == 0 ? 180 : 0
|
35
|
+
rotation = if y % 2 == 0
|
36
|
+
(x % 2 == 0) ? 180 : 0
|
36
37
|
else
|
37
|
-
|
38
|
+
(x % 2 != 0) ? 180 : 0
|
38
39
|
end
|
39
40
|
|
40
41
|
svg.polyline(triangle, styles.merge(
|
41
|
-
|
42
|
+
"transform" => "translate(#{x * side_length * 0.5 - side_length / 2}, #{triangle_height * y}) rotate(#{rotation}, #{side_length / 2}, #{triangle_height / 2})"
|
43
|
+
))
|
42
44
|
|
43
45
|
# Add an extra one at top-right, for tiling.
|
44
|
-
if
|
46
|
+
if x == 0
|
45
47
|
svg.polyline(triangle, styles.merge(
|
46
|
-
|
48
|
+
"transform" => "translate(#{6 * side_length * 0.5 - side_length / 2}, #{triangle_height * y}) rotate(#{rotation}, #{side_length / 2}, #{triangle_height / 2})"
|
49
|
+
))
|
47
50
|
end
|
48
51
|
i += 1
|
49
52
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
module StructureGenerators
|
3
5
|
class XesGenerator < BaseGenerator
|
@@ -7,54 +9,59 @@ module GeoPattern
|
|
7
9
|
|
8
10
|
def after_initialize
|
9
11
|
@square_size = map(hex_val(0, 1), 0, 15, 10, 25)
|
10
|
-
@x_shape
|
11
|
-
@x_size
|
12
|
+
@x_shape = build_plus_shape(square_size) # rotated later
|
13
|
+
@x_size = square_size * 3 * 0.943
|
12
14
|
|
13
15
|
self.height = self.width = x_size * 3
|
14
16
|
end
|
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
|
-
dy
|
23
|
-
fill
|
24
|
+
dy = (x % 2 == 0) ? y * x_size - x_size * 0.5 : y * x_size - x_size * 0.5 + x_size / 4
|
25
|
+
fill = fill_color(val)
|
24
26
|
|
25
27
|
styles = {
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
"fill" => fill,
|
29
|
+
"style" => {
|
30
|
+
"opacity" => opacity
|
29
31
|
}
|
30
32
|
}
|
31
33
|
|
32
34
|
svg.group(x_shape, styles.merge(
|
33
|
-
|
35
|
+
"transform" => "translate(#{x * x_size / 2 - x_size / 2},#{dy - y * x_size / 2}) rotate(45, #{x_size / 2}, #{x_size / 2})"
|
36
|
+
))
|
34
37
|
|
35
38
|
# Add an extra column on the right for tiling.
|
36
|
-
if
|
39
|
+
if x == 0
|
37
40
|
svg.group(x_shape, styles.merge(
|
38
|
-
|
41
|
+
"transform" => "translate(#{6 * x_size / 2 - x_size / 2},#{dy - y * x_size / 2}) rotate(45, #{x_size / 2}, #{x_size / 2})"
|
42
|
+
))
|
39
43
|
end
|
40
44
|
|
41
45
|
# Add an extra row on the bottom that matches the first row, for tiling.
|
42
|
-
if
|
43
|
-
dy = x % 2 == 0 ? 6 * x_size - x_size / 2 : 6 * x_size - x_size / 2 + x_size / 4
|
46
|
+
if y == 0
|
47
|
+
dy = (x % 2 == 0) ? 6 * x_size - x_size / 2 : 6 * x_size - x_size / 2 + x_size / 4
|
44
48
|
svg.group(x_shape, styles.merge(
|
45
|
-
|
49
|
+
"transform" => "translate(#{x * x_size / 2 - x_size / 2},#{dy - 6 * x_size / 2}) rotate(45, #{x_size / 2}, #{x_size / 2})"
|
50
|
+
))
|
46
51
|
end
|
47
52
|
|
48
53
|
# These can hang off the bottom, so put a row at the top for tiling.
|
49
|
-
if
|
54
|
+
if y == 5
|
50
55
|
svg.group(x_shape, styles.merge(
|
51
|
-
|
56
|
+
"transform" => "translate(#{x * x_size / 2 - x_size / 2},#{dy - 11 * x_size / 2}) rotate(45, #{x_size / 2}, #{x_size / 2})"
|
57
|
+
))
|
52
58
|
end
|
53
59
|
|
54
60
|
# Add an extra one at top-right and bottom-right, for tiling.
|
55
61
|
if x == 0 && y == 0
|
56
62
|
svg.group(x_shape, styles.merge(
|
57
|
-
|
63
|
+
"transform" => "translate(#{6 * x_size / 2 - x_size / 2},#{dy - 6 * x_size / 2}) rotate(45, #{x_size / 2}, #{x_size / 2})"
|
64
|
+
))
|
58
65
|
end
|
59
66
|
i += 1
|
60
67
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module GeoPattern
|
2
4
|
class SvgImage
|
3
5
|
include Comparable
|
@@ -11,9 +13,9 @@ module GeoPattern
|
|
11
13
|
attr_reader :height, :width
|
12
14
|
|
13
15
|
def initialize
|
14
|
-
@width
|
15
|
-
@height
|
16
|
-
@svg_string =
|
16
|
+
@width = 100
|
17
|
+
@height = 100
|
18
|
+
@svg_string = +""
|
17
19
|
end
|
18
20
|
|
19
21
|
def width=(width)
|
@@ -37,7 +39,7 @@ module GeoPattern
|
|
37
39
|
end
|
38
40
|
|
39
41
|
def svg_closer
|
40
|
-
|
42
|
+
"</svg>"
|
41
43
|
end
|
42
44
|
|
43
45
|
def to_s
|
@@ -70,16 +72,16 @@ module GeoPattern
|
|
70
72
|
|
71
73
|
def group(elements, args = {})
|
72
74
|
svg_string << %(<g #{write_args(args)}>)
|
73
|
-
elements.each { |e| eval e }
|
75
|
+
elements.each { |e| eval e } # rubocop:disable Security/Eval
|
74
76
|
svg_string << %(</g>)
|
75
77
|
end
|
76
78
|
|
77
79
|
def write_args(args)
|
78
|
-
str =
|
79
|
-
args.each do|key, value|
|
80
|
+
str = +""
|
81
|
+
args.each do |key, value|
|
80
82
|
if value.is_a?(Hash)
|
81
83
|
str << %(#{key}=")
|
82
|
-
value.each do|k, v|
|
84
|
+
value.each do |k, v|
|
83
85
|
str << %(#{k}:#{v};)
|
84
86
|
end
|
85
87
|
str << %(" )
|
data/lib/geo_pattern/version.rb
CHANGED
data/lib/geo_pattern.rb
CHANGED
@@ -1,56 +1,58 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
require
|
7
|
-
|
8
|
-
require
|
9
|
-
|
10
|
-
|
11
|
-
require
|
12
|
-
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
|
24
|
-
require
|
25
|
-
|
26
|
-
|
27
|
-
require
|
28
|
-
|
29
|
-
|
30
|
-
require
|
31
|
-
|
32
|
-
require
|
33
|
-
|
34
|
-
require
|
35
|
-
require
|
36
|
-
require
|
37
|
-
require
|
38
|
-
require
|
39
|
-
require
|
40
|
-
require
|
41
|
-
require
|
42
|
-
require
|
43
|
-
require
|
44
|
-
require
|
45
|
-
require
|
46
|
-
require
|
47
|
-
require
|
48
|
-
require
|
49
|
-
|
50
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "base64"
|
4
|
+
require "digest/sha1"
|
5
|
+
require "color"
|
6
|
+
require "forwardable"
|
7
|
+
|
8
|
+
require "geo_pattern/version"
|
9
|
+
|
10
|
+
require "geo_pattern/roles/named_generator"
|
11
|
+
require "geo_pattern/roles/comparable_metadata"
|
12
|
+
|
13
|
+
require "geo_pattern/errors"
|
14
|
+
require "geo_pattern/color"
|
15
|
+
require "geo_pattern/svg_image"
|
16
|
+
require "geo_pattern/pattern_helpers"
|
17
|
+
require "geo_pattern/helpers"
|
18
|
+
require "geo_pattern/pattern_store"
|
19
|
+
require "geo_pattern/pattern_validator"
|
20
|
+
require "geo_pattern/pattern_sieve"
|
21
|
+
require "geo_pattern/pattern"
|
22
|
+
require "geo_pattern/seed"
|
23
|
+
require "geo_pattern/pattern_preset"
|
24
|
+
require "geo_pattern/color_preset"
|
25
|
+
|
26
|
+
require "geo_pattern/structure"
|
27
|
+
require "geo_pattern/background"
|
28
|
+
|
29
|
+
require "geo_pattern/color_generators/simple_generator"
|
30
|
+
require "geo_pattern/color_generators/base_color_generator"
|
31
|
+
|
32
|
+
require "geo_pattern/background_generators/solid_generator"
|
33
|
+
|
34
|
+
require "geo_pattern/structure_generators/base_generator"
|
35
|
+
require "geo_pattern/structure_generators/chevrons_generator"
|
36
|
+
require "geo_pattern/structure_generators/concentric_circles_generator"
|
37
|
+
require "geo_pattern/structure_generators/diamonds_generator"
|
38
|
+
require "geo_pattern/structure_generators/hexagons_generator"
|
39
|
+
require "geo_pattern/structure_generators/mosaic_squares_generator"
|
40
|
+
require "geo_pattern/structure_generators/nested_squares_generator"
|
41
|
+
require "geo_pattern/structure_generators/octagons_generator"
|
42
|
+
require "geo_pattern/structure_generators/overlapping_circles_generator"
|
43
|
+
require "geo_pattern/structure_generators/overlapping_rings_generator"
|
44
|
+
require "geo_pattern/structure_generators/plaid_generator"
|
45
|
+
require "geo_pattern/structure_generators/plus_signs_generator"
|
46
|
+
require "geo_pattern/structure_generators/sine_waves_generator"
|
47
|
+
require "geo_pattern/structure_generators/squares_generator"
|
48
|
+
require "geo_pattern/structure_generators/tessellation_generator"
|
49
|
+
require "geo_pattern/structure_generators/triangles_generator"
|
50
|
+
require "geo_pattern/structure_generators/xes_generator"
|
51
|
+
|
52
|
+
require "geo_pattern/pattern_generator"
|
51
53
|
|
52
54
|
module GeoPattern
|
53
55
|
def self.generate(string = Time.now, opts = {})
|
54
|
-
GeoPattern::PatternGenerator.new(string.to_s, opts).generate
|
56
|
+
GeoPattern::PatternGenerator.new(string.to_s, **opts).generate
|
55
57
|
end
|
56
58
|
end
|
data/script/console
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
RSpec.describe BackgroundGenerators::SolidGenerator do
|
4
|
-
subject(:generator) {
|
6
|
+
subject(:generator) { described_class.new(seed, preset) }
|
5
7
|
|
6
|
-
let(:seed) { instance_double(
|
7
|
-
let(:preset) { instance_double(
|
8
|
-
let(:pattern) { instance_double(
|
9
|
-
let(:background_metadata) { instance_double(
|
8
|
+
let(:seed) { instance_double("GeoPattern::Seed") }
|
9
|
+
let(:preset) { instance_double("GeoPattern::ColorPreset") }
|
10
|
+
let(:pattern) { instance_double("GeoPattern::Pattern") }
|
11
|
+
let(:background_metadata) { instance_double("GeoPattern::BackgroundMetadata") }
|
10
12
|
|
11
|
-
let(:color) {
|
12
|
-
let(:base_color) {
|
13
|
+
let(:color) { "#aaaaaa" }
|
14
|
+
let(:base_color) { "#bbbbbb" }
|
13
15
|
let(:base_color_should_be_used) { true }
|
14
16
|
|
15
17
|
before :each do
|
@@ -23,9 +25,9 @@ RSpec.describe BackgroundGenerators::SolidGenerator do
|
|
23
25
|
|
24
26
|
it { is_expected.not_to be_nil }
|
25
27
|
|
26
|
-
describe
|
27
|
-
context
|
28
|
-
let(:generated_color) { %w
|
28
|
+
describe "#generate" do
|
29
|
+
context "when base color is given" do
|
30
|
+
let(:generated_color) { %w[187 187 187] }
|
29
31
|
|
30
32
|
before :each do
|
31
33
|
expect(pattern).to receive(:background=).with(have_image_with_rgb_color(generated_color))
|
@@ -34,9 +36,9 @@ RSpec.describe BackgroundGenerators::SolidGenerator do
|
|
34
36
|
it { generator.generate(pattern) }
|
35
37
|
end
|
36
38
|
|
37
|
-
context
|
39
|
+
context "when color is given" do
|
38
40
|
let(:base_color_should_be_used) { false }
|
39
|
-
let(:generated_color) { %w
|
41
|
+
let(:generated_color) { %w[170 170 170] }
|
40
42
|
|
41
43
|
before :each do
|
42
44
|
expect(pattern).to receive(:background=).with(have_image_with_rgb_color(generated_color))
|
@@ -45,6 +47,6 @@ RSpec.describe BackgroundGenerators::SolidGenerator do
|
|
45
47
|
it { generator.generate(pattern) }
|
46
48
|
end
|
47
49
|
|
48
|
-
it_behaves_like
|
50
|
+
it_behaves_like "a named generator", :solid
|
49
51
|
end
|
50
52
|
end
|
data/spec/background_spec.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
RSpec.describe Background do
|
4
6
|
subject(:metadata) { described_class.new(image: svg_image, preset: preset, generator: generator, color: color) }
|
5
7
|
|
6
|
-
let(:svg_image) { instance_double(
|
7
|
-
let(:svg_image_content) { fixtures_path(
|
8
|
-
let(:preset) { instance_double(
|
9
|
-
let(:generator) { stub_const(
|
8
|
+
let(:svg_image) { instance_double("GeoPattern::SvgImage") }
|
9
|
+
let(:svg_image_content) { fixtures_path("generated_patterns/sine_waves.svg").read.chomp }
|
10
|
+
let(:preset) { instance_double("GeoPattern::ColorPreset") }
|
11
|
+
let(:generator) { stub_const("GeoPattern::BackgroundGenerators::SolidGenerator", Class.new) }
|
10
12
|
|
11
|
-
let(:color) {
|
12
|
-
let(:base_color) {
|
13
|
+
let(:color) { "#aaaaaa" }
|
14
|
+
let(:base_color) { "#bbbbbb" }
|
13
15
|
|
14
16
|
it { is_expected.not_to be_nil }
|
15
17
|
|
@@ -18,8 +20,8 @@ RSpec.describe Background do
|
|
18
20
|
allow(preset).to receive(:base_color).and_return(base_color)
|
19
21
|
end
|
20
22
|
|
21
|
-
it_behaves_like
|
22
|
-
it_behaves_like
|
23
|
-
it_behaves_like
|
24
|
-
it_behaves_like
|
23
|
+
it_behaves_like "a metadata argument", :color
|
24
|
+
it_behaves_like "a metadata argument", :generator
|
25
|
+
it_behaves_like "a forwarded metadata argument", :base_color
|
26
|
+
it_behaves_like "a forwarded metadata argument", :color
|
25
27
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
RSpec.describe ColorGenerators::BaseColorGenerator do
|
4
6
|
subject(:generator) { described_class.new(color_string, seed) }
|
5
7
|
|
6
|
-
let(:seed) { instance_double(
|
8
|
+
let(:seed) { instance_double("GeoPattern::Seed") }
|
7
9
|
let(:seed_value1) { 2616 }
|
8
10
|
let(:seed_value2) { 2 }
|
9
11
|
|
10
|
-
let(:color_string) {
|
12
|
+
let(:color_string) { "#ff00ff" }
|
11
13
|
|
12
14
|
it { is_expected.not_to be_nil }
|
13
15
|
|
@@ -16,16 +18,16 @@ RSpec.describe ColorGenerators::BaseColorGenerator do
|
|
16
18
|
allow(seed).to receive(:to_i).with(17, 1).and_return(seed_value2)
|
17
19
|
end
|
18
20
|
|
19
|
-
describe
|
21
|
+
describe "#generate" do
|
20
22
|
let(:color) { generator.generate }
|
21
23
|
|
22
|
-
context
|
23
|
-
it { expect(color.to_svg).to eq
|
24
|
+
context "when sat offset is % 2 == 0" do
|
25
|
+
it { expect(color.to_svg).to eq "rgb(210, 255, 0)" }
|
24
26
|
end
|
25
27
|
|
26
|
-
context
|
28
|
+
context "when sat offset is not % 2 == 0" do
|
27
29
|
let(:seed_value2) { 3 }
|
28
|
-
it { expect(color.to_svg).to eq
|
30
|
+
it { expect(color.to_svg).to eq "rgb(207, 251, 4)" }
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|