@@ -8,16 +8,10 @@ import {
88 renderFramesAt ,
99 transitionFrames ,
1010 Keyframe ,
11- removeStaleFrames ,
1211 RenderCache ,
13- cleanRenderCache ,
1412} from "../internal/animate/state" ;
1513
16- // TODO copy keyframes as soon as possible to make sure they aren't modified afterwards.
17- // TODO make sure callbacks don't fill up the stack.
18- // TODO defend against "bad" keyframes like negative timing.
19- // TODO keyframe callbacks
20-
14+ // TODO make sure recursive callbacks don't fill up the stack.
2115interface CallbackKeyframe extends Keyframe {
2216 callback ?: ( ) => void ;
2317}
@@ -38,17 +32,6 @@ interface CallbackStore {
3832 [ frameId : string ] : ( ) => void ;
3933}
4034
41- const removeExpiredFrameCallbacks = (
42- frames : InternalKeyframe [ ] ,
43- oldStore : CallbackStore ,
44- ) : CallbackStore => {
45- const newStore : CallbackStore = { } ;
46- for ( const frame of frames ) {
47- newStore [ frame . id ] = oldStore [ frame . id ] ;
48- }
49- return newStore ;
50- } ;
51-
5235const canvasBlobGenerator = ( keyframe : CanvasKeyframe ) : Point [ ] => {
5336 return mapPoints ( genFromOptions ( keyframe . blobOptions ) , ( { curr} ) => {
5437 curr . x += keyframe ?. canvasOptions ?. offsetX || 0 ;
@@ -63,38 +46,39 @@ export const canvasPath = (): CanvasAnimation => {
6346 let callbackStore : CallbackStore = { } ;
6447
6548 const renderFrame : CanvasAnimation [ "renderFrame" ] = ( ) => {
66- const renderTime = Date . now ( ) ;
67- internalFrames = removeStaleFrames ( internalFrames , renderTime ) ;
6849 const renderOutput = renderFramesAt ( {
6950 renderCache : renderCache ,
70- timestamp : renderTime ,
51+ timestamp : Date . now ( ) ,
7152 currentFrames : internalFrames ,
7253 } ) ;
54+
55+ // Update render cache with returned value.
7356 renderCache = renderOutput . renderCache ;
57+
58+ // Invoke callback if defined and the first time the frame is reached.
7459 if ( renderOutput . lastFrameId && callbackStore [ renderOutput . lastFrameId ] ) {
7560 callbackStore [ renderOutput . lastFrameId ] ( ) ;
7661 delete callbackStore [ renderOutput . lastFrameId ] ;
7762 }
63+
7864 return renderPath2D ( renderOutput . points ) ;
7965 } ;
8066
8167 const transition : CanvasAnimation [ "transition" ] = ( ...keyframes ) => {
82- const transitionTime = Date . now ( ) ;
8368 const transitionOutput = transitionFrames < CanvasKeyframe > ( {
8469 renderCache : renderCache ,
85- timestamp : transitionTime ,
70+ timestamp : Date . now ( ) ,
8671 currentFrames : internalFrames ,
8772 newFrames : keyframes ,
8873 shapeGenerator : canvasBlobGenerator ,
8974 } ) ;
90- renderCache = transitionOutput . renderCache ;
91- internalFrames = transitionOutput . newFrames ;
9275
93- // Cleanup stored data that is no longer associated with a known frame.
94- callbackStore = removeExpiredFrameCallbacks ( internalFrames , callbackStore ) ;
95- renderCache = cleanRenderCache ( internalFrames , renderCache ) ;
76+ // Reset internal state..
77+ internalFrames = transitionOutput . newFrames ;
78+ callbackStore = { } ;
79+ renderCache = { } ;
9680
97- // Populate the callback using returned frame ids.
81+ // Populate callback store using returned frame ids.
9882 for ( const newFrame of internalFrames ) {
9983 if ( newFrame . transitionSourceFrameIndex === null ) continue ;
10084 const { callback} = keyframes [ newFrame . transitionSourceFrameIndex ] ;
0 commit comments