@@ -27,6 +27,8 @@ import {genFromOptions} from "../internal/gen";
2727import { BlobOptions } from "../public/blobs" ;
2828import { interpolateBetween , interpolateBetweenSmooth } from "../internal/animate/interpolate" ;
2929import { divide } from "../internal/animate/prepare" ;
30+ import { statefulAnimationGenerator } from "../internal/animate/state" ;
31+ import { CanvasKeyframe } from "../public/animate" ;
3032
3133const makePoly = ( pointCount : number , radius : number , center : Coord ) : Point [ ] => {
3234 const angle = ( 2 * Math . PI ) / pointCount ;
@@ -127,20 +129,28 @@ addCanvas(
127129) ;
128130
129131addCanvas ( 2 , ( ctx , width , height , animate ) => {
130- const startPeriod = Math . E * 1000 ;
131- const endPeriod = Math . PI * 1000 ;
132+ const startPeriod = ( 1 + Math . E ) * 1000 ;
133+ const endPeriod = ( 1 + Math . PI ) * 1000 ;
132134
133135 animate ( ( frameTime ) => {
134136 const startPercentage = calcBouncePercentage ( startPeriod , timingFunctions . ease , frameTime ) ;
137+ const startLengthPercentage = calcBouncePercentage (
138+ startPeriod * 0.8 ,
139+ timingFunctions . ease ,
140+ frameTime ,
141+ ) ;
135142 const startAngle = split ( startPercentage , - 45 , + 45 ) ;
136- const startLengthPercentage = mod ( startPercentage * 0.8 , 1 ) ;
137- const startLength = width * 0.2 + width * 0.1 * startLengthPercentage ;
143+ const startLength = width * 0.1 + width * 0.2 * startLengthPercentage ;
138144 const start = point ( width * 0.2 , height * 0.5 , 0 , 0 , startAngle , startLength ) ;
139145
140146 const endPercentage = calcBouncePercentage ( endPeriod , timingFunctions . ease , frameTime ) ;
147+ const endLengthPercentage = calcBouncePercentage (
148+ endPeriod * 0.8 ,
149+ timingFunctions . ease ,
150+ frameTime ,
151+ ) ;
141152 const endAngle = split ( endPercentage , 135 , 225 ) ;
142- const endLengthPercentage = mod ( endPercentage * 0.8 , 1 ) ;
143- const endLength = width * 0.2 + width * 0.1 * endLengthPercentage ;
153+ const endLength = width * 0.1 + width * 0.2 * endLengthPercentage ;
144154 const end = point ( width * 0.8 , height * 0.5 , endAngle , endLength , 0 , 0 ) ;
145155
146156 drawOpen ( ctx , start , end , true ) ;
@@ -416,7 +426,6 @@ addCanvas(2, (ctx, width, height, animate) => {
416426 drawClosed ( ctx , interpolateBetween ( percentage , blobA , blobB ) , true ) ;
417427 } ) ;
418428
419- // TODO have content about why being able to interrupt transitions with another.
420429 return `Interpolation requires points to be paired up from shape A to B. This means both blobs
421430 must have the same number of points and that the points should be matched in a way that
422431 minimizes movement.` ;
@@ -627,3 +636,54 @@ addCanvas(
627636 makes either side of the final point the handles.` ;
628637 } ,
629638) ;
639+
640+ addCanvas ( 1.6 , ( ctx , width , height ) => {
641+ const period = Math . PI * 1000 ;
642+ const center : Coord = { x : width * 0.5 , y : height * 0.5 } ;
643+ const size = Math . min ( width , height ) * 0.8 ;
644+
645+ const canvasBlobGenerator = ( keyframe : CanvasKeyframe ) : Point [ ] => {
646+ return mapPoints ( genFromOptions ( keyframe . blobOptions ) , ( { curr} ) => {
647+ curr . x += center . x - size / 2 ;
648+ curr . y += center . y - size / 2 ;
649+ return curr ;
650+ } ) ;
651+ } ;
652+
653+ const animation = statefulAnimationGenerator (
654+ canvasBlobGenerator ,
655+ ( points : Point [ ] ) => drawClosed ( ctx , points , true ) ,
656+ ( ) => { } ,
657+ ) ( ) ;
658+
659+ const renderFrame = ( ) => {
660+ ctx . clearRect ( 0 , 0 , width , height ) ;
661+ animation . renderFrame ( ) ;
662+ requestAnimationFrame ( renderFrame ) ;
663+ } ;
664+ requestAnimationFrame ( renderFrame ) ;
665+
666+ const loopAnimation = ( ) : void => animation . transition ( genFrame ( ) ) ;
667+
668+ let frameCount = - 1 ;
669+ const genFrame = ( overrides : Partial < CanvasKeyframe > = { } ) : CanvasKeyframe => {
670+ frameCount ++ ;
671+ return {
672+ duration : period ,
673+ timingFunction : "ease" ,
674+ callback : loopAnimation ,
675+ blobOptions : {
676+ extraPoints : Math . max ( 0 , mod ( frameCount , 4 ) - 1 ) ,
677+ randomness : 4 ,
678+ seed : Math . random ( ) ,
679+ size,
680+ } ,
681+ ...overrides ,
682+ } ;
683+ } ;
684+
685+ animation . transition ( genFrame ( { duration : 0 } ) ) ;
686+
687+ // TODO have content about why being able to interrupt transitions with another.
688+ return `` ;
689+ } ) ;
0 commit comments