class SVGEE
attr_reader :primitives, :defs, :supported_primitives
def initialize(args)
opts = {:width => '100%', :height => '100%'}.merge!(args)
@width = opts[:width]
@height = opts[:height]
@style= opts[:style]
@primitives = []
@defs = []
@supported_primitives = [:circle, :rectangle, :ellipse, :line, :polyline, :text]
end
def open_tag
%{}
end
private
def add(primitive_string)
@primitives << primitive_string
end
def add_def(definition_string)
@defs << definition_string
end
def make_tag(primitive, args)
if args.has_key?(:link)
add link_and_tag(primitive, args)
else
add self.send("#{primitive}_tag", args)
end
return Primitive.new(primitive, args)
end
def link_and_tag(primitive, args)
%{} + self.send("#{primitive}_tag", args) + %{}
end
def circle_tag(a = {})
%{}
end
def rectangle_tag(a = {})
%{}
end
def ellipse_tag(a = {})
%{}
end
def line_tag(a = {})
%{}
end
def polyline_tag(a={})
%{}
end
def polygon_tag(a={})
%{}
end
def text_tag(a = {})
%{#{a[:text]}}
end
def common_attributes(a={})
%{stroke="#{a[:stroke]}" stroke-width="#{a[:stroke_width]}" style="#{a[:style]}"}
end
def method_missing(primitive, args={}) #only used to dynamically select the primitive type..
raise NoMethodError if not self.supported_primitives.include?(primitive) #we're only doing the listed primitive types...
self.send "make_tag", primitive, args
end
public
def add_primitive(primitive_object) #adds a primitive object to the SVG
args = {}
primitive_object.instance_variables.each{|v| args[v.gsub(/@/,"").to_sym] = primitive_object.instance_variable_get(v) }
primitive_string = args.delete(:primitive)
make_tag(primitive_string, args)
end
def gradient(a)
definition_string = case a[:type]
when :radial
%{}
else
%{}
end
a[:stops].each do |s|
definition_string = definition_string + "\n" + %{}
end
add_def definition_string + (a[:type] == :linear ? '' : '')
end
def draw
head = self.open_tag
defstring = ""
defstring = "\n" + self.defs.join("\n") + "\n \n" if not defs.empty?
shapes = self.primitives.join("\n")
close = self.close_tag
head + defstring + shapes + close
end
end
=begin How to use SVGEE
s = SVGEE.new
s.gradient(:radial => "grad1", :cx => 50, :cy => 50, :r => 50, :fx => 50, :fy => 50, :stops => [ {:offset => 0, :color => 'rgb(255,255,255)', :opacity => 0}, {:offset => 100, :color => 'rgb(0,0,255)', :opacity => 1},] )
s.circle(:x_center => 40, :y_center => 40, :radius => 20, :fill_color => "url(#grad1)")
s.circle(:x_center => 250, :y_center => 250, :radius => 20, :fill_color => "url(#grad1)", :link => {:href => "http://www.bbc.co.uk"})
s.rectangle(:x => 125, :y => 125, :width => 100, :height => 50, :fill_color => 'red', :stroke => 'black', :stroke_width => 2, :style => "fill-opacity:0.1;stroke-opacity:0.9")
s.rectangle(:x => 125, :y => 125, :round_x => 5, :round_y => 5, :width => 100, :height => 50, :fill_color => 'red', :stroke => 'black', :stroke_width => 2, :style => "fill-opacity:0.1;stroke-opacity:0.9")
prim = s.ellipse(:x_center => 100, :y_center => 190, :x_radius => 40, :y_radius => 20, :fill_color => 'green', :stroke => 'black')
s.line(:x1 => 10, :y1 => 10, :x2 => 145, :y2 => 145, :stroke_width => 5, :stroke => 'blue')
s.polyline(:points => "2,2 400,440 600,440", :stroke_width => 10, :stroke => "#f00", :fill => "none")
s.text(:x => 100, :y => 100, :fill => 'red', :text => "Look! A circle!", :style => "letter-spacing:2;font-family:Arial")
s.text(:x => 100, :y => 400, :fill => 'green', :text => "This one is a link", :link => {:href => "http://www.bbc.co.uk"})
prim.update(:x_center => 200)
s.add_primitive(prim) #add one of the returned, updated Primitive objects
s.draw
=end