tween 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest ADDED
@@ -0,0 +1,5 @@
1
+ Manifest
2
+ README.markdown
3
+ Rakefile
4
+ examples/demo.rb
5
+ lib/tween.rb
data/README.markdown ADDED
@@ -0,0 +1,21 @@
1
+ # Tween
2
+
3
+ Tween is a library for doing fluid motion in Ruby. It's primarily a port of
4
+ Robert Penner's easing calculations to Ruby. It has no dependencies, but it was
5
+ written for using with Gosu.
6
+
7
+ ### What do they do?
8
+
9
+ Tweening is a technique for fluid animation. It will find a number of steps
10
+ between two points, allows something to transition smoothly between point A and
11
+ point B. While it's easy to code a linear interpolation yourself, there are a
12
+ number of **easings** in this library you can use.
13
+
14
+ An **easing** is a method of transitioning between two points *more* smoothly
15
+ than linear interpolation. Linear interpolation has sudden starts and stops,
16
+ and a constant velocity. Using an easing such as **Tween::Quart::InOut** will
17
+ make the object start moving slowly, accelerate, decelerate and arrive at its
18
+ destination gracefully.
19
+
20
+ For usage and a visual demonstration of what this really is, install Gosu
21
+ and run demo.rb in the examples directory.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('tween', '0.1') do |p|
6
+ p.description = "Fluid motion using tweens for Ruby"
7
+ p.url = "http://ruby.about.com/"
8
+ p.author = "Michael Morin"
9
+ p.email = "michael.c.morin@gmail.com"
10
+ p.ignore_pattern = %w{ examples/Rakefile examples/images/* }
11
+ end
data/examples/demo.rb ADDED
@@ -0,0 +1,320 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'gosu'
4
+ require 'yaml'
5
+ require 'tempfile'
6
+ require 'base64'
7
+ require 'tween'
8
+
9
+
10
+ $data = YAML.parse(DATA.read)
11
+
12
+ def with_data(key,&block)
13
+ Tempfile.open(File.basename(__FILE__)) do |tmp|
14
+ tmp.binmode
15
+ tmp.write( Base64.decode64($data[key].value) )
16
+ tmp.close
17
+
18
+ block.call(tmp.path)
19
+ end
20
+ end
21
+
22
+
23
+
24
+ module Z
25
+ Background, Graph, Text, Ball = (1..100).to_a
26
+ end
27
+
28
+ class MyWindow < Gosu::Window
29
+ WIDTH = 640
30
+ HEIGHT = 480
31
+ TITLE = "Tween Demo"
32
+
33
+ TOP_COLOR = Gosu::Color.new(0xFFF5F5F5)
34
+ BOTTOM_COLOR = Gosu::Color.new(0xFFBEBEBE)
35
+ GRAPH_COLOR = Gosu::Color::BLACK
36
+
37
+
38
+
39
+ def initialize
40
+ super(WIDTH, HEIGHT, false)
41
+ self.caption = TITLE
42
+
43
+ @last_frame = Gosu::milliseconds
44
+
45
+ with_data('globe.png') do |png|
46
+ @ball = Gosu::Image.new(self, png, false)
47
+ end
48
+
49
+ @font = Gosu::Font.new(self, Gosu::default_font_name, 20)
50
+ @smallfont = Gosu::Font.new(self, Gosu::default_font_name, 15)
51
+
52
+ @x, @y = width / 2, height / 2
53
+ @tween = nil
54
+ @easer = Tween::EASERS[0]
55
+ end
56
+
57
+
58
+
59
+ def update
60
+ calculate_delta
61
+ end
62
+
63
+ def calculate_delta
64
+ @this_frame = Gosu::milliseconds
65
+ @delta = (@this_frame - @last_frame) / 1000.0
66
+
67
+ # Update game objects here
68
+ unless @tween.nil? or @tween.done
69
+ @tween.update(@delta)
70
+ @x, @y = @tween.x, @tween.y
71
+ end
72
+
73
+ @last_frame = @this_frame
74
+ end
75
+
76
+
77
+
78
+ def draw
79
+ draw_background
80
+ draw_graph
81
+ draw_easer_name
82
+ draw_instructions
83
+ draw_ball
84
+ end
85
+
86
+ def draw_ball
87
+ @ball.draw(
88
+ @x - (@ball.width / 2),
89
+ @y - (@ball.height / 2),
90
+ Z::Ball
91
+ )
92
+ end
93
+
94
+ def draw_background
95
+ draw_quad(
96
+ 0, 0, TOP_COLOR,
97
+ WIDTH, 0, TOP_COLOR,
98
+ 0, HEIGHT, BOTTOM_COLOR,
99
+ WIDTH, HEIGHT, BOTTOM_COLOR,
100
+ Z::Background)
101
+ end
102
+
103
+ def draw_graph
104
+ left = width * 0.2
105
+ right = left + width * 0.6
106
+ bottom = height * 0.8
107
+ top = bottom - height * 0.6
108
+
109
+ draw_line(
110
+ left, top, GRAPH_COLOR,
111
+ left, bottom + 20, GRAPH_COLOR,
112
+ Z::Graph
113
+ )
114
+
115
+ draw_line(
116
+ left - 20, bottom, GRAPH_COLOR,
117
+ right, bottom, GRAPH_COLOR,
118
+ Z::Graph
119
+ )
120
+
121
+ graph = (0..100).map do |idx|
122
+ @easer.ease(idx, bottom, top - bottom, 100.0)
123
+ end
124
+
125
+ (1..99).map do |idx|
126
+ draw_line(
127
+ left + Tween::Linear.ease(idx - 1, 0, right - left, 100),
128
+ graph[idx - 1],
129
+ GRAPH_COLOR,
130
+
131
+ left + Tween::Linear.ease(idx, 0, right - left, 100),
132
+ graph[idx],
133
+ GRAPH_COLOR,
134
+
135
+ Z::Graph
136
+ )
137
+ end
138
+ end
139
+
140
+ def draw_easer_name
141
+ @font.draw(
142
+ @easer.to_s,
143
+ 10, 10, Z::Text,
144
+ 1.0, 1.0,
145
+ GRAPH_COLOR
146
+ )
147
+ end
148
+
149
+ def draw_instructions
150
+ @smallfont.draw(
151
+ "Click to move globe, press left and right to change easer",
152
+ 20, height - 20, Z::Text,
153
+ 1.0, 1.0,
154
+ GRAPH_COLOR
155
+ )
156
+ end
157
+
158
+
159
+ def needs_cursor?
160
+ true
161
+ end
162
+
163
+ def button_down(id)
164
+ case id
165
+ when Gosu::MsLeft
166
+ @tween = Tween.new(
167
+ [@x.to_f, @y.to_f],
168
+ [mouse_x.to_f, mouse_y.to_f],
169
+ @easer,
170
+ 1
171
+ )
172
+
173
+ when Gosu::KbEscape
174
+ close
175
+
176
+ when Gosu::KbRight
177
+ next_easer
178
+
179
+ when Gosu::KbLeft
180
+ last_easer
181
+ end
182
+ end
183
+
184
+
185
+ def next_easer
186
+ idx = Tween::EASERS.index(@easer) + 1
187
+
188
+ if idx == Tween::EASERS.length
189
+ idx = 0
190
+ end
191
+
192
+ @easer = Tween::EASERS[idx]
193
+ end
194
+
195
+ def last_easer
196
+ idx = Tween::EASERS.index(@easer) - 1
197
+
198
+ if idx == -1
199
+ idx = Tween::EASERS.length - 1
200
+ end
201
+
202
+ @easer = Tween::EASERS[idx]
203
+ end
204
+ end
205
+
206
+ MyWindow.new.show
207
+
208
+ __END__
209
+ ---
210
+ globe.png: |
211
+ iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c
212
+ 6QAAAAZiS0dEAEsAygDzbuxiFwAAAAlwSFlzAAEplQABKZUBsleJ0AAAAAd0
213
+ SU1FB9oJHgYCAhoSqCgAABKnSURBVHja5VvdjyTXVT/n3Fsf3T09szM7u+Pd
214
+ nd21vU6MsZOYJLYhJBYoEUQB8RCJBwgvCPEAEv8SPAEPKFEkEPJDlEhOlCjO
215
+ ysQfieLYjj92vd/z1Z9Vde89Px6quqempnpm1rtAIlq6quqq29V1fuf73HOJ
216
+ /p9/+P/42bM5OMFc/KYAwMecN6+hhVAcQTx+XQFoEsYNonkBCG2EagMMNO4/
217
+ NBDs/wDh0jivH48CAUcMbQHjoQBhHzLh9aNpXJMFQDQ5j8axOer3HxgIfsDf
218
+ 8QIiTW3sX7epYRObcj4YvlAiIrZJaQuYAZ8H8lloEB2qMTtH7YgHUQ1+CFxv
219
+ Em0bR64dpWETqEW3mxIQGsO3gKEfFwT7MbnPNaKlRmzUIH4u9pz0k3jz+QvS
220
+ WT3NtrNMxiYkNiUAhJBTcFP46VCnOzvF9asfIh+4GmEzwn313BkIXDOYs7l8
221
+ PyDwxxR5aeF2VB1tTeSjzpNfe9YsrX8ySntnoijumSjpRcIihoWYASXyQdUH
222
+ JReC985Ngs+H5LKtML77y/zt77yBYli0SIGrRmioCBa40gcGoE68bRAd1bme
223
+ bn72bO/y577QXVp5ptfrryz3u/Hq8pIs93vc63W500klMgIjhhSErHBhWgQd
224
+ TTLsDSdhe3dPd3aHOp5mvsjGQzfe/rm78dMfuZuv36sR62rDN1TjxCDwx+B8
225
+ nfi4dm46l547s/bE819ePrX6+TOrK52z66v27OlVc3pt2fS7XUmSmOM4JmMM
226
+ szAxMYFABILzXp1XynKng/HU390dFbfu7bmbt+/523e3dDAcZW6882px/eoP
227
+ 3M3X79YkoWgAcV8g8ANwPqlxXi5+8a9+b+XspT/dWD+1/ujmueiRs6ftyvIy
228
+ Ot2uJEkCayOIMTDGEDODWfYtIJSImFQDqyp55zjLc0ynuW4Pxv767a383Wt3
229
+ smvXb+hgONpxu9e+M3n9m1drnC9qQNRB0OMMI58AnLqFj2qcj4nIdpeWkytf
230
+ /tu/WF1b+/3LFzbiixfOyamVFUq7XcRJChsnam0EYyJiYTLGaunxhAggYiYA
231
+ FRAgVRUETyE49t5RURQyHU9wZ2fgP7i5NX3rvevFRzduhcnu3R+OXvmnf6/Z
232
+ gzYQwnHewZyAeGmIfDLj/ic+++LG5S/8+d9dvnD2uaeeuBw/+uglXlk9jXSp
233
+ H5LOUki6S97GaTBRHMRYNTYKYiNlY5VYVGysYFExRtkYZTHKIoGtVTY2iIkg
234
+ JtIoiajXTWVtKU3WV5eNjWIa5WGTzz590Q9uv4Ns4Bcw81gbYE4g+rbB9ZiI
235
+ 7FMvfOX86d/60j9cPHfmiU9cecysn9nQ3vKaizs9l6Q9jdJuMHGixsYqxkKM
236
+ BYkBiEEsIBYtjwwWA4AILCCR8r4YiI2UmFXEKrOlKIqo24nNqX7XWhvpYJqv
237
+ hZVHn9Bi8o6O7uQLwur7BqDp521D9KOnnn1+bf2ZP/z7i+fWH7v86KO0vHbG
238
+ pUsrLu72fBR3VZI0lC8vIDYgFoBYS+IZKIUfCoaCAJpd4zlACi7NoxigfI6y
239
+ WDXWILKWe2lsozjRvfF4KXTOXshvvPk6qa/HAXqSKHERAE1fP+N8dPHixc75
240
+ F77+1xtnTj+9eekyltfWXbd/ysVpN0RxR02SBDFWWaTkLJHOiCYRgPnAoNq5
241
+ VgApAGKeAUcgAhuj1XewCESYOom1ZGzYHY5XsPb4Sn7t1V8syC1wUgk4XvS/
242
+ +jd/srp++g82Ny/SytpGkfZWXNLp+Sjte5OmWnEKxKxgrl5aKgIJCkCpOq8P
243
+ oJwDlJLAUkoJkRKxKggkomBRIlEyTFaY48iYPMDtjbNHeGUzL2787NqC7LJV
244
+ CswC7tet/szw2U+++PUnV889/pcXL5yP1zcuFGn/lIu7S97GnWCSFFQRrFyK
245
+ +4yrJYEz4vdF/8CYXZ8DQtBKNebgkBBqz4MIIsNirKXd0dSPC2yyTT7wWx8M
246
+ KnrCAiBaAThS95eWlqJHPvvVb5w7u35h4/wll/RXXNxdclHSDRylQYxVlPqu
247
+ pc4KlXpfEUB1XZ+dl2FQpftaO6dqrupcGsrvVAKrRAxVEDEREzgvtLi3u2cR
248
+ 9/rZ+1ffaEmn6yDwcQA0DZ/deO7Pnlnd2PyjzYsXqb+27pKlU4VNu8HGncA2
249
+ UiUBkShEECrDFkAIc+IJocb52Zy6OoQZZ6lUk4C65OxLQxnlMFShCkCYuHCe
250
+ tsZ5PplON0z/zK3i1lt3jymmHMgGm35fGlmexKc3X+yvLFO3v+Il7hQUJZ5M
251
+ HIIIiARMDJ3xkYgC0OKRD147NGf2MmV03OrSSzSZlZhgYyYNkDhFf7lLp9ZO
252
+ Y3vrjsfqhc8T0Zs1Sfa1usWBeqQ9Iu6fFzSWnvzSZtzpn+8tnwq20w0cpZ7E
253
+ ejJRUBIQCMxM8zckrgRtdl5GfOWxhkO9JsxtzggH6WciYiEgEFhYGQQTixqH
254
+ tNuT5eUlSvprhRbTK8mlz5zNP3ztZo0OX6MtLKoHNF2gEJGk55/8XNRJ425/
255
+ xXPcVU46DjYOXkSFhAQErtlZEEp6DpxjH5MT1XrR+AZizEARUoTSv5KATEQS
256
+ JUi7PcRLfZ8Nk7hz+dnP5R++9p8tUq11dO2CSu6BH0na27RxqjbtBbaxBpZg
257
+ SDSg1C/FjDAsSDNwRArSrGHwEb/Zn4MyUOJAxGADMpGxSRJM2vUmTj26y58k
258
+ opcazDyyInQAAI5SA5fJ0jNffoyjtC/pUg6bCNlYISYom8BsgIr3DCwU35LE
259
+ NqLrcxfdRytQ5d8ZCqxSJhBCKpFnm3pJel7idLlz5fmN6buvXF9QlMWRKsA2
260
+ tnAZ2+Uzj5CJupr08kDGBGPJiPXBCACACWARIrRxnO9joQeHvlXBcGk/Dngw
261
+ kAJVPYxBYuHYaMHWwcbBpF0foriTbDz2+PTdV260lOZbvUDrQoZJl06zCAoy
262
+ WcY28iRiSBRgCBmtovcF5bg2qeDGORYsEtWM6YH7dQmoSslKyNVoRqZQG6kk
263
+ aWATiUn7GwvWJeZ0LpQAnQ6UiIzE8ZJEUXAkfqwCB7aiBAtWaPka3EzCmFvw
264
+ qIfn1Y3W+y3i34qREFTLYIKJp+BiouIlipitVWYiiZOVBQxudYOHDcTKRoeN
265
+ 7bK16sno0GmYKpOpKOWqnsWLpBl0BIdrbDxkBxYYxkM/L6Mp70GDQl0WyBNR
266
+ JMaWyZNw0rISxceVxecTTW85JuGEhUFCOg7sBwUoTskABK4o4LkbOIJz9Wtt
267
+ iN2fj6QqhiYC09AhDDwXniWIEctMJNaCxUQSd6wW02KRUTpSAlgsM3NZwGRm
268
+ p0F3ipAnPtg+IFxFNrxvsmbJa42BqPGW9wOlhpeYaUTzHfef3A6AC6TbeXAj
269
+ r14YTAZgM7cOwknXUDG9r4WRuQCHbOiZ4JmUmctob+LgdnJSk8DGpgr/pC7O
270
+ NRDmojpzgmgBoSY1LZ6kjH1KQBmoKQeTD4phHvyeI+cDCARhlD6jkiYfhlvF
271
+ UenwkRLgd29PgTCFKhMFIYADMwa5OpNr6CewkWFh2o9269Fg00BiZrepLu6g
272
+ fVOKfY93wISUv5nNYwIFACMHP3DwBUhJyBCDhcFEYNIgRFq0VIZxFADzFJKj
273
+ hODyQMGPEZwh9QR4RigkUOoHuQYVaBewkbVcY1ADjeoG11WADtyvlHn/+oHc
274
+ oTxWbGUQoCDKPIWhI18ogwjMUCZ4VlUi9UxQRvDjI2qEBwKhQ5UTiRIOLgdc
275
+ NiR4puANwwsTmBgcGGHsAzkY7bIayyTMBy38fnjA8yrAXCS06QZ5X7ErdnMj
276
+ uQIpBWUUCp0UIXgQQIFZyuVDJhBpLuqz0lH5bGdBSjync6EEqCsCEUmY7N0m
277
+ nA/w0xg+LxgFsxZMsAy2moMQCkVsha2QlCuhB9h7UOcXGncsuD6L/AgegFeo
278
+ U4IykXCZiCgCMxxTKITUCVxmKOTeD7autfQULFSBAwjBZZ6I7PSjt6+l5x4f
279
+ humog1AIXCaU9GaKzyxlISNXgp9ZIaLyfhNbbvr+o0JkrsKm8pWCMgKq4iqj
280
+ BBk6qwgRqRf43JAvjObjCL4oBj/74bvHSMBCAOZLS5P339xa+cyLW5qPH0M2
281
+ stpdCqRFUPViSJTL6i2RoKzoELNwWbU5FF4AC7LAo1e0FUTg0hDwfL4SQmBi
282
+ ZYRCoI7hM9F8bOGmJhTTW364NW1ZOT7wkUUqUGtAUD+49xaFwoTpMEaRifpM
283
+ OBRlnVc9ExMxM3FlCssSF1emjStUcbj5h0vj2HqPQEpAGewSmEsTWHqJwExK
284
+ TEoUCiafM4qpQTE1mk+M5pn1O7dea9QDW0GQBQHsgbaUey9/66qfDvfCZBBr
285
+ MbYopga+EMALMZgZVFYrlNkwlYOIyggS5ZFBpjFm903lv6R+nTF7FgkTV4MI
286
+ zIaJEBjwQuoFoTDqplazsQ2TvQQ+H2y/8tKbjd6BVhVoSkBrXw6Cd36480aY
287
+ DJIw3otDNoq0GBv4ggnKPONIGTHuD2kMpmrM5tD8SFIRWv9dNU+az6nkhwFS
288
+ l4kWU6PTkdFsFIXJIPbD7Vc1n+Yt/UWHTLAsCLybvTm699rLP1KXTf1oJ9Hp
289
+ 0Oq0kgSXCUF5JpYE5bq47h+bhNNBsObXFg+Clv+hngmB1eWCfGJCNrRaTI0b
290
+ bqVaTEejt1+9WtFwbL+AXdCrp41WFJPden/P7dz+vlj7x77XdybtBMkSFWuB
291
+ yIIlUSIm3rdSxMKNslA9IeIj6gWHK0RQMLMSgmdoIVpkovnQhmJiNRtZP9pO
292
+ w3iQFLt3vzt6942tWu+Ab5EAHLUytKhGaCbX3r6xdOXpx0ixbpLEiYnARkBG
293
+ YIzBXE9n3DVcFXJbOCxlULuQ41LlD9AytCUQ1DOpZ7hctBibMBlYP9qN/HA7
294
+ Ke7d6Pnx7ns3/+Mfv93oGTjSC5gjWmKa6wWM4Em9u945c+5TRNSVKFIRLi20
295
+ CGYeca7HZfsDz44i0iL2h1WCAGZSLqEMROqZ1QsFL5pPTSgmJox2Iz/ajf3e
296
+ dlLcvd5zo93Jzmvf/9di69ZA4tQj+KIhAa25gDmmL+iQJBRbt6bx2saeTTuf
297
+ JlWRKC6bHYWIxRARszATk87dY7lAPEvr2gbNHOIs6SwZpoEJoeR68Kz5xGg2
298
+ tjoZWjfcicNwJ8m3b3b9aDeafPjLb+7+18vvEZFD8K7RRXaitcHjmqTm55MP
299
+ 3rqXbmxmEiVPk3oWY8uen8odsphSiYWIERizRL+KkFmEqCYJNPfvs/i/IhyB
300
+ KXjRIjchn4rmU+PHw8iP9iI/uJfkW7e6briT5ndvvHT7u9/8SY3oYkGv0H23
301
+ yCwCgke/+tmN7ubjTqx9Sl1uWCr5hzKgladSrvI5LiPYCgoNzGVBqcraArMq
302
+ E5RJvUADw3tRV0jIpgbZxIZsbMN4L3LD3dgNtpP83s1eGO4m2d2PXrr50j+/
303
+ 3OgdbBq/+26RoQWrFQfuD99+/Vq8dnbLxMkT6vIukxK8pyo4EZ4R6AumEJgR
304
+ mODL68EzBccUApMGRnBlUOMyQVEIikw0n1jNxrbk+HbshzuR273XKe7e6Pnh
305
+ bja+/va3bn/n316piM5rnHdHWf77AYAWuMn5Z/z+L+4Q8Kt4+dR5n03OlrUD
306
+ ZQpBEBwjOIF3UhaWgsAXAvXz6/BOSqueC1xuQjY1KMY2TMc2TEbWDXdjP9qJ
307
+ /WA3yXfudPOtW90wGXy089Mf/Mv2T773TovYn5j4k3aKLuoVjGtL6FaiOL7w
308
+ tW98JVpZe8EknShaXs1tr+9Mr+9MknqJUzVRrGws2EbK3KgXAQTvRX0h6grW
309
+ IjMhy0yYDq0bDWM32E61KLJi586Pb33v29/zo0HW6BZ1DeKP7RG8HwDaVo3n
310
+ PQQSp5EWmSUis/o7X9zsP/7bL0T95U+ZpGtN2nGm0/Um7TmJEzVJGkgMmAll
311
+ wjArQHqBOtbCieaZ8dOxDdNxFPKJ1Tx3frT3+t5br/9o980f3yQiL0nqNc/q
312
+ On/fxD+sZmnbaKgwRCS9y59YOfXMc88mq+ufkThdkTiN2BpiMWriuOwlMgKa
313
+ Gf/gJBSFwHuBegp54dRlO25v5+fbr/7g6uSj9/ZamqV9o2H6voi/3/0CvKCV
314
+ xrSAcWDDxOqnf/d879KVK7bXP89RsiLGpMwSkYglAqAI0FCQaq4uH/rR8Pro
315
+ w3d+ufvGj2+15CXNEDfcj84/jB0ji7pJmhsmDu8YqcBLzpzrpWfPL0XdfkpE
316
+ 5CajaX7no1F29+akUcEJjbwktIwH2jDxMLfMmJbmigMgSJwaLbLjPAzo6O0y
317
+ /6dbZo4Mjujw/iHT+D6fY9Iu76+EMEI2wQLuN88f6saph7FvsA2INlCae4bq
318
+ 9Qhd0NzYRuxD2zH2sAA4SRJ11BJ1W0GmTbQf+p7Bhw3AUTkE0fGbJo+KOH8j
319
+ ts6e5Nkn+T+c8NqvPQAP8l/433qp/wYZEIaDro/1JgAAAABJRU5ErkJggg==
320
+
data/lib/tween.rb ADDED
@@ -0,0 +1,383 @@
1
+ # This is a tweening library for Ruby. It has no dependencies, but was
2
+ # designed with Gosu in mind.
3
+
4
+ # This is mostly an implementation of Robert Penner's easing equations
5
+ # More information on the equations can be found here:
6
+ # http://www.robertpenner.com/easing/
7
+ #
8
+ # UziMonkey <michael.c.morin@gmail.com>
9
+
10
+ class Tween
11
+ attr_reader :done
12
+ attr_reader :easer
13
+
14
+ def initialize(start, finish, easer, duration)
15
+ @start, @finish = start, finish
16
+ @easer, @duration = easer, duration
17
+
18
+ @time = 0
19
+ @done = false
20
+ end
21
+
22
+ def update(delta)
23
+ @time += delta
24
+ if @time > @duration
25
+ @time = @duration
26
+ @done = true
27
+ end
28
+ end
29
+
30
+ def [](idx)
31
+ @easer.ease(
32
+ @time,
33
+ @start[idx],
34
+ (@finish[idx] - @start[idx]),
35
+ @duration
36
+ )
37
+ end
38
+
39
+ def x; self[0]; end
40
+ def y; self[1]; end
41
+ def z; self[2]; end
42
+
43
+ # In the following ease methods:
44
+ # st = start
45
+ # t = time
46
+ # d = duration
47
+ # ch = change
48
+
49
+ # I know, these are quite messy. I don't know 100% what's going on in many
50
+ # of them, but they're translated from Penner's ActionScript code which was
51
+ # uncommented and rather indecipherable.
52
+ module Linear
53
+ def self.ease(t, st, ch, d)
54
+ ch * t / d + st
55
+ end
56
+ end
57
+
58
+ module Sine
59
+ module In
60
+ def self.ease(t, st, ch, d)
61
+ -ch * Math.cos(t / d * (Math::PI / 2)) + ch + st
62
+ end
63
+ end
64
+
65
+ module Out
66
+ def self.ease(t, st, ch, d)
67
+ ch * Math.sin(t / d * (Math::PI / 2)) + st
68
+ end
69
+ end
70
+
71
+ module InOut
72
+ def self.ease(t, st, ch, d)
73
+ -ch / 2 * (Math.cos(Math::PI * t / d) - 1) + st
74
+ end
75
+ end
76
+ end
77
+
78
+ module Circ
79
+ module In
80
+ def self.ease(t, st, ch, d)
81
+ -ch * (Math.sqrt(1 - (t/d) * t/d) - 1) + st
82
+ end
83
+ end
84
+
85
+ module Out
86
+ def self.ease(t, st, ch, d)
87
+ t = t/d - 1
88
+ ch * Math.sqrt(1 - t * t) + st
89
+ end
90
+ end
91
+
92
+ module InOut
93
+ def self.ease(t, st, ch, d)
94
+ if (t /= d/2.0) < 1
95
+ return -ch / 2 * (Math.sqrt(1 - t*t) - 1) + st
96
+ else
97
+ return ch / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + st
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ module Bounce
104
+ module Out
105
+ def self.ease(t, st, ch, d)
106
+ if (t /= d) < (1/2.75)
107
+ ch * (7.5625 * t * t) + st
108
+ elsif t < (2 / 2.75)
109
+ ch * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + st
110
+ elsif t < (2.5 / 2.75)
111
+ ch * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + st
112
+ else
113
+ ch * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + st
114
+ end
115
+ end
116
+ end
117
+
118
+ module In
119
+ def self.ease(t, st, ch, d)
120
+ ch - Tween::Bounce::Out.ease(d-t, 0, ch, d) + st
121
+ end
122
+ end
123
+
124
+ module InOut
125
+ def self.ease(t, st, ch, d)
126
+ if t < d/2.0
127
+ Tween::Bounce::In.ease(t*2.0, 0, ch, d) * 0.5 + st
128
+ else
129
+ Tween::Bounce::Out.ease(t*2.0 - d, 0, ch, d) * 0.5 + ch * 0.5 + st
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ module Back
136
+ module In
137
+ def self.ease(t, st, ch, d, s=1.70158)
138
+ ch * (t/=d) * t * ((s+1) * t - s) + st
139
+ end
140
+ end
141
+
142
+ module Out
143
+ def self.ease(t, st, ch, d, s=1.70158)
144
+ ch * ((t=t/d-1) * t * ((s+1) * t + s) + 1) + st
145
+ end
146
+ end
147
+
148
+ module InOut
149
+ def self.ease(t, st, ch, d, s=1.70158)
150
+ if (t /= d/2.0) < 1
151
+ ch / 2.0 * (t * t * (((s *= (1.525)) + 1) * t - s)) + st
152
+ else
153
+ ch / 2.0 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + st
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ module Cubic
160
+ module In
161
+ def self.ease(t, st, ch, d)
162
+ ch * (t /= d) * t * t + st
163
+ end
164
+ end
165
+
166
+ module Out
167
+ def self.ease(t, st, ch, d)
168
+ ch * ((t = t / d.to_f - 1) * t * t + 1) + st
169
+ end
170
+ end
171
+
172
+ module InOut
173
+ def self.ease(t, st, ch, d)
174
+ if (t /= d / 2.0) < 1
175
+ ch / 2.0 * t * t * t + st
176
+ else
177
+ ch / 2.0 * ((t -= 2) * t * t + 2) + st
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ module Expo
184
+ module In
185
+ def self.ease(t, st, ch, d)
186
+ if t == 0
187
+ st
188
+ else
189
+ ch * (2 ** (10 * (t / d.to_f - 1))) + st
190
+ end
191
+ end
192
+ end
193
+
194
+ module Out
195
+ def self.ease(t, st, ch, d)
196
+ if t == d
197
+ st + ch
198
+ else
199
+ ch * (-(2 ** (-10 * t / d.to_f)) + 1) + st
200
+ end
201
+ end
202
+ end
203
+
204
+ module InOut
205
+ def self.ease(t, st, ch, d)
206
+ if t == 0
207
+ st
208
+ elsif t == d
209
+ st + ch
210
+ elsif (t /= d / 2.0) < 1
211
+ ch / 2.0 * (2 ** (10 * (t - 1))) + st
212
+ else
213
+ ch / 2.0 * (-(2 ** (-10 * (t -= 1))) + 2) + st
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ module Quad
220
+ module In
221
+ def self.ease(t, st, ch, d)
222
+ ch * (t /= d.to_f) * t + st
223
+ end
224
+ end
225
+
226
+ module Out
227
+ def self.ease(t, st, ch, d)
228
+ -ch * (t /= d.to_f) * (t - 2) + st
229
+ end
230
+ end
231
+
232
+ module InOut
233
+ def self.ease(t, st, ch, d)
234
+ if (t /= d / 2.0) < 1
235
+ ch / 2.0 * t * t + st
236
+ else
237
+ -ch / 2.0 * ((t -= 1) * (t - 2) - 1) + st
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ module Quart
244
+ module In
245
+ def self.ease(t, st, ch, d)
246
+ ch * (t /= d.to_f) * t * t * t + st
247
+ end
248
+ end
249
+
250
+ module Out
251
+ def self.ease(t, st, ch, d)
252
+ -ch * ((t = t / d.to_f - 1) * t * t * t - 1) + st
253
+ end
254
+ end
255
+
256
+ module InOut
257
+ def self.ease(t, st, ch, d)
258
+ if (t /= d / 2.0) < 1
259
+ ch / 2.0 * t * t * t * t + st
260
+ else
261
+ -ch / 2.0 * ((t -= 2) * t * t * t - 2) + st
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+ module Quint
268
+ module In
269
+ def self.ease(t, st, ch, d)
270
+ ch * (t /= d.to_f) * t * t * t * t + st
271
+ end
272
+ end
273
+
274
+ module Out
275
+ def self.ease(t, st, ch, d)
276
+ ch * ((t = t / d.to_f - 1) * t * t *t * t + 1) + st
277
+ end
278
+ end
279
+
280
+ module InOut
281
+ def self.ease(t, st, ch, d)
282
+ if (t /= d / 2.0) < 1
283
+ ch / 2.0 * t * t *t * t * t + st
284
+ else
285
+ ch / 2.0 * ((t -= 2) * t * t * t * t + 2) + st
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ module Elastic
292
+ module In
293
+ def self.ease(t, st, ch, d, a = 5, p = 0)
294
+ s = 0
295
+
296
+ if t == 0
297
+ return st
298
+ elsif (t /= d.to_f) >= 1
299
+ return st + ch
300
+ end
301
+
302
+ p = d * 0.3 if p == 0
303
+
304
+ if (a == 0) || (a < ch.abs)
305
+ a = ch
306
+ s = p / 4.0
307
+ else
308
+ s = p / (2 * Math::PI) * Math.asin(ch / a.to_f)
309
+ end
310
+
311
+ -(a * (2 ** (10 * (t -= 1))) * Math.sin( (t * d - s) * (2 * Math::PI) / p)) + st
312
+ end
313
+ end
314
+
315
+ module Out
316
+ def self.ease(t, st, ch, d, a = 0.1, p = 0)
317
+ s = 0
318
+
319
+ if t == 0
320
+ return st
321
+ elsif (t /= d.to_f) >= 1
322
+ return st + ch
323
+ end
324
+
325
+ p = d * 0.3 if p == 0
326
+
327
+ if (a == 0) || (a < ch.abs)
328
+ a = ch
329
+ s = p / 4.0
330
+ else
331
+ s = p / (2 * Math::PI) * Math.asin(ch / a.to_f)
332
+ end
333
+
334
+ a * (2 ** (-10 * t)) * Math.sin((t * d - s) * (2 * Math::PI) / p.to_f) + ch + st
335
+ end
336
+ end
337
+ end
338
+
339
+ # This is mostly for use by demo.rb
340
+ EASERS = [
341
+ Linear,
342
+
343
+ Sine::In,
344
+ Sine::Out,
345
+ Sine::InOut,
346
+
347
+ Circ::In,
348
+ Circ::Out,
349
+ Circ::InOut,
350
+
351
+ Bounce::Out,
352
+ Bounce::In,
353
+ Bounce::InOut,
354
+
355
+ Back::In,
356
+ Back::Out,
357
+ Back::InOut,
358
+
359
+ Cubic::In,
360
+ Cubic::Out,
361
+ Cubic::InOut,
362
+
363
+ Expo::In,
364
+ Expo::Out,
365
+ Expo::InOut,
366
+
367
+ Quad::In,
368
+ Quad::Out,
369
+ Quad::InOut,
370
+
371
+ Quart::In,
372
+ Quart::Out,
373
+ Quart::InOut,
374
+
375
+ Quint::In,
376
+ Quint::Out,
377
+ Quint::InOut,
378
+
379
+ Elastic::In,
380
+ Elastic::Out
381
+ ]
382
+
383
+ end
data/tween.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{tween}
5
+ s.version = "0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Michael Morin"]
9
+ s.date = %q{2010-10-01}
10
+ s.description = %q{Fluid motion using tweens for Ruby}
11
+ s.email = %q{michael.c.morin@gmail.com}
12
+ s.extra_rdoc_files = ["README.markdown", "lib/tween.rb"]
13
+ s.files = ["Manifest", "README.markdown", "Rakefile", "examples/demo.rb", "lib/tween.rb", "tween.gemspec"]
14
+ s.homepage = %q{http://ruby.about.com/}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Tween", "--main", "README.markdown"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{tween}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Fluid motion using tweens for Ruby}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tween
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ version: "0.1"
9
+ platform: ruby
10
+ authors:
11
+ - Michael Morin
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-10-01 00:00:00 -04:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: Fluid motion using tweens for Ruby
21
+ email: michael.c.morin@gmail.com
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files:
27
+ - README.markdown
28
+ - lib/tween.rb
29
+ files:
30
+ - Manifest
31
+ - README.markdown
32
+ - Rakefile
33
+ - examples/demo.rb
34
+ - lib/tween.rb
35
+ - tween.gemspec
36
+ has_rdoc: true
37
+ homepage: http://ruby.about.com/
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --line-numbers
43
+ - --inline-source
44
+ - --title
45
+ - Tween
46
+ - --main
47
+ - README.markdown
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 1
65
+ - 2
66
+ version: "1.2"
67
+ requirements: []
68
+
69
+ rubyforge_project: tween
70
+ rubygems_version: 1.3.7
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Fluid motion using tweens for Ruby
74
+ test_files: []
75
+