drawsvg 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6abc0de1a69c4536479ce57735395ff711b6e13f
4
+ data.tar.gz: ab8cb412975012d970012152fed5dab9069385f4
5
+ SHA512:
6
+ metadata.gz: 588d2e30558ce08d83aee2a94bf8ca622325fa16bc50483b84b3275d660b1fe6a1de291ba300ef9e1b9d23c8a1e9be39266002120f3432b4e7adbb4afeaa39df
7
+ data.tar.gz: 9cf8c6cafa5cbc03c52468a53f48af950082725fcc41fd530461bec6d8eea10c3ba843c250fc074bbc2154b921e31ddb98f59a20378a06e02b21df682857cd9d
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in drawsvg.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ben Delsol
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ # DrawSvg
2
+
3
+ A ruby layer to make drawing SVGs easier. Uses rasem under the hood.
4
+
5
+ * A Canvas holds all the Items to be drawn.
6
+ * Group related shapes into an Item.
7
+ * Items can have sub-Items.
8
+ * The Canvas can be scaled (ie. zoom in/out).
9
+ * Individual Items can be scaled.
10
+ * Use coordinates as if you are drawing on the first Cartesian quadrant.
11
+ * Shapes can be snapped or unsnapped to each other (do they stay together or drift apart when scaled).
12
+ * Lines are drawn with a starting point, length and angle (versus two points).
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'drawsvg'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install drawsvg
27
+
28
+ ## Usage
29
+
30
+ ```ruby
31
+ require 'drawsvg'
32
+ include DrawSvg
33
+
34
+ class StickMan < Item
35
+ def draw
36
+ @left_leg = Line.new(self, [0,0], 40, 60, stroke: 'red')
37
+ @right_leg = Line.new(self, @left_leg.p2, 40, -60)
38
+ @body = Line.new(self, @left_leg.p2, 30, 90)
39
+ @left_arm = Line.new(self, @body.p2-[0, 8], 30, 180+45)
40
+ @right_arm = Line.new(self, @left_arm.p1, 30, 20)
41
+ @box = Rectangle.new(self, @right_arm.p2, [10,15], fill: 'white', draw_from: :bottom_left)
42
+ @head = Circle.new(self, @body.p2, 15, draw_from: :bottom, stroke: %w[orange blue red].sample, fill: 'white')
43
+ end
44
+ end
45
+
46
+ class MyCanvas < Canvas
47
+ def draw
48
+ 30.times do
49
+ StickMan.new(self, Point[(0..475).to_a.sample, (0..475).to_a.sample], scale: (50..150).to_a.sample.to_f/100)
50
+ end
51
+ end
52
+ end
53
+
54
+ canvas = MyCanvas.new(501, 501, nil, scale: [1.1, 1.0])
55
+ File.write("/tmp/image.svg", canvas.to_svg)
56
+ ```
57
+
58
+ ## Contributing
59
+
60
+ 1. Fork it ( https://github.com/bdiz/drawsvg/fork )
61
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
62
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
63
+ 4. Push to the branch (`git push origin my-new-feature`)
64
+ 5. Create a new Pull Request
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ end
7
+
8
+ task :default => :test
9
+
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'drawsvg/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "drawsvg"
8
+ spec.version = DrawSvg::VERSION
9
+ spec.authors = ["Ben Delsol"]
10
+ spec.summary = %q{A ruby layer built on top of the rasem gem to make drawing SVGs easier.}
11
+ spec.description = %q{}
12
+ spec.homepage = "https://github.com/bdiz/drawsvg"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "rasem"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "minitest"
25
+ end
@@ -0,0 +1,236 @@
1
+ require "drawsvg/version"
2
+ require "rasem"
3
+
4
+ # TODO: Remove PrintStatusImg
5
+ class PrintStatusImg
6
+ def initialize img
7
+ @img = img
8
+ end
9
+ def method_missing meth, *args, &block
10
+ puts "img.#{meth}(#{args.join(", ")})"
11
+ @img.send(meth, *args, &block)
12
+ end
13
+ end
14
+ module DrawSvg
15
+ class Point
16
+ def self.[] *args
17
+ Point.new(*args)
18
+ end
19
+ attr_accessor :x, :y
20
+ def initialize x, y=nil
21
+ if !y.nil?
22
+ @x, @y = x, y
23
+ elsif x.is_a? Array and x.size == 2
24
+ @x, @y = x[0], x[1]
25
+ elsif x.is_a? Point
26
+ @x, @y = x.x, x.y
27
+ else
28
+ @x, @y = x, x
29
+ end
30
+ end
31
+ def + other
32
+ other = Point.new(other)
33
+ Point.new(@x+other.x, @y+other.y)
34
+ end
35
+ def - other
36
+ other = Point.new(other)
37
+ Point.new(@x-other.x, @y-other.y)
38
+ end
39
+ def * other
40
+ other = Point.new(other)
41
+ Point.new(@x*other.x, @y*other.y)
42
+ end
43
+ def round
44
+ Point.new(@x.round, @y.round)
45
+ end
46
+ def to_s
47
+ "[#{@x}, #{@y}]"
48
+ end
49
+ end
50
+ class Scale < Point; end
51
+
52
+ # TODO: consider making Canvas an Item.
53
+ # TODO: Add Rotation.
54
+ # TODO: performance.
55
+ class Canvas
56
+ DEFAULT_SCALE = 1
57
+ attr_reader :img, :width, :height, :items
58
+ attr_accessor :scale
59
+ def initialize width, height, output=nil, opts={}
60
+ @width, @height, @output, @opts = width, height, output, opts
61
+ @scale = Scale.new(@opts.delete(:scale) || DEFAULT_SCALE)
62
+ @img = SVGImageCalls.new
63
+ @location = Point[0, 0]
64
+ @items = []
65
+ draw
66
+ end
67
+ def draw
68
+ raise NotImplementedError
69
+ end
70
+ def absolute_location
71
+ @location
72
+ end
73
+ def to_svg
74
+ svg = PrintStatusImg.new(Rasem::SVGImage.new(@width, @height, @output))
75
+ @img.replay_on svg
76
+ @items.each {|i| i.to_svg svg }
77
+ svg.close
78
+ svg.output
79
+ end
80
+ end
81
+
82
+ class SVGImageCalls
83
+ def initialize
84
+ @calls = []
85
+ end
86
+ def method_missing name, *args, &block
87
+ @calls << [name, args, block]
88
+ end
89
+ def replay_on img
90
+ @calls.each {|name, args, block| img.send(name, *args, &block) }
91
+ end
92
+ end
93
+
94
+ class Item
95
+ include Comparable
96
+ DEFAULT_SCALE = 1
97
+ attr_reader :parent, :items, :location
98
+ def initialize parent, location, opts={}
99
+ @parent, @location = parent, Point.new(location)
100
+ @scale = Scale.new(opts[:scale] || DEFAULT_SCALE)
101
+ @parent.items << self
102
+ @items = []
103
+ draw
104
+ end
105
+ def draw
106
+ raise NotImplementedError
107
+ end
108
+ def <=> other
109
+ self.object_id <=> other.object_id
110
+ end
111
+ def img; canvas.img; end
112
+ def scale; parent.scale * @scale; end
113
+ def absolute_location; parent.absolute_location + location; end
114
+ def delete
115
+ @parent.delete(self)
116
+ end
117
+ def to_svg img
118
+ @items.each {|i| i.to_svg img }
119
+ end
120
+ def canvas
121
+ return parent if parent.is_a? Canvas
122
+ return parent.canvas
123
+ end
124
+ end
125
+
126
+ class Line < Item
127
+ attr_reader :length, :angle
128
+ def initialize parent, location, length, angle, opts={}
129
+ super(parent, location)
130
+ @length = length
131
+ @angle = angle * Math::PI / 180
132
+ @opts = opts
133
+ @snap = @opts.has_key?(:snap) ? @opts.delete(:snap) : true
134
+ end
135
+ def draw; end
136
+ def to_svg img
137
+ img.line(p1_svg.x, p1_svg.y, p2_svg.x, p2_svg.y, Rasem::SVGImage::DefaultStyles[:line].merge(@opts))
138
+ end
139
+ def p1
140
+ @snap ? location : (location * scale)
141
+ end
142
+ def p2
143
+ p1 + Point.new(length*Math.cos(angle), length*Math.sin(angle))*scale
144
+ end
145
+ def p1_absolute
146
+ parent.absolute_location + p1
147
+ end
148
+ def p2_absolute
149
+ parent.absolute_location + p2
150
+ end
151
+ def p1_svg
152
+ Point.new(p1_absolute.x, (canvas.height - p1_absolute.y)).round
153
+ end
154
+ def p2_svg
155
+ Point.new(p2_absolute.x, (canvas.height - p2_absolute.y)).round
156
+ end
157
+ end
158
+
159
+ # TODO: consider making only an Ellipse class with a Circle wrapper
160
+ class Circle < Item
161
+ attr_writer :radius
162
+ def initialize parent, location, radius, opts={} #location is center of circle by default
163
+ super(parent, location)
164
+ @radius, @opts = radius, opts
165
+ @draw_from = @opts.delete(:draw_from) || :center
166
+ @snap = @opts.delete(:snap)
167
+ end
168
+ def draw; end
169
+ def to_svg img
170
+ img.circle(center_svg.x, center_svg.y, radius, Rasem::SVGImage::DefaultStyles[:line].merge(fill: 'white').merge(@opts))
171
+ end
172
+ def center
173
+ if @draw_from == :bottom
174
+ location + Point[0, radius]
175
+ else
176
+ location
177
+ end
178
+ end
179
+ def radius
180
+ (@radius*scale.x).round
181
+ end
182
+ def center_absolute
183
+ parent.absolute_location + center
184
+ end
185
+ def center_svg
186
+ Point.new(center_absolute.x, (canvas.height - center_absolute.y)).round
187
+ end
188
+ end
189
+
190
+ # TODO: Consider only having Polygon w/ a Rectangle wrapper.
191
+ class Rectangle < Item
192
+ attr_reader :location2
193
+ def initialize parent, location, location2, opts={}
194
+ super(parent, location)
195
+ @location2 = Point.new(location2)
196
+ @opts = opts
197
+ @draw_from = @opts.delete(:draw_from) || :top_left
198
+ @snap = @opts.has_key?(:snap) ? @opts.delete(:snap) : true
199
+ end
200
+ def draw; end
201
+ def to_svg img
202
+ img.rectangle(p1_svg.x, p1_svg.y, p2_svg.x, p2_svg.y, Rasem::SVGImage::DefaultStyles[:rect].merge(@opts))
203
+ end
204
+ # top left corner
205
+ def p1
206
+ p = @snap ? location : (location * scale)
207
+ if @draw_from == :bottom_left
208
+ p + Point[0, (location2*scale).y]
209
+ else
210
+ p
211
+ end
212
+ end
213
+ # bottom right corner
214
+ def p2
215
+ p1 + p2_relative
216
+ end
217
+ def p2_relative
218
+ location2*scale
219
+ end
220
+ def p1_absolute
221
+ parent.absolute_location + p1
222
+ end
223
+ def p2_absolute
224
+ parent.absolute_location + p2
225
+ end
226
+ def p1_svg
227
+ Point.new(p1_absolute.x, (canvas.height - p1_absolute.y)).round
228
+ end
229
+ def p2_svg
230
+ p2_relative.round
231
+ end
232
+ end
233
+
234
+ # TODO: class Polygon
235
+
236
+ end
@@ -0,0 +1,3 @@
1
+ module DrawSvg
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,43 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'drawsvg'
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/spec'
6
+
7
+ include DrawSvg
8
+
9
+ class Sign < Item
10
+ def draw
11
+ l = Line.new(self, Point.new(0,0), 40, 0)
12
+ Line.new(self, Point.new(0,0), 40, -90)
13
+ Line.new(self, Point.new(10,-10), 40, -45, snap: false)
14
+ Line.new(self, l.p1 + Point.new(-5,5), 40, 90+45, snap: false)
15
+ Line.new(self, l.p2 + Point.new(-5,5), 40, 90+45)
16
+ end
17
+ end
18
+
19
+ class StickMan < Item
20
+ def draw
21
+ @left_leg = Line.new(self, [0,0], 40, 60, stroke: 'red')
22
+ @right_leg = Line.new(self, @left_leg.p2, 40, -60)
23
+ @body = Line.new(self, @left_leg.p2, 30, 90)
24
+ @left_arm = Line.new(self, @body.p2-[0, 8], 30, 180+45)
25
+ @right_arm = Line.new(self, @left_arm.p1, 30, 20)
26
+ @box = Rectangle.new(self, @right_arm.p2, [10,15], fill: 'white', draw_from: :bottom_left)
27
+ @head = Circle.new(self, @body.p2, 15, draw_from: :bottom, stroke: %w[orange blue red].sample, fill: 'white')
28
+ end
29
+ end
30
+
31
+ class MyCanvas < Canvas
32
+ def draw
33
+ 30.times do
34
+ StickMan.new(self, Point.new((0..475).to_a.sample, (0..475).to_a.sample), scale: (50..150).to_a.sample.to_f/100)
35
+ end
36
+ Sign.new(self, Point.new(100,170), scale: [2,1])
37
+ Sign.new(self, Point.new(100,100), scale: 1)
38
+ # img.ellipse(200,200, 10, 30)
39
+ # img.polygon(50,50,100,50,300,23, stroke: 'black', fill: 'white')
40
+ # img.polyline(36,76,534,123,455,321,112,344, stroke: 'black', fill: 'white')
41
+ end
42
+ end
43
+
@@ -0,0 +1,13 @@
1
+ require 'minitest_helper'
2
+
3
+ describe DrawSvg do
4
+ it "has a version number" do
5
+ ::DrawSvg::VERSION.wont_be_nil
6
+ end
7
+
8
+ it "can draw something" do
9
+ canvas = MyCanvas.new(501, 501, nil, scale: [1.1, 1.0])
10
+ canvas.to_svg.wont_be_empty
11
+ File.write("/tmp/image.svg", canvas.to_svg)
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: drawsvg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Delsol
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rasem
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: ''
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - Gemfile
77
+ - LICENSE.txt
78
+ - README.md
79
+ - Rakefile
80
+ - drawsvg.gemspec
81
+ - lib/drawsvg.rb
82
+ - lib/drawsvg/version.rb
83
+ - test/minitest_helper.rb
84
+ - test/test_drawsvg.rb
85
+ homepage: https://github.com/bdiz/drawsvg
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.2.2
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: A ruby layer built on top of the rasem gem to make drawing SVGs easier.
109
+ test_files:
110
+ - test/minitest_helper.rb
111
+ - test/test_drawsvg.rb