-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtransition_v1.lua
More file actions
353 lines (292 loc) · 9.69 KB
/
Copy pathtransition_v1.lua
File metadata and controls
353 lines (292 loc) · 9.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
-------------------------------------------------------------------------------
--
-- Corona Labs
--
-- transition.lua
--
-- Code is MIT licensed; see https://www.coronalabs.com/links/code/license
--
-------------------------------------------------------------------------------
-- copies all key/value pairs
local function copyTable( src )
local t = {}
for k,v in pairs( src ) do
t[k] = v
end
return t
end
-------------------------------------------------------------------------------
-- NOTE: transition is assigned to the global var "transition" in init.lua.
-- This file should follos standard Lua module conventions
local transition = { _activeTweens = {} }
transition._nonPropertyKeys =
{
time=true, transition=true, delay=true, delta=true,
onStart=true, onComplete=true
}
local numberKeys =
{
x=true, y=true, xScale=true, yScale=true, rotation=true, width=true, height=true,
alpha=true,
xReference=true, yReference=true,
maskX=true, maskY=true, maskScaleX=true, maskScaleY=true, maskRotation=true,
delta=true,
}
local function validateValue( k, v )
if ( "number" == type( v ) and numberKeys[k] ) then
local isNan = ( v ~= v )
if ( isNan ) then
print( "ERROR: Invalid number argument provided. Attempt to set property " .. k .. " to NaN." )
end
assert( not isNan )
end
return v
end
transition._initTween = function( tween, parameters )
local target = tween._target
-- onStart listener
--[[
local onStart = tween._onStart
if onStart and type(onStart) == "function" then
onStart( target )
tween._onStart = nil -- only call once
end
--]]
local listener = tween._onStart
if listener then
Runtime.callListener( listener, "onStart", target )
tween._onStart = nil -- only call once
end
local keysStart = {}
local keysFinish = {}
local invalidKeys = transition._nonPropertyKeys
local isDeltaValue = validateValue( "delta", parameters.delta )
for k,v in pairs( parameters ) do
if not invalidKeys[k] then
-- Only tween properties that have a non-nil starting value
local startValue = target[k]
if startValue then
keysStart[k] = startValue
local finishValue = (isDeltaValue and (startValue+v)) or v
keysFinish[k] = validateValue( k, finishValue )
--print( "Tween("..k..") ["..startValue..","..keysFinish[k].."]" )
end
end
end
tween._keysStart = keysStart
tween._keysFinish = keysFinish
end
transition._add = function( tween )
local activeTweens = transition._activeTweens
-- Once we have at least one tween, register for frame events
if #activeTweens == 0 and not transition._hasEventListener then
transition._hasEventListener = true
Runtime:addEventListener( "enterFrame", transition )
end
table.insert( activeTweens, tween )
end
transition.to = function( target, parameters )
local tween = nil
if target and parameters then
-- faster to access a local timer var than a global one
local transition = transition
tween = {}
local t = system.getTimer()
tween._target = target
tween._timeStart = t
tween._duration = parameters.time or 500
tween._transition = parameters.transition or easing.linear
tween._onStart = Runtime.verifyListener( parameters.onStart, "onStart" )
tween._onComplete = Runtime.verifyListener( parameters.onComplete, "onComplete" )
local delay = parameters.delay
if type(delay) == "number" then
tween._delay = delay
-- save off params: init after delay to minimize race conditions
local params = copyTable( parameters )
tween._delayParams = params
--[[
local params = {}
tween._delayParams = params
for k,v in pairs( parameters ) do
params[k] = v
end
--]]
else
-- no delay, so init immediately
transition._initTween( tween, parameters )
end
transition._add( tween )
end
return tween
end
transition.from = function( target, parameters )
local tween = nil
if target and parameters then
local params = {}
local invalidKeys = transition._nonPropertyKeys
for k,v in pairs( parameters ) do
if not invalidKeys[k] then
params[k] = target[k]
target[k] = validateValue( k, v )
else
-- copy over non-property keys, e.g. time, delay, etc.
params[k] = v
end
end
tween = transition.to( target, params )
end
return tween
end
transition.cancel = function( tween )
tween._cancel = true
end
function transition:enterFrame( event )
-- Calls to listeners could trigger a call to transition:add,
-- causing changes to the tween array during iteration of that array.
-- To prevent contention, we swap it with a tmp tween table and then later
-- restore the original, appending any new tweens added to the tmp table
local currentActiveTweens = self._activeTweens
self._activeTweens = {}
local currentTime = event.time
-- TODO: See if we can remove during traversal
local toRemove = {}
--print( "Num active tweens: ".. #currentActiveTweens )
for i,tween in ipairs( currentActiveTweens ) do
--print( "["..i.."]" )
if tween._cancel then
-- queue up cancelled tween for removal
table.insert( toRemove, i )
else
local delay = tween._delay
if delay and ( currentTime >= (tween._timeStart + delay) ) then
tween._delay = nil
tween._timeStart = currentTime
delay = nil
end
if not delay then
local params = tween._delayParams
if params then
transition._initTween( tween, params )
tween._delayParams = nil
end
local target = tween._target
local keysFinish = tween._keysFinish
local t = currentTime - tween._timeStart
if t < 0 then t = 0 end
local tMax = tween._duration
if t < tMax then
for k,v in pairs( tween._keysStart ) do
target[k] = tween._transition( t, tMax, v, keysFinish[k] - v )
--local newVal = tween._transition( t, tMax, v, keysFinish[k] - v )
--print( "\t("..t.."/"..tMax..") "..tostring(target) .."["..k.."] = "..target[k].."(=="..newVal..")" )
end
else
for k,v in pairs( keysFinish ) do
target[k] = v
--print( "\t("..t..">="..tMax..") "..tostring(target) .."["..k.."] = "..v )
end
-- onComplete listener
local listener = tween._onComplete
if listener then
Runtime.callListener( listener, "onComplete", target )
end
-- queue up complete tween for removal
table.insert( toRemove, i )
end
end
end
end
for i=#toRemove,1,-1 do
table.remove( currentActiveTweens, toRemove[i] )
end
-- Swap out tmp tween table and restore self._activeTweens.
-- Append any new tweens in the tmp table back into _activeTweens
local tmpTweens = self._activeTweens
if #tmpTweens > 0 then
for _,tween in ipairs( tmpTweens ) do
table.insert( currentActiveTweens, tween )
end
end
self._activeTweens = currentActiveTweens
if #currentActiveTweens == 0 then
--print( "remove transition.enterFrame" )
Runtime:removeEventListener( "enterFrame", transition )
transition._hasEventListener = false
end
end
function transition._setInvisible( object )
object.isVisible = false
end
function transition._dissolvePrepareSrc( object )
object.alpha = 1
end
function transition._dissolvePrepareDst( object )
object.alpha = 0
object.isVisible = true
end
function transition.dissolve( src, dst, duration, delayDuration )
-- faster to access a local timer var than a global one
local transition = transition
duration = duration or 500
transition.to( src, { alpha=0, time=duration, delay=delayDuration, onStart=transition._dissolvePrepareSrc, onComplete=transition._setInvisible } )
transition.to( dst, { alpha=1, time=duration, delay=delayDuration, onStart=transition._dissolvePrepareDst } )
end
function transition._createSlideParameters( target, direction, pos, duration )
local bounds = target.stageBounds
local dx = 0
local dy = 0
-- Calculate all deltas as if we're sliding "in" from offscreen (pos)
if ( "left" == pos ) then
dx = bounds.xMax
elseif ( "right" == pos ) then
dx = bounds.xMin - display.stageWidth
elseif ( "top" == pos ) then
dy = bounds.yMax
else -- "bottom"
dy = bounds.yMin - display.stageHeight
end
local result = nil
if ( dx ~= 0 or dy ~= 0 ) then
if ( "out" == direction ) then
result = { x=(target.x-dx), y=(target.y-dy), time=duration, onComplete=transition._setInvisible }
else
-- store precise final positions
result = { x=target.x, y=target.y, time=duration }
-- init o's starting position off screen
target:translate( -dx, -dy )
end
end
return result
end
function transition.slide( src, dst, duration, dstEntryPos, style )
-- faster to access a local timer var than a global one
local transition = transition
-- TODO: Reorder src to be *above* dst
-- src:moveAbove( dst )
src.isVisible = true
dst.isVisible = true
duration = duration or 1000
local srcParameters = nil
if ( style == "over" ) then
src.alpha = 1
srcParameters = { alpha=0, time=duration, onComplete=transition._setInvisible }
else
-- "push"
local oppositePos = "top"
if ( dstEntryPos == "left" ) then
oppositePos = "right"
elseif ( dstEntryPos == "right" ) then
oppositePos = "left"
elseif( dstEntryPos == "top" ) then
oppositePos = "bottom"
end
--print( "pos,oppositePos = "..dstEntryPos ..","..oppositePos )
srcParameters = transition._createSlideParameters( src, "out", oppositePos, duration )
end
transition.to( src, srcParameters )
--printTable( srcParameters, "slide srcParam" )
dstParameters = transition._createSlideParameters( dst, "in", dstEntryPos, duration )
transition.to( dst, dstParameters )
--printTable( dstParameters, "slide dstParam" )
end
return transition