@@ -256,6 +256,44 @@ function handle_raf(time) {
256
256
}
257
257
}
258
258
259
+ /**
260
+ * @param {{(t: number): number;(t: number): number;(arg0: number): any;} } easing_fn
261
+ * @param {((t: number, u: number) => string) } css_fn
262
+ * @param {number } duration
263
+ * @param {string } direction
264
+ * @param {boolean } reverse
265
+ */
266
+ function create_keyframes ( easing_fn , css_fn , duration , direction , reverse ) {
267
+ /** @type {Keyframe[] } */
268
+ const keyframes = [ ] ;
269
+ // We need at least two frames
270
+ const frame_time = 16.666 ;
271
+ const max_duration = Math . max ( duration , frame_time ) ;
272
+ // Have a keyframe every fame for 60 FPS
273
+ for ( let i = 0 ; i <= max_duration ; i += frame_time ) {
274
+ let time ;
275
+ if ( i + frame_time > max_duration ) {
276
+ time = 1 ;
277
+ } else if ( i === 0 ) {
278
+ time = 0 ;
279
+ } else {
280
+ time = i / max_duration ;
281
+ }
282
+ let t = easing_fn ( time ) ;
283
+ if ( reverse ) {
284
+ t = 1 - t ;
285
+ }
286
+ keyframes . push ( css_to_keyframe ( css_fn ( t , 1 - t ) ) ) ;
287
+ }
288
+ if ( direction === 'out' || reverse ) {
289
+ keyframes . reverse ( ) ;
290
+ }
291
+ return keyframes ;
292
+ }
293
+
294
+ /** @param {number } t */
295
+ const linear = ( t ) => t ;
296
+
259
297
/**
260
298
* @param {HTMLElement } dom
261
299
* @param {() => import('./types.js').TransitionPayload } init
@@ -286,38 +324,15 @@ function create_transition(dom, init, direction, effect) {
286
324
const delay = payload . delay ?? 0 ;
287
325
const css_fn = payload . css ;
288
326
const tick_fn = payload . tick ;
289
-
290
- /** @param {number } t */
291
- const linear = ( t ) => t ;
292
327
const easing_fn = payload . easing || linear ;
293
328
294
- /** @type {Keyframe[] } */
295
- const keyframes = [ ] ;
296
-
297
329
if ( typeof tick_fn === 'function' ) {
298
330
animation = new TickAnimation ( tick_fn , duration , delay , direction === 'out' ) ;
299
331
} else {
300
- if ( typeof css_fn === 'function' ) {
301
- // We need at least two frames
302
- const frame_time = 16.666 ;
303
- const max_duration = Math . max ( duration , frame_time ) ;
304
- // Have a keyframe every fame for 60 FPS
305
- for ( let i = 0 ; i <= max_duration ; i += frame_time ) {
306
- let time ;
307
- if ( i + frame_time > max_duration ) {
308
- time = 1 ;
309
- } else if ( i === 0 ) {
310
- time = 0 ;
311
- } else {
312
- time = i / max_duration ;
313
- }
314
- const t = easing_fn ( time ) ;
315
- keyframes . push ( css_to_keyframe ( css_fn ( t , 1 - t ) ) ) ;
316
- }
317
- if ( direction === 'out' ) {
318
- keyframes . reverse ( ) ;
319
- }
320
- }
332
+ const keyframes =
333
+ typeof css_fn === 'function'
334
+ ? create_keyframes ( easing_fn , css_fn , duration , direction , false )
335
+ : [ ] ;
321
336
animation = dom . animate ( keyframes , {
322
337
duration,
323
338
endDelay : delay ,
@@ -421,6 +436,26 @@ function create_transition(dom, init, direction, effect) {
421
436
} else {
422
437
dispatch_event ( dom , 'outrostart' ) ;
423
438
if ( needs_reverse ) {
439
+ const payload = transition . p ;
440
+ const current_animation = /** @type {Animation } */ ( animation ) ;
441
+ // If we are working with CSS animations, then before we call reverse, we also need to ensure
442
+ // that we reverse the easing logic. To do this we need to re-create the keyframes so they're
443
+ // in reverse with easing properly reversed too.
444
+ if (
445
+ payload !== null &&
446
+ payload . css !== undefined &&
447
+ current_animation . playState === 'idle'
448
+ ) {
449
+ const duration = payload . duration ?? 300 ;
450
+ const css_fn = payload . css ;
451
+ const easing_fn = payload . easing || linear ;
452
+ const keyframes = create_keyframes ( easing_fn , css_fn , duration , direction , true ) ;
453
+ const effect = current_animation . effect ;
454
+ if ( effect !== null ) {
455
+ // @ts -ignore
456
+ effect . setKeyframes ( keyframes ) ;
457
+ }
458
+ }
424
459
/** @type {Animation | TickAnimation } */ ( animation ) . reverse ( ) ;
425
460
} else {
426
461
/** @type {Animation | TickAnimation } */ ( animation ) . play ( ) ;
0 commit comments