1234567891011121314151617181920212223242526272829303132333435363738394041424344(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Animation.mli *)type'at={from:'a;to_:'a;start:float;duration:float;timing:Timing.t}letmake?(timing=Timing.default)~(duration:float)~(now:float)(from:'a)(to_:'a):'at={from;to_;start=now;duration;timing}letstill(v:'a):'at={from=v;to_=v;start=0.;duration=0.;timing=Timing.linear}letprogress(a:'at)~(now:float):float=ifa.duration<=0.then1.elseTiming.ata.timing((now-.a.start)/.a.duration)letfinished(a:'at)~(now:float):bool=a.duration<=0.||now>=a.start+.a.durationletvalue~(lerp:'a->'a->float->'a)(a:'at)~(now:float):'a=iffinisheda~nowthena.to_elselerpa.froma.to_(progressa~now)letlerp_float(a:float)(b:float)(p:float):float=a+.((b-.a)*.p)type('k,'a)keyed={timing:Timing.t;duration:float;lerp:'a->'a->float->'a;anims:('k*'at)list}letkeyed?(timing=Timing.default)~(duration:float)~(lerp:'a->'a->float->'a)():('k,'a)keyed={timing;duration;lerp;anims=[]}letset(k:('k,'a)keyed)~(now:float)(key:'k)(target:'a):('k,'a)keyed=matchList.assoc_optkeyk.animswith|None->{kwithanims=(key,stilltarget)::k.anims}|Someawhena.to_=target->k|Somea->(* from where it is now: an interruption without a jump *)lethere=value~lerp:k.lerpa~nowin{kwithanims=(key,make~timing:k.timing~duration:k.duration~nowheretarget)::List.remove_assockeyk.anims}letvalue_of(k:('k,'a)keyed)~(now:float)(key:'k):'aoption=Option.map(funa->value~lerp:k.lerpa~now)(List.assoc_optkeyk.anims)letmoving(k:('k,'a)keyed)~(now:float):bool=List.exists(fun(_,a)->not(finisheda~now))k.anims