ranicoma 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +61 -0
- data/.rspec +3 -0
- data/.rubocop.yml +86 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +9 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +35 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/example/create_example.rb +46 -0
- data/exe/ranicoma +6 -0
- data/lib/ranicoma.rb +14 -0
- data/lib/ranicoma/app.rb +27 -0
- data/lib/ranicoma/creator.rb +29 -0
- data/lib/ranicoma/design/base.rb +88 -0
- data/lib/ranicoma/design/geji.rb +249 -0
- data/lib/ranicoma/design/polypoly.rb +89 -0
- data/lib/ranicoma/design/rotobj.rb +103 -0
- data/lib/ranicoma/design/spbox.rb +109 -0
- data/lib/ranicoma/rect.rb +79 -0
- data/lib/ranicoma/util.rb +28 -0
- data/lib/ranicoma/version.rb +3 -0
- data/ranicoma.gemspec +35 -0
- metadata +116 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
require "ranicoma/design/base"
|
6
|
+
require "ranicoma/rect"
|
7
|
+
|
8
|
+
module Ranicoma
|
9
|
+
module Design
|
10
|
+
class RotObj < Base
|
11
|
+
LINE = 1.0/80
|
12
|
+
def initialize(rng)
|
13
|
+
super
|
14
|
+
@ct0 = rng.rand(Math::PI*2)
|
15
|
+
@count = rng.rand(5..10)
|
16
|
+
@body_seed = rng.rand(2**256)
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader(:count)
|
20
|
+
attr_reader(:body_seed)
|
21
|
+
|
22
|
+
def make_dists(body_rng, lo, hi, depth)
|
23
|
+
return [] if depth<=0
|
24
|
+
x = (hi-lo)*0.2
|
25
|
+
mid = body_rng.rand(lo+x..hi-x)
|
26
|
+
[
|
27
|
+
body_rng.rand(lo..mid),
|
28
|
+
make_dists(body_rng, lo, mid, depth-1),
|
29
|
+
make_dists(body_rng, mid, hi, depth-1),
|
30
|
+
body_rng.rand(mid..hi),
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def colmove( r, c )
|
35
|
+
delta = 80
|
36
|
+
f = ->(x){ r.rand(x-delta..x+delta).clamp(0,255).round }
|
37
|
+
c.map{ |e| f[e] }
|
38
|
+
end
|
39
|
+
|
40
|
+
def body(theta, seed)
|
41
|
+
body_rng = Random.new(seed)
|
42
|
+
arc=20
|
43
|
+
r=0.48
|
44
|
+
dt = Math::PI*2/count/2*0.9
|
45
|
+
t0 = -Math::PI/2 - dt
|
46
|
+
t1 = -Math::PI/2 + dt
|
47
|
+
pts = [
|
48
|
+
[0.5, 0.5]
|
49
|
+
]+Array.new(arc+1){ |ix|
|
50
|
+
t = (t1-t0)*ix*1.0/arc + t0
|
51
|
+
[Math.cos(t)*r+0.5, Math.sin(t)*r+0.5]
|
52
|
+
}
|
53
|
+
bc = rainbow( theta*3/(Math::PI*2) + @ct0 )
|
54
|
+
dists=make_dists(body_rng, 0, 0.5, 3).flatten
|
55
|
+
clip_id = Random.new_seed
|
56
|
+
[
|
57
|
+
element( "clipPath", id:clip_id ){
|
58
|
+
element( "polygon", points:points_str(pts))
|
59
|
+
},
|
60
|
+
element( "g", "clip-path":"url(##{clip_id})", style:"fill:#0000" ){
|
61
|
+
dists.map{ |dist|
|
62
|
+
t = body_rng.rand(t0..t1)
|
63
|
+
cx = Math.cos(t)*dist + 0.5
|
64
|
+
cy = Math.sin(t)*dist + 0.5
|
65
|
+
cr = body_rng.rand(0.05..0.1)
|
66
|
+
color = colmove(body_rng,bc)
|
67
|
+
if body_rng.rand(2)==0
|
68
|
+
element(
|
69
|
+
"circle",
|
70
|
+
cx:cx, cy:cy, r:cr,
|
71
|
+
**fill(color)
|
72
|
+
)
|
73
|
+
else
|
74
|
+
element(
|
75
|
+
"circle",
|
76
|
+
cx:cx, cy:cy, r:cr,
|
77
|
+
**stroke( color, 1.0/20)
|
78
|
+
)
|
79
|
+
end
|
80
|
+
}
|
81
|
+
}
|
82
|
+
]
|
83
|
+
end
|
84
|
+
|
85
|
+
def unit(theta)
|
86
|
+
rot = "rotate(#{theta*180/Math::PI},0.5,0.5)"
|
87
|
+
element("g", transform:rot ){
|
88
|
+
body(theta, body_seed)
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def create
|
93
|
+
basecol = rainbow(rng.rand(Math::PI*2), ->(v){ (v+3)/4.0 } )
|
94
|
+
[
|
95
|
+
element("circle", cx:0.5, cy:0.5, r:0.4, **fill(basecol) )
|
96
|
+
]+Array.new(count){ |ix|
|
97
|
+
unit(Math::PI*2*ix/count)
|
98
|
+
}.flatten
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
require "ranicoma/design/base"
|
6
|
+
require "ranicoma/rect"
|
7
|
+
|
8
|
+
module Ranicoma
|
9
|
+
module Design
|
10
|
+
class SpBox < Base
|
11
|
+
LINE = 1.0/30
|
12
|
+
MINSIZE = LINE*2
|
13
|
+
COLS= %i( red blue yellow green )
|
14
|
+
COLMAKERS=[]
|
15
|
+
|
16
|
+
def create_cols
|
17
|
+
send COLMAKERS.sample(random:rng)
|
18
|
+
end
|
19
|
+
|
20
|
+
COLMAKERS<<
|
21
|
+
def rainbow_cols
|
22
|
+
colcount = rng.rand(3..7)
|
23
|
+
base = rng.rand(100.0)
|
24
|
+
cols = Array.new(colcount){ |ix| rainbow( ix*3.0/colcount+base+rng.rand(3.0/colcount) ) }
|
25
|
+
cols.flat_map{ |e|
|
26
|
+
[e] + [:white]*rng.rand(2)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
COLMAKERS<<
|
31
|
+
def pale_cols
|
32
|
+
colcount = rng.rand(3..7)
|
33
|
+
base = rng.rand(100.0)
|
34
|
+
f = ->(x){ x/2+0.5 }
|
35
|
+
( Array.new(colcount){ |ix|
|
36
|
+
rainbow( ix*3.0/colcount+base+rng.rand(3.0/colcount), f )
|
37
|
+
} + [[40]*3, :white] ).shuffle( random:rng )
|
38
|
+
end
|
39
|
+
|
40
|
+
COLMAKERS<<
|
41
|
+
def basic_cols
|
42
|
+
colcount = rng.rand(3..7)
|
43
|
+
cols=%i(red green blue yellow cyan magenta green).shuffle( random:rng ).take(colcount)
|
44
|
+
cols.flat_map{ |e|
|
45
|
+
[e] + [:white]*rng.rand(2)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(rng)
|
50
|
+
super
|
51
|
+
@cols=create_cols
|
52
|
+
@col_ix=rng.rand(@cols.size)
|
53
|
+
end
|
54
|
+
|
55
|
+
def randcol
|
56
|
+
@col_ix = (@col_ix+1) % @cols.size
|
57
|
+
@cols[ @col_ix ]
|
58
|
+
end
|
59
|
+
|
60
|
+
def fill?(depth)
|
61
|
+
prob = [0.1, 0.4][depth] || 0.6
|
62
|
+
rng.rand < prob
|
63
|
+
end
|
64
|
+
|
65
|
+
def hsubbox( rc, depth )
|
66
|
+
ratio=rng.rand(0.3..0.7)
|
67
|
+
rest = (rc.w - LINE)
|
68
|
+
return rect_element(rc, randcol) if rest<MINSIZE
|
69
|
+
left = rest*ratio
|
70
|
+
right = rest-left
|
71
|
+
rc_l = Rect.new( rc.x, rc.y, left, rc.h )
|
72
|
+
rc_r = Rect.new( rc.right-right, rc.y, right, rc.h )
|
73
|
+
[
|
74
|
+
( fill?(depth) ? rect_element(rc_l, randcol) : vsubbox(rc_l, depth+1) ),
|
75
|
+
( fill?(depth) ? rect_element(rc_r, randcol) : vsubbox(rc_r, depth+1) )
|
76
|
+
]
|
77
|
+
end
|
78
|
+
|
79
|
+
def vsubbox( rc, depth )
|
80
|
+
ratio=rng.rand(0.3..0.7)
|
81
|
+
rest = (rc.h - LINE)
|
82
|
+
return rect_element(rc, randcol) if rest<MINSIZE
|
83
|
+
top = rest*ratio
|
84
|
+
bottom = rest-top
|
85
|
+
rc_t = Rect.new( rc.x, rc.y, rc.w, top )
|
86
|
+
rc_b = Rect.new( rc.x, rc.bottom-bottom, rc.w, bottom)
|
87
|
+
[
|
88
|
+
( fill?(depth) ? rect_element(rc_t, randcol) : hsubbox(rc_t, depth+1 ) ),
|
89
|
+
( fill?(depth) ? rect_element(rc_b, randcol) : hsubbox(rc_b, depth+1 ) )
|
90
|
+
]
|
91
|
+
end
|
92
|
+
|
93
|
+
def create
|
94
|
+
total = Rect.new( LINE, LINE, 1-LINE*2, 1-LINE*2 )
|
95
|
+
dir=%i(h v).sample( random:rng )
|
96
|
+
[
|
97
|
+
element("rect", height:1, width:1, **fill(:black)),
|
98
|
+
case dir
|
99
|
+
when :h
|
100
|
+
hsubbox(total, 0)
|
101
|
+
when :v
|
102
|
+
vsubbox(total, 0)
|
103
|
+
end
|
104
|
+
].flatten
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ranicoma
|
4
|
+
|
5
|
+
# 矩形
|
6
|
+
Rect = Struct.new( :x, :y, :w, :h ) do
|
7
|
+
|
8
|
+
# 垂直(上下)に分割する
|
9
|
+
# rel_hs :: 相対的な高さのリスト
|
10
|
+
def vsplit( *rel_hs )
|
11
|
+
rel_sum = rel_hs.sum
|
12
|
+
abs_y = y.to_f
|
13
|
+
rel_hs.map{ |rel_h|
|
14
|
+
abs_h = rel_h.to_f * h / rel_sum
|
15
|
+
rc = Rect.new( x, abs_y, w, abs_h )
|
16
|
+
abs_y += abs_h
|
17
|
+
rc
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
# 水平(左右)に分割する
|
22
|
+
# rel_ws :: 相対的な幅のリスト
|
23
|
+
def hsplit( *rel_ws )
|
24
|
+
rel_sum = rel_ws.sum
|
25
|
+
abs_x = x.to_f
|
26
|
+
rel_ws.map{ |rel_w|
|
27
|
+
abs_w = rel_w.to_f * w / rel_sum
|
28
|
+
rc = Rect.new( abs_x, y, abs_w, h )
|
29
|
+
abs_x += abs_w
|
30
|
+
rc
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
# 自分を縮小した矩形を返す。中心を維持して、上下左右から同じ長さを減じる。
|
35
|
+
# ratio :: 縮小する割合。0.1 とかを想定。
|
36
|
+
def reduce( ratio )
|
37
|
+
len = [w,h].min*ratio/2
|
38
|
+
Rect.new( x+len, y+len, w-len*2, h-len*2 )
|
39
|
+
end
|
40
|
+
|
41
|
+
# 自分を左右方向に縮小した矩形を返す。中心を維持して、左右から同じ長さを減じる。
|
42
|
+
# ratio :: 縮小する割合。0.1 とかを想定。
|
43
|
+
def reduce_h( ratio )
|
44
|
+
len = w*ratio/2
|
45
|
+
Rect.new( x+len, y, w-len*2, h )
|
46
|
+
end
|
47
|
+
|
48
|
+
# 中心の座標。x, y の順
|
49
|
+
def center
|
50
|
+
[cx, cy]
|
51
|
+
end
|
52
|
+
|
53
|
+
# 中心の x 座標
|
54
|
+
def cx
|
55
|
+
x+w/2.0
|
56
|
+
end
|
57
|
+
|
58
|
+
# 中心の y 座標
|
59
|
+
def cy
|
60
|
+
y+h/2.0
|
61
|
+
end
|
62
|
+
|
63
|
+
# 自分を90度回した矩形。回転の中心は矩形の中心。
|
64
|
+
def rot
|
65
|
+
cx, cy = center
|
66
|
+
Rect.new( cx-h/2, cy-w/2, h, w )
|
67
|
+
end
|
68
|
+
|
69
|
+
# 右端の座標
|
70
|
+
def right
|
71
|
+
x+w
|
72
|
+
end
|
73
|
+
|
74
|
+
# 下端の座標
|
75
|
+
def bottom
|
76
|
+
y+h
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module Ranicoma
|
4
|
+
module Util
|
5
|
+
# REXML::Element を作る
|
6
|
+
# @param [Object] name タグ名。to_s で文字列にされる。
|
7
|
+
# @param [Hash] opt アトリビュート。key も value も to_s で文字列にされる
|
8
|
+
# @yield [] 子要素作るブロック
|
9
|
+
# @yieldreturn [REXML::Element, Array<REXML::Element>] 子要素または子要素の配列
|
10
|
+
# @return [REXML::Element] XML Element。
|
11
|
+
def element(name, opt={})
|
12
|
+
r=opt.each.with_object(REXML::Element.new(name)) do |(k,v),e|
|
13
|
+
e.add_attribute(k.to_s, v.to_s)
|
14
|
+
end
|
15
|
+
if block_given?
|
16
|
+
children = yield
|
17
|
+
if children.is_a?(Array)
|
18
|
+
children.flatten.each do |ch|
|
19
|
+
r.add_element(ch)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
r.add_element(children)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
r
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/ranicoma.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "ranicoma/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "ranicoma"
|
7
|
+
spec.version = Ranicoma::VERSION
|
8
|
+
spec.authors = ["Nabetani"]
|
9
|
+
spec.email = ["takenori@nabetani.sakura.ne.jp"]
|
10
|
+
|
11
|
+
spec.summary = %q{Create SVG random colorful icon.}
|
12
|
+
spec.description = %q{Create SVG random colorful icon.}
|
13
|
+
spec.homepage = "https://github.com/nabetani/ranicoma"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
|
18
|
+
version = Ranicoma::VERSION
|
19
|
+
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/nabetani/ranicoma/tree/v#{version}/ranicoma"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/nabetani/ranicoma/tree/v#{version}/CHANGELOG.md"
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
|
+
end
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ranicoma
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nabetani
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description: Create SVG random colorful icon.
|
56
|
+
email:
|
57
|
+
- takenori@nabetani.sakura.ne.jp
|
58
|
+
executables:
|
59
|
+
- ranicoma
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".rubocop.yml"
|
66
|
+
- ".travis.yml"
|
67
|
+
- CHANGELOG.md
|
68
|
+
- CODE_OF_CONDUCT.md
|
69
|
+
- Gemfile
|
70
|
+
- Gemfile.lock
|
71
|
+
- LICENSE.txt
|
72
|
+
- README.md
|
73
|
+
- Rakefile
|
74
|
+
- bin/console
|
75
|
+
- bin/setup
|
76
|
+
- example/create_example.rb
|
77
|
+
- exe/ranicoma
|
78
|
+
- lib/ranicoma.rb
|
79
|
+
- lib/ranicoma/app.rb
|
80
|
+
- lib/ranicoma/creator.rb
|
81
|
+
- lib/ranicoma/design/base.rb
|
82
|
+
- lib/ranicoma/design/geji.rb
|
83
|
+
- lib/ranicoma/design/polypoly.rb
|
84
|
+
- lib/ranicoma/design/rotobj.rb
|
85
|
+
- lib/ranicoma/design/spbox.rb
|
86
|
+
- lib/ranicoma/rect.rb
|
87
|
+
- lib/ranicoma/util.rb
|
88
|
+
- lib/ranicoma/version.rb
|
89
|
+
- ranicoma.gemspec
|
90
|
+
homepage: https://github.com/nabetani/ranicoma
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata:
|
94
|
+
homepage_uri: https://github.com/nabetani/ranicoma
|
95
|
+
source_code_uri: https://github.com/nabetani/ranicoma/tree/v0.1.0/ranicoma
|
96
|
+
changelog_uri: https://github.com/nabetani/ranicoma/tree/v0.1.0/CHANGELOG.md
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubygems_version: 3.0.4
|
113
|
+
signing_key:
|
114
|
+
specification_version: 4
|
115
|
+
summary: Create SVG random colorful icon.
|
116
|
+
test_files: []
|