icodi 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +21 -2
- data/lib/icodi/options.rb +68 -0
- data/lib/icodi/randomization.rb +16 -0
- data/lib/icodi.rb +57 -77
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f552185f36c92756e8ebb28fe15ca0ac2efdf821934ada7e115fef570658687f
|
4
|
+
data.tar.gz: 3cc2ff20a4fbfa8137a75e76651e1362af861712a0099cb455aca9a0e7632996
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8b4b6538723c593eecb1e87a3b550a855a412c48fc81357e9031bef096585828e47f74e1aa4db2eecb62925651ab21380632412ee61310a5be434d6bdf6cfe9
|
7
|
+
data.tar.gz: 709621cd1d7cf475644f721b9f8f2d42f35eaa2ed47eca512645cb6b55f615e2a1eb7c3a197e6e98a9f01f1ef9aa262e4fdbdb09eaea6e0ad7f10047f9273841
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Icodi - Deterministic Random SVG Icon Generator
|
|
4
4
|
==================================================
|
5
5
|
|
6
6
|
[![Gem Version](https://badge.fury.io/rb/icodi.svg)](https://badge.fury.io/rb/icodi)
|
7
|
-
[![Build Status](https://
|
7
|
+
[![Build Status](https://github.com/DannyBen/icodi/workflows/Test/badge.svg)](https://github.com/DannyBen/icodi/actions?query=workflow%3ATest)
|
8
8
|
[![Maintainability](https://api.codeclimate.com/v1/badges/0b74be3877413501c7a9/maintainability)](https://codeclimate.com/github/DannyBen/icodi/maintainability)
|
9
9
|
|
10
10
|
---
|
@@ -18,10 +18,12 @@ Table of Contents
|
|
18
18
|
--------------------------------------------------
|
19
19
|
|
20
20
|
- [Installation](#installation)
|
21
|
+
- [Demo](#demo)
|
21
22
|
- [Examples](#examples)
|
22
23
|
- [Usage](#usage)
|
23
24
|
- [Options](#options)
|
24
25
|
- [Using with Sinatra](#using-with-sinatra)
|
26
|
+
- [Contributing / Support](#contributing--support)
|
25
27
|
|
26
28
|
|
27
29
|
Installation
|
@@ -31,6 +33,13 @@ Installation
|
|
31
33
|
|
32
34
|
|
33
35
|
|
36
|
+
Demo
|
37
|
+
--------------------------------------------------
|
38
|
+
|
39
|
+
Visit the [Icodi Playground] to experiment with the parameters.
|
40
|
+
|
41
|
+
|
42
|
+
|
34
43
|
Examples
|
35
44
|
--------------------------------------------------
|
36
45
|
|
@@ -122,6 +131,7 @@ Parameter | Default | Type | Description
|
|
122
131
|
`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
132
|
`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.
|
124
133
|
`background`| `#fff` | String | A named SVG color string (`blue`, `yellow` etc.) or RGB color (for example `#dddddd`).
|
134
|
+
`id` | `icodi` | String | The ID to assign the SVG object. Normally this should not matter, but if you intend to embed this icon in an HTML, or in another SVG, this can be useful.
|
125
135
|
`template` | `:default` | Symbol/String | SVG template to use. Can be `:default`, `:html` or a path to a file. Read more on [Victor SVG Templates].
|
126
136
|
|
127
137
|
---
|
@@ -131,9 +141,18 @@ Using with Sinatra
|
|
131
141
|
--------------------------------------------------
|
132
142
|
|
133
143
|
To create a Sinatra server that serves Icodi images, see the
|
134
|
-
[
|
144
|
+
[config.ru](config.ru) example code.
|
135
145
|
|
136
146
|
|
147
|
+
Contributing / Support
|
148
|
+
--------------------------------------------------
|
149
|
+
|
150
|
+
If you experience any issue, have a question or a suggestion, or if you wish
|
151
|
+
to contribute, feel free to [open an issue][issues].
|
152
|
+
|
153
|
+
---
|
137
154
|
|
138
155
|
[GitHub identicons]: https://blog.github.com/2013-08-14-identicons/
|
139
156
|
[Victor SVG Templates]: https://github.com/DannyBen/victor#svg-templates
|
157
|
+
[Icodi Playground]: https://icodi.dannyb.co/sandbox
|
158
|
+
[issues]: https://github.com/DannyBen/icodi/issues
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module IcodiCore
|
2
|
+
module Options
|
3
|
+
def default_options
|
4
|
+
{
|
5
|
+
pixels: 5,
|
6
|
+
density: 0.5,
|
7
|
+
stroke: 0.1,
|
8
|
+
background: '#fff',
|
9
|
+
color: random_color,
|
10
|
+
mirror: :x,
|
11
|
+
jitter: 0,
|
12
|
+
id: :icodi,
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def background
|
17
|
+
options[:background]
|
18
|
+
end
|
19
|
+
|
20
|
+
def color
|
21
|
+
options[:color]
|
22
|
+
end
|
23
|
+
|
24
|
+
def density
|
25
|
+
options[:density]
|
26
|
+
end
|
27
|
+
|
28
|
+
def id
|
29
|
+
options[:id]
|
30
|
+
end
|
31
|
+
|
32
|
+
def jitter
|
33
|
+
options[:jitter]
|
34
|
+
end
|
35
|
+
|
36
|
+
def mirror
|
37
|
+
options[:mirror]
|
38
|
+
end
|
39
|
+
|
40
|
+
def mirror_x?
|
41
|
+
%i[x both].include? mirror
|
42
|
+
end
|
43
|
+
|
44
|
+
def mirror_y?
|
45
|
+
%i[y both].include? mirror
|
46
|
+
end
|
47
|
+
|
48
|
+
def mirror_both?
|
49
|
+
mirror == :both
|
50
|
+
end
|
51
|
+
|
52
|
+
def pixels
|
53
|
+
options[:pixels]
|
54
|
+
end
|
55
|
+
|
56
|
+
def size
|
57
|
+
@size ||= pixels * 10
|
58
|
+
end
|
59
|
+
|
60
|
+
def stroke
|
61
|
+
options[:stroke]
|
62
|
+
end
|
63
|
+
|
64
|
+
def style
|
65
|
+
@style ||= { stroke: color, stroke_width: stroke }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module IcodiCore
|
2
|
+
module Randomization
|
3
|
+
def seed(string)
|
4
|
+
Digest::MD5.hexdigest(string).to_i(16)
|
5
|
+
end
|
6
|
+
|
7
|
+
def random(set = nil)
|
8
|
+
set ||= :default
|
9
|
+
random_sets[set] ||= (text ? Random.new(seed(text)) : Random.new)
|
10
|
+
end
|
11
|
+
|
12
|
+
def random_sets
|
13
|
+
@random_sets ||= {}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/icodi.rb
CHANGED
@@ -1,81 +1,38 @@
|
|
1
1
|
require 'victor'
|
2
2
|
require 'digest/md5'
|
3
|
+
require 'icodi/options'
|
4
|
+
require 'icodi/randomization'
|
3
5
|
|
4
6
|
class Icodi < Victor::SVGBase
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(text = nil, options = {})
|
8
|
-
text, options = nil, text if text.is_a? Hash
|
9
|
-
|
10
|
-
@text = text
|
11
|
-
@options = default_options.merge options
|
12
|
-
|
13
|
-
super template: template, viewBox: "0 0 #{size} #{size}", clip_path: "url(#rect)"
|
14
|
-
|
15
|
-
generate
|
16
|
-
end
|
17
|
-
|
18
|
-
def method_missing(method_name, *_args, &_block)
|
19
|
-
respond_to?(method_name) ? options[method_name] : super
|
20
|
-
end
|
21
|
-
|
22
|
-
def respond_to?(method_name, include_private = false)
|
23
|
-
options.has_key?(method_name) ? true : super
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
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
|
-
}
|
39
|
-
end
|
7
|
+
include IcodiCore::Options
|
8
|
+
include IcodiCore::Randomization
|
40
9
|
|
41
|
-
|
42
|
-
"#%06x" % (random(:color).rand * 0xffffff)
|
43
|
-
end
|
10
|
+
attr_reader :text, :options
|
44
11
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
12
|
+
def initialize(text = nil, opts = {})
|
13
|
+
if text.is_a? Hash
|
14
|
+
opts = text
|
15
|
+
text = nil
|
16
|
+
end
|
48
17
|
|
49
|
-
|
50
|
-
@random_sets ||= {}
|
51
|
-
set ||= :default
|
52
|
-
@random_sets[set] ||= (text ? Random.new(seed(text)) : Random.new)
|
53
|
-
end
|
18
|
+
svg_template = opts.delete :template
|
54
19
|
|
55
|
-
|
56
|
-
@
|
57
|
-
end
|
58
|
-
|
59
|
-
def style
|
60
|
-
@style ||= { stroke: color, stroke_width: stroke }
|
61
|
-
end
|
20
|
+
@text = text
|
21
|
+
@options = default_options.merge opts
|
62
22
|
|
63
|
-
|
64
|
-
[:x, :both].include? mirror
|
65
|
-
end
|
23
|
+
super template: svg_template, viewBox: "0 0 #{size} #{size}", id: id
|
66
24
|
|
67
|
-
|
68
|
-
[:y, :both].include? mirror
|
25
|
+
generate
|
69
26
|
end
|
70
27
|
|
71
|
-
|
72
|
-
mirror == :both
|
73
|
-
end
|
28
|
+
private
|
74
29
|
|
75
30
|
def generate
|
31
|
+
clip_path_id = "#{id}-#{random_id}"
|
32
|
+
|
76
33
|
element :rect, x: 0, y: 0, width: size, height: size, fill: background
|
77
34
|
element :defs do
|
78
|
-
element :clipPath, id:
|
35
|
+
element :clipPath, id: clip_path_id do
|
79
36
|
element :rect, width: size, height: size
|
80
37
|
end
|
81
38
|
end
|
@@ -84,10 +41,10 @@ private
|
|
84
41
|
x = mirror_x? ? half : pixels
|
85
42
|
y = mirror_y? ? half : pixels
|
86
43
|
|
87
|
-
element :g, clip_path: "url(
|
44
|
+
element :g, clip_path: "url(##{clip_path_id})" do
|
88
45
|
draw x, y
|
89
46
|
end
|
90
|
-
end
|
47
|
+
end
|
91
48
|
|
92
49
|
def draw(x_times, y_times)
|
93
50
|
y_times.times do |y|
|
@@ -95,7 +52,7 @@ private
|
|
95
52
|
add_pixels x, y if random.rand < density
|
96
53
|
end
|
97
54
|
end
|
98
|
-
end
|
55
|
+
end
|
99
56
|
|
100
57
|
def add_pixels(x, y)
|
101
58
|
x, y = add_jitter x, y
|
@@ -106,8 +63,28 @@ private
|
|
106
63
|
draw_pixel mirror_value(x), mirror_value(y) if mirror? x: x, y: y
|
107
64
|
end
|
108
65
|
|
66
|
+
def add_jitter(x, y)
|
67
|
+
if jitter.positive? && (random(:jitter).rand < jitter)
|
68
|
+
add_jitter! x, y
|
69
|
+
else
|
70
|
+
[x, y]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_jitter!(x, y)
|
75
|
+
x += random_jitter unless mirror_x? && mid?(x: x)
|
76
|
+
y += random_jitter unless mirror_y? && mid?(y: y)
|
77
|
+
[x, y]
|
78
|
+
end
|
79
|
+
|
80
|
+
def draw_pixel(x, y)
|
81
|
+
element :rect, x: x * 10, y: y * 10, width: 10, height: 10, fill: color, style: style
|
82
|
+
end
|
83
|
+
|
84
|
+
# Drawing Utilities
|
85
|
+
|
109
86
|
def mirror?(x: nil, y: nil)
|
110
|
-
if x
|
87
|
+
if x && y
|
111
88
|
mirror_both? and !mid?(x: x) and !mid?(y: y)
|
112
89
|
elsif x
|
113
90
|
mirror_x? and !mid? x: x
|
@@ -117,23 +94,26 @@ private
|
|
117
94
|
end
|
118
95
|
|
119
96
|
def mid?(x: nil, y: nil)
|
120
|
-
|
97
|
+
if x
|
98
|
+
x == pixels / 2
|
99
|
+
elsif y
|
100
|
+
y == pixels / 2
|
101
|
+
end
|
121
102
|
end
|
122
103
|
|
123
|
-
def
|
124
|
-
|
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]
|
104
|
+
def mirror_value(value)
|
105
|
+
pixels - 1 - value
|
129
106
|
end
|
130
107
|
|
131
|
-
def
|
132
|
-
|
108
|
+
def random_id
|
109
|
+
random(:nonvisual).rand(9_999_999)
|
133
110
|
end
|
134
111
|
|
135
|
-
def
|
136
|
-
|
112
|
+
def random_jitter
|
113
|
+
[0, 0.5, -0.5][random(:jitter).rand(3)]
|
137
114
|
end
|
138
115
|
|
116
|
+
def random_color
|
117
|
+
'#%06x' % (random(:color).rand * 0xffffff)
|
118
|
+
end
|
139
119
|
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.
|
4
|
+
version: 0.1.4
|
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:
|
11
|
+
date: 2023-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: victor
|
@@ -32,10 +32,15 @@ extra_rdoc_files: []
|
|
32
32
|
files:
|
33
33
|
- README.md
|
34
34
|
- lib/icodi.rb
|
35
|
+
- lib/icodi/options.rb
|
36
|
+
- lib/icodi/randomization.rb
|
35
37
|
homepage: https://github.com/dannyben/icodi
|
36
38
|
licenses:
|
37
39
|
- MIT
|
38
|
-
metadata:
|
40
|
+
metadata:
|
41
|
+
bug_tracker_uri: https://github.com/DannyBen/icodi/issues
|
42
|
+
source_code_uri: https://github.com/DannyBen/icodi
|
43
|
+
rubygems_mfa_required: 'true'
|
39
44
|
post_install_message:
|
40
45
|
rdoc_options: []
|
41
46
|
require_paths:
|
@@ -44,15 +49,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
49
|
requirements:
|
45
50
|
- - ">="
|
46
51
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.
|
52
|
+
version: 2.7.0
|
48
53
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
54
|
requirements:
|
50
55
|
- - ">="
|
51
56
|
- !ruby/object:Gem::Version
|
52
57
|
version: '0'
|
53
58
|
requirements: []
|
54
|
-
|
55
|
-
rubygems_version: 2.7.6
|
59
|
+
rubygems_version: 3.4.7
|
56
60
|
signing_key:
|
57
61
|
specification_version: 4
|
58
62
|
summary: Deterministic Random SVG Icon Generator
|