ranicoma 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,3 @@
1
+ module Ranicoma
2
+ VERSION = "0.1.0"
3
+ end
@@ -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: []