dyi 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +11 -0
- data/README +2 -3
- data/examples/animation.rb +104 -28
- data/examples/clock.rb +152 -0
- data/examples/data/money.csv +13 -12
- data/examples/external_files/asian_map.png +0 -0
- data/examples/external_files/xslt.xsl +71 -0
- data/examples/letter.rb +125 -0
- data/examples/line_and_bar.rb +32 -19
- data/examples/logo.rb +1 -62
- data/examples/map.rb +30705 -0
- data/examples/panther.rb +1602 -0
- data/examples/pie_chart.rb +27 -20
- data/examples/rainbow.rb +31 -0
- data/examples/simple_animation.rb +28 -0
- data/examples/thumbnail.rb +73 -0
- data/examples/xslt.rb +9 -0
- data/lib/dyi.rb +71 -2
- data/lib/dyi/animation.rb +270 -79
- data/lib/dyi/canvas.rb +10 -1
- data/lib/dyi/chart/line_chart.rb +75 -27
- data/lib/dyi/drawing/color_effect.rb +117 -0
- data/lib/dyi/drawing/pen.rb +6 -2
- data/lib/dyi/element.rb +11 -10
- data/lib/dyi/event.rb +3 -3
- data/lib/dyi/formatter/svg_formatter.rb +113 -25
- data/lib/dyi/shape.rb +2 -0
- data/lib/dyi/shape/base.rb +42 -3
- data/lib/dyi/shape/graphical_template.rb +106 -0
- data/lib/dyi/shape/reused_shape.rb +99 -0
- metadata +14 -3
- data/examples/class_diagram.rb +0 -154
data/examples/pie_chart.rb
CHANGED
@@ -3,25 +3,32 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'dyi'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:baloon_format => "{?name}\n{?percent}",
|
14
|
-
# :moved_elements => [0.2,nil,nil,0.5],
|
15
|
-
# :chart_colors => ['blue', 'red', 'yellow', 'green'],
|
16
|
-
:_3d_settings => {:dy => 30},
|
17
|
-
:background_image_opacity => 0.1,
|
18
|
-
:legend_format => "{?name}\t{!e}{?value:#,##0}\t{!e}({?percent:0.00%})",
|
19
|
-
:chart_stroke_color => 'white'
|
6
|
+
# Nominal GDP of Asian Countries (2010)
|
7
|
+
chart_data = [['China', 5878],
|
8
|
+
['Japan', 5459],
|
9
|
+
['India', 1538],
|
10
|
+
['South Koria', 1007],
|
11
|
+
['Other Countries', 2863]]
|
12
|
+
reader = DYI::Chart::ArrayReader.read(chart_data, :schema => [:name, :value])
|
20
13
|
|
21
|
-
|
22
|
-
chart.
|
14
|
+
# Creates the Pie Chart
|
15
|
+
chart = DYI::Chart::PieChart.new(500,240,
|
16
|
+
:center_point => [130, 130],
|
17
|
+
:legend_point => [250, 80],
|
18
|
+
:chart_radius_x => 100,
|
19
|
+
:show_data_label => false,
|
20
|
+
:represent_3d => true,
|
21
|
+
:_3d_settings => {:dy => 20},
|
22
|
+
:baloon_format => "{?name}\n{?value:#,0}",
|
23
|
+
:legend_format => "{?name}\t{!e}{?value:#,0}\t{!e}({?percent:0.0%})",
|
24
|
+
:chart_stroke_color => 'white',
|
25
|
+
:background_image_file => {:path => 'external_files/asian_map.png', :content_type => 'image/png'},
|
26
|
+
:background_image_opacity => 0.3)
|
27
|
+
chart.load_data(reader)
|
28
|
+
DYI::Drawing::Pen.black_pen.draw_text(chart.canvas,
|
29
|
+
[250, 40],
|
30
|
+
'Nominal GDP of Asian Countries (2010)',
|
31
|
+
:text_anchor => 'middle',
|
32
|
+
:font => {:font_family => 'sans-serif', :size => '14pt', :weight => 'bold'})
|
23
33
|
|
24
|
-
chart.save
|
25
|
-
chart.save 'output/pie_chart.xaml', :xaml
|
26
|
-
chart.save 'output/pie_chart.eps', :eps
|
27
|
-
chart.save 'output/pie_chart.emf', :emf if defined? IRONRUBY_VERSION
|
34
|
+
chart.save('output/pie_chart.svg')
|
data/examples/rainbow.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: UTF-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'dyi'
|
5
|
+
|
6
|
+
canvas = DYI::Canvas.new(500, 280)
|
7
|
+
canvas.title = 'Rainbow'
|
8
|
+
canvas.description = 'This image is a sample of DYI which uses a radial gradient.'
|
9
|
+
|
10
|
+
logo_container = DYI::Shape::ShapeGroup.draw_on(canvas)
|
11
|
+
DYI.logo(:canvas => logo_container,
|
12
|
+
:width => 287,
|
13
|
+
:height => 163,
|
14
|
+
:top => 100,
|
15
|
+
:left => 160)
|
16
|
+
|
17
|
+
gradient = DYI::Drawing::ColorEffect::RadialGradient.new([1,1.2], 1.2)
|
18
|
+
gradient.add_color_opacity(0.72, 'violet', 0)
|
19
|
+
gradient.add_color_opacity(0.74, 'violet', 0.5)
|
20
|
+
gradient.add_color_opacity(0.78, 'indigo', 0.5)
|
21
|
+
gradient.add_color_opacity(0.82, 'blue', 0.5)
|
22
|
+
gradient.add_color_opacity(0.86, 'green', 0.5)
|
23
|
+
gradient.add_color_opacity(0.9, 'yellow', 0.5)
|
24
|
+
gradient.add_color_opacity(0.94, 'orange', 0.5)
|
25
|
+
gradient.add_color_opacity(0.98, 'red', 0.5)
|
26
|
+
gradient.add_color_opacity(1, 'red', 0)
|
27
|
+
|
28
|
+
pen = DYI::Drawing::Brush.new(:color => gradient)
|
29
|
+
pen.draw_rectangle(canvas, [0,0], 500, 280)
|
30
|
+
|
31
|
+
canvas.save('output/rainbow.svg')
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: UTF-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'dyi'
|
5
|
+
|
6
|
+
canvas = DYI::Canvas.new(400, 300)
|
7
|
+
|
8
|
+
rect = DYI::Drawing::Brush.new(:color=>'#51ADE2').draw_rectangle(canvas, [10,10], 300, 200)
|
9
|
+
rect.add_painting_animation(:from => {:fill => '#51ADE2'},
|
10
|
+
:to => {:fill => 'red'},
|
11
|
+
:duration => 3,
|
12
|
+
:begin_event => DYI::Event.mouseover(rect),
|
13
|
+
:end_event => DYI::Event.mouseout(rect),
|
14
|
+
:fill => 'freeze')
|
15
|
+
text = DYI::Drawing::Brush.new.draw_text(canvas,
|
16
|
+
[100,250],
|
17
|
+
'click me!',
|
18
|
+
:show_border => true,
|
19
|
+
:border_color=>'#325BA8',
|
20
|
+
:padding => 8,
|
21
|
+
:border_rx => 10,
|
22
|
+
:border_width => 3,
|
23
|
+
:background_color=>'#A5C7F8')
|
24
|
+
rect.add_painting_animation(:to => {:fill => 'green'},
|
25
|
+
:begin_event => DYI::Event.click(text),
|
26
|
+
:fill => 'freeze')
|
27
|
+
|
28
|
+
canvas.save('output/simple_animation.svg')
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# -*- encoding: UTF-8 -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'dyi'
|
5
|
+
|
6
|
+
include DYI::Script::EcmaScript::DomLevel2
|
7
|
+
|
8
|
+
canvas = DYI::Canvas.new(500, 280)
|
9
|
+
|
10
|
+
base_pen = DYI::Drawing::Pen.new(:font => {:size => '14pt'})
|
11
|
+
|
12
|
+
symbols = []
|
13
|
+
|
14
|
+
symbol = DYI::Shape::GraphicalTemplate.new(400,170)
|
15
|
+
pen = DYI::Drawing::Pen.new(:color => 'blue', :width => 10)
|
16
|
+
pen.draw_rectangle(symbol, [50, 40], 300, 90, :rx => 30)
|
17
|
+
base_pen.draw_text(symbol, [200, 25], 'Rounded Rectangle', :text_anchor => 'middle')
|
18
|
+
base_pen.draw_text(symbol, [200, 160], 'page 1', :text_anchor => 'middle')
|
19
|
+
symbols << symbol
|
20
|
+
|
21
|
+
symbol = DYI::Shape::GraphicalTemplate.new(400,170)
|
22
|
+
pen = DYI::Drawing::Pen.new(:color => 'red', :width => 10)
|
23
|
+
pen.draw_ellipse(symbol, [200, 85], 150, 45)
|
24
|
+
base_pen.draw_text(symbol, [200, 25], 'Ellipse', :text_anchor => 'middle')
|
25
|
+
base_pen.draw_text(symbol, [200, 160], 'page 2', :text_anchor => 'middle')
|
26
|
+
symbols << symbol
|
27
|
+
|
28
|
+
symbol = DYI::Shape::GraphicalTemplate.new(400,170)
|
29
|
+
pen = DYI::Drawing::Pen.new(:color => 'green', :width => 10)
|
30
|
+
pen.draw_polygon(symbol, [[200, 40], [150, 60], [150, 110], [200, 130], [250, 110], [250, 60]])
|
31
|
+
base_pen.draw_text(symbol, [200, 25], 'Hexagon', :text_anchor => 'middle')
|
32
|
+
base_pen.draw_text(symbol, [200, 160], 'page 3', :text_anchor => 'middle')
|
33
|
+
symbols << symbol
|
34
|
+
|
35
|
+
symbol = DYI::Shape::GraphicalTemplate.new(400,170)
|
36
|
+
pen = DYI::Drawing::Pen.new(:color => 'orange', :width => 10)
|
37
|
+
pen.draw_path(symbol, [100, 85]){|path|
|
38
|
+
path.quadratic_curve_to([150, 0], [200, 85], [300, 85])
|
39
|
+
}
|
40
|
+
base_pen.draw_text(symbol, [200, 25], 'Wave', :text_anchor => 'middle')
|
41
|
+
base_pen.draw_text(symbol, [200, 160], 'page 4', :text_anchor => 'middle')
|
42
|
+
symbols << symbol
|
43
|
+
|
44
|
+
symbol = DYI::Shape::GraphicalTemplate.new(400,170)
|
45
|
+
brush = DYI::Drawing::Brush.cyan_brush
|
46
|
+
brush.draw_circle(symbol, [200, 85], 50).add_transform_animation(:translate,
|
47
|
+
:from => [-100, 0],
|
48
|
+
:relays => [[100,0]],
|
49
|
+
:to => [-100, 0],
|
50
|
+
:relayTimes => [0.5],
|
51
|
+
:duration => 3,
|
52
|
+
:calc_mode => 'spline',
|
53
|
+
:key_splines => [0.6, 0, 0.4, 1, 0.6, 0, 0.4, 1],
|
54
|
+
:repeat_count => 0)
|
55
|
+
base_pen.draw_text(symbol, [200, 25], 'Animation Circle', :text_anchor => 'middle')
|
56
|
+
base_pen.draw_text(symbol, [200, 160], 'page 5', :text_anchor => 'middle')
|
57
|
+
symbols << symbol
|
58
|
+
|
59
|
+
current_use = symbols.first.instantiate_on(canvas, [50, 10], :width => 400, :height => 170)
|
60
|
+
base_pen.draw_rectangle(canvas, [50, 10], 400, 170)
|
61
|
+
|
62
|
+
symbols.each_with_index do |symbol, i|
|
63
|
+
group = DYI::Shape::ShapeGroup.draw_on(canvas)
|
64
|
+
rect = base_pen.draw_rectangle(group, [105 + i * 60, 190], 50, 50)
|
65
|
+
use = symbol.instantiate_on(group, [105 + i * 60, 190], :width => 50, :height => 50)
|
66
|
+
group.skew_y(35, [105 + i * 60, 190])
|
67
|
+
rect.add_event_listener(:click, <<-SCRIPT)
|
68
|
+
var currentUse = #{get_element(current_use)};
|
69
|
+
currentUse.setAttributeNS('http://www.w3.org/1999/xlink', 'href', "##{symbol.id = canvas.publish_shape_id}");
|
70
|
+
SCRIPT
|
71
|
+
end
|
72
|
+
|
73
|
+
canvas.save('output/thumbnail.svg')
|
data/examples/xslt.rb
ADDED
data/lib/dyi.rb
CHANGED
@@ -24,11 +24,80 @@
|
|
24
24
|
module DYI
|
25
25
|
|
26
26
|
# DYI program version
|
27
|
-
VERSION = '1.
|
27
|
+
VERSION = '1.3.0'
|
28
28
|
|
29
29
|
# URL of DYI Project
|
30
30
|
# @since 0.0.2
|
31
|
-
URL = 'http://
|
31
|
+
URL = 'http://open-dyi.org/'
|
32
|
+
|
33
|
+
class << self
|
34
|
+
|
35
|
+
# Draw a DYI's logo.
|
36
|
+
# @option options [Canvas, Shape::ShapeGroup] :canvas a container element
|
37
|
+
# of the DYI's logo
|
38
|
+
# @option options [Length] :width a width of the logo mark
|
39
|
+
# @option options [Length] :height a height of the logo mark
|
40
|
+
# @option options [Length] :left a x-coordinate of a left edge of the logo
|
41
|
+
# mark
|
42
|
+
# @option options [Length] :top a y-coordinate of a top edge of the logo
|
43
|
+
# mark
|
44
|
+
# @return [Canvas, Shape::ShapeGroup] a new Canvas object which logo mark is
|
45
|
+
# draw on if :canvas option is given, otherwise a new Shape::Group object
|
46
|
+
# which logo mark is on.
|
47
|
+
# @since 1.3.0
|
48
|
+
def logo(options = {})
|
49
|
+
width = Length.new(options[:width] || 287)
|
50
|
+
height = Length.new(options[:height] || 163)
|
51
|
+
if options[:canvas]
|
52
|
+
canvas = Shape::ShapeGroup.draw_on(options[:canvas])
|
53
|
+
canvas.scale(width / 287, height / 163)
|
54
|
+
canvas.translate(options[:left] || 0, options[:top] || 0)
|
55
|
+
else
|
56
|
+
canvas = Canvas.new(width, height)
|
57
|
+
end
|
58
|
+
Drawing::Brush.new(:color=>'#51ADE2').draw_closed_path(canvas, [287,0]) {|path|
|
59
|
+
path.rline_to([0,162.637], [-39.41,0])
|
60
|
+
path.rcurve_to([0,-5.191], [-1.729,-107.272], [-1.729,-107.272], [-2.594,102.295], [-2.813,107.272])
|
61
|
+
path.rline_to([-3.246,0])
|
62
|
+
path.rcurve_to([0,-4.977], [-1.728,-107.272], [-1.728,-107.272], [-2.595,102.513], [-2.595,107.272])
|
63
|
+
path.rline_to([-3.245, 0])
|
64
|
+
path.rcurve_to([-0.215,-4.54], [-1.729,-107.272], [-1.729,-107.272], [-2.813,102.943], [-2.813,107.272])
|
65
|
+
path.rline_to([-3.46, 0], [0, -162.637])
|
66
|
+
}
|
67
|
+
Drawing::Brush.new(:color=>'#325BA8').draw_closed_path(canvas, [258.471,0]) {|path|
|
68
|
+
path.rline_to([-52.793,97.971], [-0.078,64.666], [-57.073,0], [-0.071,-65.106], [-49.789,-97.531],[92.148,0])
|
69
|
+
path.rcurve_to([-12.327,25.52], [-35.9,74.829], [-35.9,74.829], [27.034,-50.391], [40.013,-74.829])
|
70
|
+
path.rline_to([4.322,0])
|
71
|
+
path.rcurve_to([-11.461,24.221], [-37.414,78.289], [-37.414,78.289], [30.206,-55.798], [41.955,-78.289])
|
72
|
+
path.rline_to([4.111,0])
|
73
|
+
path.rcurve_to([-10.599,21.844], [-39.146,81.75], [-39.146,81.75], [33.306,-62.069], [43.687,-81.75])
|
74
|
+
}
|
75
|
+
Drawing::Brush.new(:color=>'#51ADE2', :rule => 'evenodd').draw_closed_path(canvas, [149.875,78.938]){|path|
|
76
|
+
path.rcurve_to([0,13.193], [-2.379,25.52], [-7.353,36.552], [-11.894,20.114], [-20.112,27.249])
|
77
|
+
path.rline_to([-0.216, 0])
|
78
|
+
path.rcurve_to([-9.517,7.786], [-20.113,12.76], [-31.144,15.787], [-22.276,4.111], [-33.954,4.111], [-22.276,-0.651], [-28.98,-1.514])
|
79
|
+
path.rline_to([-20.113, -2.815])
|
80
|
+
path.rcurve_to([12.327,-1.077], [34.17,-4.322], [54.5,-15.784])
|
81
|
+
path.rcurve_to([14.921,-8.219], [27.034,-21.627], [32.441,-33.524], [6.271,-20.543], [6.487,-20.543])
|
82
|
+
path.rcurve_to([-0.217,0], [-1.08,8.649], [-7.137,20.114], [-18.167,24.654], [-32.873,32.003])
|
83
|
+
path.rcurve_to([-25.953,13.411], [-54.067,13.84], [-61.421,13.84])
|
84
|
+
path.rline_to([0, -3.241])
|
85
|
+
path.rcurve_to([7.137,-0.215], [34.82,-1.729], [58.827,-15.355])
|
86
|
+
path.rcurve_to([29.844,-14.921], [35.9,-49.526], [35.035,-48.661])
|
87
|
+
path.rcurve_to([0.866,-0.866], [-6.487,33.303], [-36.117,46.714])
|
88
|
+
path.rcurve_to([-23.791,12.327], [-50.608,12.976], [-57.745,12.976])
|
89
|
+
path.rline_to([0, -3.246])
|
90
|
+
path.rcurve_to([6.92,-0.211], [33.307,-1.942], [55.15,-14.488])
|
91
|
+
path.rcurve_to([26.168,-13.193], [31.358,-41.955], [31.358,-43.254])
|
92
|
+
path.rcurve_to([0,1.299], [-6.487,29.631], [-32.44,41.311])
|
93
|
+
path.rcurve_to([-21.628,11.242], [-47.148,12.108], [-54.068,12.108])
|
94
|
+
path.rline_to([0,-132.574])
|
95
|
+
path.rline_to([27.25, -4.326])
|
96
|
+
path.rcurve_to([10.381,-1.731], [22.06,-2.378], [34.604,-2.378], [21.194,0.864], [31.36,3.677], [19.464,6.92], [27.25,12.975], [16.868,16.006], [21.843,26.819], [7.568,22.924], [7.568,35.467])
|
97
|
+
}
|
98
|
+
canvas
|
99
|
+
end
|
100
|
+
end
|
32
101
|
end
|
33
102
|
|
34
103
|
%w(
|
data/lib/dyi/animation.rb
CHANGED
@@ -32,31 +32,103 @@ module DYI
|
|
32
32
|
|
33
33
|
# Base class for animation classes.
|
34
34
|
# @abstract
|
35
|
-
# @attr [Object] from a starting value of the animation
|
36
|
-
# @attr [Object] to a ending value of the animation
|
37
|
-
# @attr [Numeric] duration a simple duration of the animation
|
38
|
-
# @attr [Numeric] begin_offset a offset that determine the animation begin
|
39
|
-
# @attr [Event] begin_event an event that determine the element begin
|
40
|
-
# @attr [Numeric] end_offset a offset that determine the animation end
|
41
|
-
# @attr [Event] end_event an event that determine the element end
|
42
|
-
# @attr [String] fill the effect of animation when the animation is over,
|
43
|
-
# either 'freeze' or 'remove'
|
44
|
-
# @attr [String] additive a value that means whether or not the animation is
|
45
|
-
# additive, either 'replace' or 'sum'
|
46
|
-
# @attr [String] restart a value for the restart, either 'always',
|
47
|
-
# 'whenNotActive'or 'never'
|
48
35
|
class Base
|
36
|
+
|
49
37
|
IMPLEMENT_ATTRIBUTES = [:from, :to, :duration, :begin_offset,
|
50
38
|
:begin_event, :end_offset, :end_event, :fill,
|
51
|
-
:additive, :restart
|
39
|
+
:additive, :restart, :relays, :relay_times,
|
40
|
+
:calc_mode, :repeat_count, :key_splines]
|
52
41
|
VALID_VALUES = {
|
53
42
|
:fill => ['freeze','remove'],
|
54
43
|
:additive => ['replace', 'sum'],
|
55
|
-
:restart => ['always', 'whenNotActive', 'never']
|
44
|
+
:restart => ['always', 'whenNotActive', 'never'],
|
45
|
+
:calc_mode => ['discrete', 'linear', 'paced', 'spline']
|
56
46
|
}
|
57
47
|
|
48
|
+
# @attribute from
|
49
|
+
# Returns a starting value of the animation.
|
50
|
+
# @return [Object] a starting value of the animation
|
51
|
+
#+++
|
52
|
+
# @attribute to
|
53
|
+
# Returns a ending value of the animation.
|
54
|
+
# @return [Object] a ending value of the animation
|
55
|
+
#+++
|
56
|
+
# @attribute duration
|
57
|
+
# Returns a simple duration of the animation.
|
58
|
+
# @return [Numeric] a simple duration of the animation
|
59
|
+
#+++
|
60
|
+
# @attribute begin_offset
|
61
|
+
# Returns a offset that determine the animation begin.
|
62
|
+
# @return [Numeric] a offset that determine the animation begin
|
63
|
+
#+++
|
64
|
+
# @attribute begin_event
|
65
|
+
# Returns an event that determine the element begin.
|
66
|
+
# @return [Event] an event that determine the element begin
|
67
|
+
#+++
|
68
|
+
# @attribute end_offset
|
69
|
+
# Returns a offset that determine the animation end
|
70
|
+
# @return [Numeric] a offset that determine the animation end
|
71
|
+
#+++
|
72
|
+
# @attribute end_event
|
73
|
+
# Returns an event that determine the element end.
|
74
|
+
# @return [Event] an event that determine the element end
|
75
|
+
#+++
|
76
|
+
# @attribute fill
|
77
|
+
# Returns the effect of animation when the animation is over, either
|
78
|
+
# <tt>'freeze'</tt> or <tt>'remove'</tt>
|
79
|
+
# @return [String] the effect of animation
|
80
|
+
#+++
|
81
|
+
# @attribute additive
|
82
|
+
# Returns a value that means whether or not the animation is additive,
|
83
|
+
# either <tt>'replace'</tt> or <tt>'sum'</tt>
|
84
|
+
# @return [String] either <tt>'replace'</tt> or <tt>'sum'</tt>
|
85
|
+
#+++
|
86
|
+
# @attribute restart
|
87
|
+
# Returns a value for the restart, either <tt>'always'</tt>,
|
88
|
+
# <tt>'whenNotActive'</tt> or <tt>'never'</tt>
|
89
|
+
# @return [String] either <tt>'always'</tt>, <tt>'whenNotActive'</tt> or
|
90
|
+
# <tt>'never'</tt>
|
91
|
+
#+++
|
92
|
+
# @attribute relays
|
93
|
+
# @return [Array]
|
94
|
+
# @since 1.3.0
|
95
|
+
#+++
|
96
|
+
# @attribute relay_times
|
97
|
+
# @return [Array<#to_f>]
|
98
|
+
# @since 1.3.0
|
99
|
+
#+++
|
100
|
+
# @attribute calc_mode
|
101
|
+
# @return [String]
|
102
|
+
# @since 1.3.0
|
103
|
+
#+++
|
104
|
+
# @attribute repeat_count
|
105
|
+
# @return [Numeric]
|
106
|
+
# @since 1.3.0
|
107
|
+
#+++
|
108
|
+
# @attribute key_splines
|
109
|
+
# @return [Array<#to_f>]
|
110
|
+
# @since 1.3.0
|
58
111
|
attr_reader *IMPLEMENT_ATTRIBUTES
|
59
112
|
|
113
|
+
# Returns whether the animation is cumulative.
|
114
|
+
# @return [Boolean] true if the animation is cumulative, false otherwise
|
115
|
+
# @since 1.3.0
|
116
|
+
def accumulate?
|
117
|
+
@accumulate ? true : false
|
118
|
+
end
|
119
|
+
|
120
|
+
# @attribute [w] fill
|
121
|
+
# @param [String] value the value of attribute fill
|
122
|
+
#+++
|
123
|
+
# @attribute [w] additive
|
124
|
+
# @param [String] value the value of attribute additive
|
125
|
+
#+++
|
126
|
+
# @attribute [w] restart
|
127
|
+
# @param [String] value the value of attribute restart
|
128
|
+
#+++
|
129
|
+
# @attribute [w] calc_mode
|
130
|
+
# @param [String] value the value of attribute calc_mode
|
131
|
+
# @since 1.3.0
|
60
132
|
VALID_VALUES.each do |attr, valid_values|
|
61
133
|
define_method("#{attr.to_s}=") {|value|
|
62
134
|
if (value = value.to_s).size == 0
|
@@ -71,11 +143,18 @@ module DYI
|
|
71
143
|
end
|
72
144
|
|
73
145
|
def duration=(duration)
|
74
|
-
@duration = duration
|
146
|
+
@duration = duration.to_f
|
147
|
+
end
|
148
|
+
|
149
|
+
# @attribute [w] repeat_count
|
150
|
+
# @param [#to_f] count
|
151
|
+
# @since 1.3.0
|
152
|
+
def repeat_count=(count)
|
153
|
+
@repeat_count = count.to_f
|
75
154
|
end
|
76
155
|
|
77
156
|
def begin_offset=(offset)
|
78
|
-
@begin_offset = offset
|
157
|
+
@begin_offset = offset.to_f
|
79
158
|
end
|
80
159
|
|
81
160
|
def begin_event=(event)
|
@@ -83,13 +162,33 @@ module DYI
|
|
83
162
|
end
|
84
163
|
|
85
164
|
def end_offset=(offset)
|
86
|
-
@end_offset = offset
|
165
|
+
@end_offset = offset.to_f
|
87
166
|
end
|
88
167
|
|
89
168
|
def end_event=(event)
|
90
169
|
@end_event = event
|
91
170
|
end
|
92
171
|
|
172
|
+
# @attribute [w] relays
|
173
|
+
# @param [Array<#to_f>] times
|
174
|
+
# @since 1.3.0
|
175
|
+
def relay_times=(times)
|
176
|
+
@relay_times = times.map{|time| time.to_f}
|
177
|
+
end
|
178
|
+
|
179
|
+
# @attribute [w] key_splines
|
180
|
+
# @param [Array<#to_f>] keys
|
181
|
+
# @since 1.3.0
|
182
|
+
def key_splines=(keys)
|
183
|
+
@key_splines = keys.map{|time| time.to_f}
|
184
|
+
end
|
185
|
+
|
186
|
+
# @param [Boolean] value
|
187
|
+
# @since 1.3.0
|
188
|
+
def accumulate=(value)
|
189
|
+
@accumulate = value
|
190
|
+
end
|
191
|
+
|
93
192
|
# @param [Shape::Base] shape a target element for an animation
|
94
193
|
# @param [Hash] options an option for an animation
|
95
194
|
def initialize(shape, options)
|
@@ -100,14 +199,17 @@ module DYI
|
|
100
199
|
__send__("#{attr}=", value)
|
101
200
|
end
|
102
201
|
end
|
202
|
+
@relays ||= []
|
203
|
+
@relay_times ||= []
|
103
204
|
end
|
104
205
|
end
|
105
206
|
|
106
207
|
# Class representing an animation of a painting
|
107
|
-
# @attr [Painting] from a starting value of the animation
|
108
|
-
# @attr [Painting] to a ending value of the animation
|
109
208
|
class PaintingAnimation < Base
|
110
209
|
|
210
|
+
# @attribute [rw] from
|
211
|
+
# Returns a starting value of the animation.
|
212
|
+
# @return [Painting] a starting value of the animation
|
111
213
|
def from=(painting)
|
112
214
|
@from = painting && DYI::Painting.new(painting)
|
113
215
|
end
|
@@ -116,11 +218,19 @@ module DYI
|
|
116
218
|
@to = DYI::Painting.new(painting)
|
117
219
|
end
|
118
220
|
|
221
|
+
# @attribute relays
|
222
|
+
# @return [Array<Painting>]
|
223
|
+
# @since 1.3.0
|
224
|
+
def relays=(paintings)
|
225
|
+
@relays = paintings.map{|painting| DYI::Painting.new(painting)}
|
226
|
+
end
|
227
|
+
|
119
228
|
def animation_attributes
|
120
229
|
DYI::Painting::IMPLEMENT_ATTRIBUTES.inject({}) do |result, attr|
|
121
230
|
from_attr, to_attr = @from && @from.__send__(attr), @to.__send__(attr)
|
122
|
-
|
123
|
-
|
231
|
+
relay_attrs = @relays.map{|relay| relay.__send__(attr)}
|
232
|
+
if to_attr && (from_attr != to_attr || relay_attrs.any?{|relay_attr| from_attr != relay_attrs || relay_attr != to_attr})
|
233
|
+
result[attr] = [from_attr].push(*relay_attrs).push(to_attr)
|
124
234
|
end
|
125
235
|
result
|
126
236
|
end
|
@@ -159,69 +269,150 @@ module DYI
|
|
159
269
|
end
|
160
270
|
|
161
271
|
def from=(value)
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
272
|
+
@from =
|
273
|
+
case type
|
274
|
+
when :translate
|
275
|
+
case value
|
276
|
+
when Array
|
277
|
+
case value.size
|
278
|
+
when 2 then @from = value.map{|v| v.to_f}
|
279
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
280
|
+
end
|
281
|
+
when Numeric, Length
|
282
|
+
[value.to_f, 0]
|
283
|
+
when nil
|
284
|
+
nil
|
285
|
+
else
|
286
|
+
raise TypeError, "illegal argument: #{value}"
|
287
|
+
end
|
288
|
+
when :scale
|
289
|
+
case value
|
290
|
+
when Array
|
291
|
+
case value.size
|
292
|
+
when 2 then @from = value.map{|v| v.to_f}
|
293
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
294
|
+
end
|
295
|
+
when Numeric
|
296
|
+
[value.to_f, value.to_f]
|
297
|
+
when nil
|
298
|
+
nil
|
299
|
+
else
|
300
|
+
raise TypeError, "illegal argument: #{value}"
|
301
|
+
end
|
302
|
+
when :rotate
|
303
|
+
case value
|
304
|
+
when Array
|
305
|
+
case value.size
|
306
|
+
when 3 then value.map{|v| v.to_f}
|
307
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
308
|
+
end
|
309
|
+
when Numeric
|
310
|
+
value.to_f
|
311
|
+
when nil
|
312
|
+
nil
|
313
|
+
else
|
314
|
+
raise TypeError, "illegal argument: #{value}"
|
315
|
+
end
|
316
|
+
when :skewX, :skewY
|
317
|
+
value.nil? ? nil : value.to_f
|
169
318
|
end
|
170
|
-
when Numeric, Length
|
171
|
-
@from = [value.to_f, 0]
|
172
|
-
when nil
|
173
|
-
@from = nil
|
174
|
-
else
|
175
|
-
raise TypeError, "illegal argument: #{value}"
|
176
|
-
end
|
177
|
-
when :scale
|
178
|
-
case value
|
179
|
-
when Array
|
180
|
-
case value.size
|
181
|
-
when 2 then @from = value.map{|v| v.to_f}
|
182
|
-
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
183
|
-
end
|
184
|
-
when Numeric
|
185
|
-
@from = [value.to_f, value.to_f]
|
186
|
-
when nil
|
187
|
-
@from = nil
|
188
|
-
else
|
189
|
-
raise TypeError, "illegal argument: #{value}"
|
190
|
-
end
|
191
|
-
when :rotate, :skewX, :skewY
|
192
|
-
@from = value.nil? ? nil : value.to_f
|
193
|
-
end
|
194
319
|
end
|
195
320
|
|
196
321
|
def to=(value)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
322
|
+
@to =
|
323
|
+
case type
|
324
|
+
when :translate
|
325
|
+
case value
|
326
|
+
when Array
|
327
|
+
case value.size
|
328
|
+
when 2 then value.map{|v| v.to_f}
|
329
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
330
|
+
end
|
331
|
+
when Numeric, Length
|
332
|
+
@to = [value.to_f, 0]
|
333
|
+
else
|
334
|
+
raise TypeError, "illegal argument: #{value}"
|
335
|
+
end
|
336
|
+
when :scale
|
337
|
+
case value
|
338
|
+
when Array
|
339
|
+
case value.size
|
340
|
+
when 2 then value.map{|v| v.to_f}
|
341
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
342
|
+
end
|
343
|
+
when Numeric
|
344
|
+
[value.to_f, value.to_f]
|
345
|
+
else
|
346
|
+
raise TypeError, "illegal argument: #{value}"
|
347
|
+
end
|
348
|
+
when :rotate
|
349
|
+
case value
|
350
|
+
when Array
|
351
|
+
case value.size
|
352
|
+
when 3 then value.map{|v| v.to_f}
|
353
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
354
|
+
end
|
355
|
+
when Numeric
|
356
|
+
value.to_f
|
357
|
+
else
|
358
|
+
raise TypeError, "illegal argument: #{value}"
|
359
|
+
end
|
360
|
+
when :skewX, :skewY
|
361
|
+
value.to_f
|
204
362
|
end
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
363
|
+
end
|
364
|
+
|
365
|
+
# @attribute relays
|
366
|
+
# @return [Array]
|
367
|
+
# @since 1.3.0
|
368
|
+
def relays=(values)
|
369
|
+
@relays =
|
370
|
+
case type
|
371
|
+
when :translate
|
372
|
+
values.map do |value|
|
373
|
+
case value
|
374
|
+
when Array
|
375
|
+
case value.size
|
376
|
+
when 2 then value.map{|v| v.to_f}
|
377
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
378
|
+
end
|
379
|
+
when Numeric, Length
|
380
|
+
[value.to_f, 0]
|
381
|
+
else
|
382
|
+
raise TypeError, "illegal argument: #{value}"
|
383
|
+
end
|
384
|
+
end
|
385
|
+
when :scale
|
386
|
+
values.map do |value|
|
387
|
+
case value
|
388
|
+
when Array
|
389
|
+
case value.size
|
390
|
+
when 2 then value.map{|v| v.to_f}
|
391
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
392
|
+
end
|
393
|
+
when Numeric
|
394
|
+
[value.to_f, value.to_f]
|
395
|
+
else
|
396
|
+
raise TypeError, "illegal argument: #{value}"
|
397
|
+
end
|
398
|
+
end
|
399
|
+
when :rotate
|
400
|
+
values.map do |value|
|
401
|
+
case value
|
402
|
+
when Array
|
403
|
+
case value.size
|
404
|
+
when 3 then value.map{|v| v.to_f}
|
405
|
+
else raise ArgumentError, "illegal size of Array: #{value.size}"
|
406
|
+
end
|
407
|
+
when Numeric
|
408
|
+
value.to_f
|
409
|
+
else
|
410
|
+
raise TypeError, "illegal argument: #{value}"
|
411
|
+
end
|
412
|
+
end
|
413
|
+
when :skewX, :skewY
|
414
|
+
values.map{|value| value.to_f}
|
216
415
|
end
|
217
|
-
when Numeric
|
218
|
-
@to = [value.to_f, value.to_f]
|
219
|
-
else
|
220
|
-
raise TypeError, "illegal argument: #{value}"
|
221
|
-
end
|
222
|
-
when :rotate, :skewX, :skewY
|
223
|
-
@to = value.to_f
|
224
|
-
end
|
225
416
|
end
|
226
417
|
|
227
418
|
def initialize(shape, type, options)
|