geo_pattern 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,76 @@
1
+ module GeoPattern
2
+ class MosaicSquaresPattern < BasePattern
3
+ def render_to_svg
4
+ triangle_size = map(hex_val(0, 1), 0, 15, 15, 50)
5
+
6
+ svg.set_width(triangle_size * 8)
7
+ svg.set_height(triangle_size * 8)
8
+
9
+ i = 0
10
+ for y in 0..3
11
+ for x in 0..3
12
+ if x.even?
13
+ if y.even?
14
+ draw_outer_mosaic_tile(x*triangle_size*2, y*triangle_size*2, triangle_size, hex_val(i, 1))
15
+ else
16
+ draw_inner_mosaic_tile(x*triangle_size*2, y*triangle_size*2, triangle_size, [hex_val(i, 1), hex_val(i+1, 1)])
17
+ end
18
+ else
19
+ if y.even?
20
+ draw_inner_mosaic_tile(x*triangle_size*2, y*triangle_size*2, triangle_size, [hex_val(i, 1), hex_val(i+1, 1)])
21
+ else
22
+ draw_outer_mosaic_tile(x*triangle_size*2, y*triangle_size*2, triangle_size, hex_val(i, 1))
23
+ end
24
+ end
25
+ i += 1
26
+ end
27
+ end
28
+ end
29
+
30
+ def draw_inner_mosaic_tile(x, y, triangle_size, vals)
31
+ triangle = build_right_triangle_shape(triangle_size)
32
+ opacity = opacity(vals[0])
33
+ fill = fill_color(vals[0])
34
+ styles = {
35
+ "stroke" => STROKE_COLOR,
36
+ "stroke-opacity" => STROKE_OPACITY,
37
+ "fill-opacity" => opacity,
38
+ "fill" => fill
39
+ }
40
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x+triangle_size}, #{y}) scale(-1, 1)"}))
41
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x+triangle_size}, #{y+triangle_size*2}) scale(1, -1)"}))
42
+
43
+ opacity = opacity(vals[1])
44
+ fill = fill_color(vals[1])
45
+ styles = {
46
+ "stroke" => STROKE_COLOR,
47
+ "stroke-opacity" => STROKE_OPACITY,
48
+ "fill-opacity" => opacity,
49
+ "fill" => fill
50
+ }
51
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x+triangle_size}, #{y+triangle_size*2}) scale(-1, -1)"}))
52
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x+triangle_size}, #{y}) scale(1, 1)"}))
53
+ end
54
+
55
+ def draw_outer_mosaic_tile(x, y, triangle_size, val)
56
+ opacity = opacity(val)
57
+ fill = fill_color(val)
58
+ triangle = build_right_triangle_shape(triangle_size)
59
+ styles = {
60
+ "stroke" => STROKE_COLOR,
61
+ "stroke-opacity" => STROKE_OPACITY,
62
+ "fill-opacity" => opacity,
63
+ "fill" => fill
64
+ }
65
+
66
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x}, #{y+triangle_size}) scale(1, -1)"}))
67
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x+triangle_size*2}, #{y+triangle_size}) scale(-1, -1)"}))
68
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x}, #{y+triangle_size}) scale(1, 1)"}))
69
+ svg.polyline(triangle, styles.merge({"transform" => "translate(#{x+triangle_size*2}, #{y+triangle_size}) scale(-1, 1)"}))
70
+ end
71
+
72
+ def build_right_triangle_shape(side_length)
73
+ "0, 0, #{side_length}, #{side_length}, 0, #{side_length}, 0, 0"
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,51 @@
1
+ module GeoPattern
2
+ class NestedSquaresPattern < BasePattern
3
+ def render_to_svg
4
+ block_size = map(hex_val(0, 1), 0, 15, 4, 12)
5
+ square_size = block_size * 7
6
+
7
+ svg.set_width((square_size + block_size)*6 + block_size*6)
8
+ svg.set_height((square_size + block_size)*6 + block_size*6)
9
+
10
+ i = 0
11
+ for y in 0..5
12
+ for x in 0..5
13
+ val = hex_val(i, 1)
14
+ opacity = opacity(val)
15
+ fill = fill_color(val)
16
+
17
+ styles = {
18
+ "fill" => "none",
19
+ "stroke" => fill,
20
+ "style" => {
21
+ "opacity" => opacity,
22
+ "stroke-width" => "#{block_size}px"
23
+ }
24
+ }
25
+
26
+ svg.rect(x*square_size + x*block_size*2 + block_size/2,
27
+ y*square_size + y*block_size*2 + block_size/2,
28
+ square_size, square_size, styles)
29
+
30
+ val = hex_val(39-i, 1)
31
+ opacity = opacity(val)
32
+ fill = fill_color(val)
33
+
34
+ styles = {
35
+ "fill" => "none",
36
+ "stroke" => fill,
37
+ "style" => {
38
+ "opacity" => opacity,
39
+ "stroke-width" => "#{block_size}px"
40
+ }
41
+ }
42
+
43
+ svg.rect(x*square_size + x*block_size*2 + block_size/2 + block_size*2,
44
+ y*square_size + y*block_size*2 + block_size/2 + block_size*2,
45
+ block_size * 3, block_size * 3, styles)
46
+ i += 1
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
1
+ module GeoPattern
2
+ class OctagonPattern < BasePattern
3
+ def render_to_svg
4
+ square_size = map(hex_val(0, 1), 0, 15, 10, 60)
5
+ tile = build_octogon_shape(square_size)
6
+
7
+ svg.set_width(square_size * 6)
8
+ svg.set_height(square_size * 6)
9
+
10
+ i = 0
11
+ for y in 0..5
12
+ for x in 0..5
13
+ val = hex_val(i, 1)
14
+ opacity = opacity(val)
15
+ fill = fill_color(val)
16
+
17
+ svg.polyline(tile, {
18
+ "fill" => fill,
19
+ "fill-opacity" => opacity,
20
+ "stroke" => STROKE_COLOR,
21
+ "stroke-opacity" => STROKE_OPACITY,
22
+ "transform" => "translate(#{x*square_size}, #{y*square_size})"
23
+ })
24
+ i += 1
25
+ end
26
+ end
27
+ end
28
+
29
+ def build_octogon_shape(square_size)
30
+ s = square_size
31
+ c = s * 0.33
32
+ "#{c},0,#{s-c},0,#{s},#{c},#{s},#{s-c},#{s-c},#{s},#{c},#{s},0,#{s-c},0,#{c},#{c},0"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,46 @@
1
+ module GeoPattern
2
+ class OverlappingCirclesPattern < BasePattern
3
+ def render_to_svg
4
+ scale = hex_val(0, 1)
5
+ diameter = map(scale, 0, 15, 25, 200)
6
+ radius = diameter/2;
7
+
8
+ svg.set_width(radius * 6)
9
+ svg.set_height(radius * 6)
10
+
11
+ i = 0
12
+ for y in 0..5
13
+ for x in 0..5
14
+ val = hex_val(i, 1)
15
+ opacity = opacity(val)
16
+ fill = fill_color(val)
17
+
18
+ styles = {
19
+ "fill" => fill,
20
+ "style" => {
21
+ "opacity" => opacity
22
+ }
23
+ }
24
+
25
+ svg.circle(x*radius, y*radius, radius, styles)
26
+
27
+ # Add an extra one at top-right, for tiling.
28
+ if (x == 0)
29
+ svg.circle(6*radius, y*radius, radius, styles)
30
+ end
31
+
32
+ # Add an extra row at the end that matches the first row, for tiling.
33
+ if (y == 0)
34
+ svg.circle(x*radius, 6*radius, radius, styles)
35
+ end
36
+
37
+ # Add an extra one at bottom-right, for tiling.
38
+ if (x == 0 and y == 0)
39
+ svg.circle(6*radius, 6*radius, radius, styles)
40
+ end
41
+ i += 1
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ module GeoPattern
2
+ class OverlappingRingsPattern < BasePattern
3
+ def render_to_svg
4
+ scale = hex_val(0, 1)
5
+ ring_size = map(scale, 0, 15, 10, 60)
6
+ stroke_width = ring_size / 4
7
+
8
+ svg.set_width(ring_size * 6)
9
+ svg.set_height(ring_size * 6)
10
+
11
+ i = 0
12
+ for y in 0..5
13
+ for x in 0..5
14
+ val = hex_val(i, 1)
15
+ opacity = opacity(val)
16
+ fill = fill_color(val)
17
+
18
+ styles = {
19
+ "fill" => "none",
20
+ "stroke" => fill,
21
+ "style" => {
22
+ "opacity" => opacity,
23
+ "stroke-width" => "#{stroke_width}px"
24
+ }
25
+ }
26
+
27
+ svg.circle(x*ring_size, y*ring_size, ring_size - stroke_width/2, styles)
28
+
29
+ # Add an extra one at top-right, for tiling.
30
+ if (x == 0)
31
+ svg.circle(6*ring_size, y*ring_size, ring_size - stroke_width/2, styles)
32
+ end
33
+
34
+ if (y == 0)
35
+ svg.circle(x*ring_size, 6*ring_size, ring_size - stroke_width/2, styles)
36
+ end
37
+
38
+ if (x == 0 and y == 0)
39
+ svg.circle(6*ring_size, 6*ring_size, ring_size - stroke_width/2, styles)
40
+ end
41
+ i += 1
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,19 @@
1
+ Dir[File.join(File.dirname(__FILE__), '**', '*.rb')].each { |file| require file }
2
+
3
+ module GeoPattern
4
+ module PatternHelpers
5
+ def self.hex_val(hash, index, length)
6
+ hash[index, length || 1].to_i(16)
7
+ end
8
+
9
+ # Ruby implementation of Processing's map function
10
+ # http://processing.org/reference/map_.html
11
+ def self.map(value, v_min, v_max, d_min, d_max) # v for value, d for desired
12
+ v_value = value.to_f # so it returns float
13
+
14
+ v_range = v_max - v_min
15
+ d_range = d_max - d_min
16
+ (v_value - v_min) * d_range / v_range + d_min
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,49 @@
1
+ module GeoPattern
2
+ class PlaidPattern < BasePattern
3
+ def render_to_svg
4
+ height = 0
5
+ width = 0
6
+
7
+ # horizontal stripes
8
+ i = 0
9
+ 18.times do
10
+ space = hex_val(i, 1)
11
+ height += space + 5
12
+
13
+ val = hex_val(i+1, 1)
14
+ opacity = opacity(val)
15
+ fill = fill_color(val)
16
+ stripe_height = val + 5
17
+
18
+ svg.rect(0, height, "100%", stripe_height, {
19
+ "opacity" => opacity,
20
+ "fill" => fill
21
+ })
22
+ height += stripe_height
23
+ i += 2
24
+ end
25
+
26
+ # vertical stripes
27
+ i = 0
28
+ 18.times do
29
+ space = hex_val(i, 1)
30
+ width += space + 5
31
+
32
+ val = hex_val(i+1, 1)
33
+ opacity = opacity(val)
34
+ fill = fill_color(val)
35
+ stripe_width = val + 5
36
+
37
+ svg.rect(width, 0, stripe_width, "100%", {
38
+ "opacity" => opacity,
39
+ "fill" => fill
40
+ })
41
+ width += stripe_width
42
+ i += 2
43
+ end
44
+
45
+ svg.set_width(width)
46
+ svg.set_height(height)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,53 @@
1
+ module GeoPattern
2
+ class PlusSignPattern < BasePattern
3
+ def render_to_svg
4
+ square_size = map(hex_val(0, 1), 0, 15, 10, 25)
5
+ plus_size = square_size * 3
6
+ plus_shape = build_plus_shape(square_size)
7
+
8
+ svg.set_width(square_size * 12)
9
+ svg.set_height(square_size * 12)
10
+
11
+ i = 0
12
+ for y in 0..5
13
+ for x in 0..5
14
+ val = hex_val(i, 1)
15
+ opacity = opacity(val)
16
+ fill = fill_color(val)
17
+ dx = (y % 2 == 0) ? 0 : 1
18
+
19
+ styles = {
20
+ "fill" => fill,
21
+ "stroke" => STROKE_COLOR,
22
+ "stroke-opacity" => STROKE_OPACITY,
23
+ "style" => {
24
+ "fill-opacity" => opacity
25
+ }
26
+ }
27
+
28
+ svg.group(plus_shape, styles.merge({
29
+ "transform" => "translate(#{x*plus_size - x*square_size + dx*square_size - square_size},#{y*plus_size - y*square_size - plus_size/2})"}))
30
+
31
+ # Add an extra column on the right for tiling.
32
+ if (x == 0)
33
+ svg.group(plus_shape, styles.merge({
34
+ "transform" => "translate(#{4*plus_size - x*square_size + dx*square_size - square_size},#{y*plus_size - y*square_size - plus_size/2})"}))
35
+ end
36
+
37
+ # Add an extra row on the bottom that matches the first row, for tiling.
38
+ if (y == 0)
39
+ svg.group(plus_shape, styles.merge({
40
+ "transform" => "translate(#{x*plus_size - x*square_size + dx*square_size - square_size},#{4*plus_size - y*square_size - plus_size/2})"}))
41
+ end
42
+
43
+ # Add an extra one at top-right and bottom-right, for tiling.
44
+ if (x == 0 && y == 0)
45
+ svg.group(plus_shape, styles.merge({
46
+ "transform" => "translate(#{4*plus_size - x*square_size + dx*square_size - square_size},#{4*plus_size - y*square_size - plus_size/2})"}))
47
+ end
48
+ i += 1
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,36 @@
1
+ module GeoPattern
2
+ class SineWavePattern < BasePattern
3
+ def render_to_svg
4
+ period = map(hex_val(0, 1), 0, 15, 100, 400).floor
5
+ amplitude = map(hex_val(1, 1), 0, 15, 30, 100).floor
6
+ wave_width = map(hex_val(2, 1), 0, 15, 3, 30).floor
7
+
8
+ svg.set_width(period)
9
+ svg.set_height(wave_width * 36)
10
+
11
+ for i in 0..35
12
+ val = hex_val(i, 1)
13
+ opacity = opacity(val)
14
+ fill = fill_color(val)
15
+ x_offset = period / 4 * 0.7
16
+
17
+ styles = {
18
+ "fill" => "none",
19
+ "stroke" => fill,
20
+ "style" => {
21
+ "opacity" => opacity,
22
+ "stroke-width" => "#{wave_width}px"
23
+ }
24
+ }
25
+
26
+ str = "M0 "+amplitude.to_s+
27
+ " C "+x_offset.to_s+" 0, "+(period/2 - x_offset).to_s+" 0, "+(period/2).to_s+" "+amplitude.to_s+
28
+ " S "+(period-x_offset).to_s+" "+(amplitude*2).to_s+", "+period.to_s+" "+amplitude.to_s+
29
+ " S "+(period*1.5-x_offset).to_s+" 0, "+(period*1.5).to_s+", "+amplitude.to_s;
30
+
31
+ svg.path(str, styles.merge({"transform" => "translate(-#{period/4}, #{wave_width*i-amplitude*1.5})"}))
32
+ svg.path(str, styles.merge({"transform" => "translate(-#{period/4}, #{wave_width*i-amplitude*1.5 + wave_width*36})"}))
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module GeoPattern
2
+ class SquarePattern < BasePattern
3
+ def render_to_svg
4
+ square_size = map(hex_val(0, 1), 0, 15, 10, 60)
5
+
6
+ svg.set_width(square_size * 6)
7
+ svg.set_height(square_size * 6)
8
+
9
+ i = 0
10
+ for y in 0..5
11
+ for x in 0..5
12
+ val = hex_val(i, 1)
13
+ opacity = opacity(val)
14
+ fill = fill_color(val)
15
+
16
+ svg.rect(x*square_size, y*square_size, square_size, square_size, {
17
+ "fill" => fill,
18
+ "fill-opacity" => opacity,
19
+ "stroke" => STROKE_COLOR,
20
+ "stroke-opacity" => STROKE_OPACITY
21
+ })
22
+ i += 1
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end