icodi 0.1.1 → 0.1.2

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -12
  3. data/lib/icodi.rb +72 -39
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c658ed87b6473e55b975104c7578b27ee558df59623a710d89637fd168acb528
4
- data.tar.gz: e5c37860c467df8b4daa3046352812ee036cf3f5197530aa8c83f4d8ae76d972
3
+ metadata.gz: 9d272a6dc8d9e595006ce36f72421892a2381cb0d51285e2390143d257c9f119
4
+ data.tar.gz: e7fc61dfee1364269ffe07d4100b14fa7b48ec100680ed5094b6e40b673ea6c3
5
5
  SHA512:
6
- metadata.gz: c8f9a6b9bee3066dffa76ca91def8f199aed7fc15b0c21828b5f6add814e464a02e4138eac8dffb1b64dca07dc17870e8d23765c481db5112103c8caf1c67813
7
- data.tar.gz: 1da2da19a46676aa49a7b4dd01eb90ba5d7f86703aaf8946febbb5777c709128dc0d04b6c4da431e560ffbdc00c1ac242feca8bc6fe685761807349f374a2cac
6
+ metadata.gz: 86b7e257b95b0ead2d4ec44ee27edb3187cafa18ba519f99776831520502294b6a47c80732cc71abbf5f3e544a17307f449d66153391b8d806c7df03298a6b86
7
+ data.tar.gz: 68fa6d9f3ed793c99f3cdce6437781026e2bd44c8192bae60e8925988ec8b496840083bbf4a5c2314b1a6fa33f4069e0d150413928e91054fe6d35f71d54bdd4
data/README.md CHANGED
@@ -5,6 +5,7 @@ Icodi - Deterministic Random SVG Icon Generator
5
5
 
6
6
  [![Gem Version](https://badge.fury.io/rb/icodi.svg)](https://badge.fury.io/rb/icodi)
7
7
  [![Build Status](https://travis-ci.com/DannyBen/icodi.svg?branch=master)](https://travis-ci.com/DannyBen/icodi)
8
+ [![Maintainability](https://api.codeclimate.com/v1/badges/0b74be3877413501c7a9/maintainability)](https://codeclimate.com/github/DannyBen/icodi/maintainability)
8
9
 
9
10
  ---
10
11
 
@@ -13,6 +14,16 @@ Generate repeatable random SVG icons from any string, similar to
13
14
 
14
15
  ---
15
16
 
17
+ Table of Contents
18
+ --------------------------------------------------
19
+
20
+ - [Installation](#installation)
21
+ - [Examples](#examples)
22
+ - [Usage](#usage)
23
+ - [Options](#options)
24
+ - [Using with Sinatra](#using-with-sinatra)
25
+
26
+
16
27
  Installation
17
28
  --------------------------------------------------
18
29
 
@@ -23,33 +34,41 @@ Installation
23
34
  Examples
24
35
  --------------------------------------------------
25
36
 
26
- ### Grid: 5x5, Mirror: X (default options)
37
+ ### Grid: 5x5, Mirror: X (default settings)
27
38
 
28
- ![sample](assets/sample-strip-default.svg)
39
+ ![strip1](assets/strip_default.svg)
29
40
 
30
- ### Grid: 6x6, Mirror: Y
41
+ ### Grid: 6x6, Mirror: Y, Stroke: 4
31
42
 
32
- ![sample](assets/sample-strip-6y.svg)
43
+ ![strip2](assets/strip_mirror_y.svg)
33
44
 
34
- ### Grid: 8x8, Mirror: X/Y, Density: 0.3
45
+ ### Grid: 8x8, Stroke: 7, Density: 0.3
35
46
 
36
- ![sample](assets/sample-strip-8xylow.svg)
47
+ ![strip3](assets/strip_thick_stroke.svg)
37
48
 
38
- ### Grid: 8x8, Mirror: X/Y, Density: 0.8
49
+ ### Grid: 7x7, Mirror: X/Y, Stroke: 3, Density: 0.8
39
50
 
40
- ![sample](assets/sample-strip-8xyhigh.svg)
51
+ ![strip4](assets/strip_mirror_both.svg)
52
+
53
+ ### Grid: 5x5, Jitter: 0.9, Stroke: 2
54
+
55
+ ![strip4](assets/strip_jitter.svg)
41
56
 
42
57
  ### Increasing Stroke: 0.1 - 5.0
43
58
 
44
- ![sample](assets/sample-strip-stroke.svg)
59
+ ![strip5](assets/strip_strokes.svg)
45
60
 
46
61
  ### Increasing Density: 0.3 - 0.8
47
62
 
48
- ![sample](assets/sample-strip-density.svg)
63
+ ![strip6](assets/strip_densities.svg)
64
+
65
+ ### Increasing Jitter: 0 - 1.0
66
+
67
+ ![strip6](assets/strip_jitters.svg)
49
68
 
50
69
  ### Mirror Styles: X, Y, Both, None
51
70
 
52
- ![sample](assets/sample-strip-mirrors.svg)
71
+ ![strip7](assets/strip_mirrors.svg)
53
72
 
54
73
 
55
74
  Usage
@@ -98,13 +117,23 @@ Parameter | Default | Type | Description
98
117
  ------------|------------|---------|---------------------
99
118
  `pixels` | `5` | Integer | Grid size.
100
119
  `mirror` | `:x` | Symbol | Mirroring mode: `:x`, `:y`, `:both` or `:none`.
101
- `color` | Deterministic Random | String | A color string for the pixels.
120
+ `color` | Deterministic Random | String | A color string for the pixels.
102
121
  `density` | `0.5` | Float | A value between 0 and 1 representing the chance for a pixel to be drawn. Lower values mean less pixels.
103
122
  `stroke` | `0.1` | Float | Width of the border around each pixel. Note that each pixel is a 10x10 box, so a stroke of 1 means it will take 10% of the box. Higher values generate more overlap between the pixels.
123
+ `jitter` | `0` | Float | A value between 0 and 1 representing the chance for a pixel to be dislocated by half of its size in a random direction.
104
124
  `background`| `#fff` | String | A named SVG color string (`blue`, `yellow` etc.) or RGB color (for example `#dddddd`).
105
125
  `template` | `:default` | Symbol/String | SVG template to use. Can be `:default`, `:html` or a path to a file. Read more on [Victor SVG Templates].
106
126
 
107
127
  ---
108
128
 
129
+
130
+ Using with Sinatra
131
+ --------------------------------------------------
132
+
133
+ To create a Sinatra server that serves Icodi images, see the
134
+ [server.rb](server.rb) example code.
135
+
136
+
137
+
109
138
  [GitHub identicons]: https://blog.github.com/2013-08-14-identicons/
110
139
  [Victor SVG Templates]: https://github.com/DannyBen/victor#svg-templates
data/lib/icodi.rb CHANGED
@@ -6,49 +6,50 @@ class Icodi < Victor::SVGBase
6
6
 
7
7
  def initialize(text = nil, options = {})
8
8
  text, options = nil, text if text.is_a? Hash
9
- @text, @options = text, options
10
- super template: template, viewBox: "0 0 #{size} #{size}"
9
+
10
+ @text = text
11
+ @options = default_options.merge options
11
12
 
12
- first_random_hit
13
+ super template: template, viewBox: "0 0 #{size} #{size}", clip_path: "url(#rect)"
14
+
13
15
  generate
14
16
  end
15
17
 
16
- def template
17
- options[:template] ||= :default
18
+ def method_missing(method_name, *_args, &_block)
19
+ respond_to?(method_name) ? options[method_name] : super
18
20
  end
19
21
 
20
- def pixels
21
- options[:pixels] ||= 5
22
+ def respond_to?(method_name, include_private = false)
23
+ options.has_key?(method_name) ? true : super
22
24
  end
23
25
 
24
- def density
25
- options[:density] ||= 0.5
26
- end
27
-
28
- def stroke
29
- options[:stroke] ||= 0.1
30
- end
31
-
32
- def background
33
- options[:background] ||= '#fff'
34
- end
26
+ private
35
27
 
36
- def color
37
- options[:color] ||= "#%06x" % (random.rand * 0xffffff)
28
+ def default_options
29
+ {
30
+ template: :default,
31
+ pixels: 5,
32
+ density: 0.5,
33
+ stroke: 0.1,
34
+ background: '#fff',
35
+ color: random_color,
36
+ mirror: :x,
37
+ jitter: 0,
38
+ }
38
39
  end
39
40
 
40
- def mirror
41
- options[:mirror] ||= :x
41
+ def random_color
42
+ "#%06x" % (random(:color).rand * 0xffffff)
42
43
  end
43
44
 
44
- private
45
-
46
45
  def seed(string)
47
46
  Digest::MD5.hexdigest(string).to_i(16)
48
47
  end
49
48
 
50
- def random
51
- @random ||= (text ? Random.new(seed(text)) : Random.new)
49
+ def random(set = nil)
50
+ @random_sets ||= {}
51
+ set ||= :default
52
+ @random_sets[set] ||= (text ? Random.new(seed(text)) : Random.new)
52
53
  end
53
54
 
54
55
  def size
@@ -59,29 +60,33 @@ private
59
60
  @style ||= { stroke: color, stroke_width: stroke }
60
61
  end
61
62
 
62
- def mirror_x
63
+ def mirror_x?
63
64
  [:x, :both].include? mirror
64
65
  end
65
66
 
66
- def mirror_y
67
+ def mirror_y?
67
68
  [:y, :both].include? mirror
68
69
  end
69
70
 
70
- def mirror_both
71
+ def mirror_both?
71
72
  mirror == :both
72
73
  end
73
74
 
74
- def first_random_hit
75
- options[:color] ? random.rand : color
76
- end
77
-
78
75
  def generate
79
76
  element :rect, x: 0, y: 0, width: size, height: size, fill: background
77
+ element :defs do
78
+ element :clipPath, id: :clipper do
79
+ element :rect, width: size, height: size
80
+ end
81
+ end
82
+
80
83
  half = (pixels / 2.0).round
81
- x = mirror_x ? half : pixels
82
- y = mirror_y ? half : pixels
84
+ x = mirror_x? ? half : pixels
85
+ y = mirror_y? ? half : pixels
83
86
 
84
- draw x, y
87
+ element :g, clip_path: "url(#clipper)" do
88
+ draw x, y
89
+ end
85
90
  end
86
91
 
87
92
  def draw(x_times, y_times)
@@ -93,14 +98,42 @@ private
93
98
  end
94
99
 
95
100
  def add_pixels(x, y)
101
+ x, y = add_jitter x, y
102
+
96
103
  draw_pixel x, y
97
- draw_pixel pixels-1-x, y if mirror_x and x != pixels/2
98
- draw_pixel x, pixels-1-y if mirror_y and y != pixels/2
99
- draw_pixel pixels-1-x, pixels-1-y if mirror_both and x != pixels/2 and y != pixels/2
104
+ draw_pixel mirror_value(x), y if mirror? x: x
105
+ draw_pixel x, mirror_value(y) if mirror? y: y
106
+ draw_pixel mirror_value(x), mirror_value(y) if mirror? x: x, y: y
107
+ end
108
+
109
+ def mirror?(x: nil, y: nil)
110
+ if x and y
111
+ mirror_both? and !mid?(x: x) and !mid?(y: y)
112
+ elsif x
113
+ mirror_x? and !mid? x: x
114
+ elsif y
115
+ mirror_y? and !mid? y: y
116
+ end
117
+ end
118
+
119
+ def mid?(x: nil, y: nil)
120
+ x ? x == pixels/2 : y ? y == pixels/2 : nil
121
+ end
122
+
123
+ def add_jitter(x, y)
124
+ return [x, y] unless jitter > 0 and random(:jitter).rand < jitter
125
+
126
+ x += [0, 0.5, -0.5][random(:jitter).rand(3)] unless mirror_x? and mid? x: x
127
+ y += [0, 0.5, -0.5][random(:jitter).rand(3)] unless mirror_y? and mid? y: y
128
+ [x, y]
100
129
  end
101
130
 
102
131
  def draw_pixel(x, y)
103
132
  element :rect, x: x*10, y: y*10, width: 10, height: 10, fill: color, style: style
104
133
  end
105
134
 
135
+ def mirror_value(value)
136
+ pixels - 1 - value
137
+ end
138
+
106
139
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: icodi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-17 00:00:00.000000000 Z
11
+ date: 2018-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: victor