act
Version:
An animation engine for the canvas and dom
273 lines (236 loc) • 71 kB
HTML
<!DOCTYPE html><html lang="en"><head><title>act</title></head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><meta name="groc-relative-root" content=""><meta name="groc-document-path" content="act"><meta name="groc-project-path" content="src/act.coffee"><link rel="stylesheet" type="text/css" media="all" href="assets/style.css"><script type="text/javascript" src="assets/behavior.js"></script><body><div id="meta"><div class="file-path">src/act.coffee</div></div><div id="document"><div class="segment"></div><div class="segment"><div class="comments"><div class="wrapper"><h1 id="act">act</h1>
<p>Transaction based animation for dom and canvas</p>
<h3 id="usage">Usage</h3>
<h4 id="act">act</h4></div></div><div class="code"><div class="wrapper"><span class="nv">_ = </span><span class="nx">require</span> <span class="s">'underscore'</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actfunction">act.function</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="nv">actGenerator = </span><span class="o">-></span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actfunction">act.function</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nv">act = </span><span class="nf">(obj, dest, options = {}) -></span>
<span class="nv">scheduler = </span><span class="nx">act</span><span class="p">.</span><span class="nx">_scheduler</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Implicit</span>
<span class="nv">obj = </span><span class="nx">obj</span><span class="p">.</span><span class="nx">_obj</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">animator</span>
<span class="nv">task = </span><span class="k">new</span> <span class="nx">Task</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">dest</span><span class="p">,</span> <span class="nx">options</span>
<span class="nx">scheduler</span><span class="p">.</span><span class="nx">addTask</span> <span class="nx">task</span>
<span class="k">else</span>
<span class="k">for</span> <span class="nx">k</span> <span class="k">of</span> <span class="nx">dest</span>
<span class="nv">task = </span><span class="k">new</span> <span class="nx">Task</span> <span class="nx">obj</span><span class="p">,</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">pick</span> <span class="nx">dest</span><span class="p">,</span> <span class="nx">k</span><span class="p">),</span> <span class="nx">options</span>
<span class="nx">scheduler</span><span class="p">.</span><span class="nx">addTask</span> <span class="nx">task</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="acteaselinear-etc">act.EaseLinear, etc.</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">Ease</span>
<span class="nx">act</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">v</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="acton-actoff-acttrigger">act.on, act.off, act.trigger</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nx">_extendEventFunctions</span> <span class="nx">act</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actclone">act.clone</h2>
<p>Create a seperate act function with seperate scheduler, rate, etc
This does not clone tasks.</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act.clone = </span><span class="nx">actGenerator</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actrate">act.rate</h2>
<p>Rate allows speeding up and slowing down time.</p>
<pre><code>rate = 2 Twice as fast
rate = 0.5 Half as fast
</code></pre></div></div><div class="code"><div class="wrapper"> <span class="nv">act.rate = </span><span class="mi">1</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="acttickinterval">act.tickInterval</h2>
<p>Interval in seconds between update ticks (default: 1/60, 60 Hz)</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act.tickInterval = </span><span class="mi">1</span><span class="o">/</span><span class="mi">60</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="act-transactionbuilders">act._transactionBuilders</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nv">act._transactionBuilders = </span><span class="p">[]</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actplay">act.play</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nv">act.play = </span><span class="o">-></span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">act</span><span class="p">.</span><span class="nx">_playState</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Store reference to state to indentity specific start has been stopped</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act._playState = state = lastTick: </span><span class="nx">_getTime</span><span class="p">()</span>
<span class="nv">ticker = </span><span class="o">-></span>
<span class="k">if</span> <span class="nx">act</span><span class="p">.</span><span class="nx">_playState</span> <span class="o">==</span> <span class="nx">state</span>
<span class="nx">_setTimeout</span> <span class="nx">act</span><span class="p">.</span><span class="nx">tickInterval</span><span class="p">,</span> <span class="nx">ticker</span>
<span class="nv">timeCurrent = </span><span class="nx">_getTime</span><span class="p">()</span>
<span class="nv">timeElapsed = </span><span class="nx">timeCurrent</span> <span class="o">-</span> <span class="nx">state</span><span class="p">.</span><span class="nx">lastTick</span>
<span class="nx">act</span><span class="p">.</span><span class="nx">_tick</span> <span class="nx">timeElapsed</span> <span class="o">*</span> <span class="nx">act</span><span class="p">.</span><span class="nx">rate</span>
<span class="nv">state.lastTick = </span><span class="nx">timeCurrent</span>
<span class="nx">act</span><span class="p">.</span><span class="nx">trigger</span> <span class="s">'render'</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Continue tick
Start tick</p></div></div><div class="code"><div class="wrapper"> <span class="nx">_setTimeout</span> <span class="nx">act</span><span class="p">.</span><span class="nx">tickInterval</span><span class="p">,</span> <span class="nx">ticker</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="act-tick">act._tick</h2>
<p>Tick all your tasks</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act._tick = </span><span class="nf">(dt) -></span>
<span class="nx">act</span><span class="p">.</span><span class="nx">_rootScheduler</span><span class="p">.</span><span class="nx">tick</span> <span class="nx">dt</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actfastforward">act.fastForward</h2>
<p>Fast forward in time</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act.fastForward = </span><span class="nx">act</span><span class="p">.</span><span class="nx">_tick</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actstop">act.stop</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nv">act.stop = </span><span class="o">-></span>
<span class="nv">act._playState = </span><span class="kc">null</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actbegin">act.begin</h2>
<p>Start defining a new transaction</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act.begin = </span><span class="nf">(options) -></span>
<span class="nv">builder = </span><span class="k">new</span> <span class="nx">TransactionBuilder</span> <span class="nx">options</span>
<span class="nx">act</span><span class="p">.</span><span class="nx">_transactionBuilders</span><span class="p">.</span><span class="nx">push</span> <span class="nx">builder</span>
<span class="nx">builder</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="act-scheduler">act._scheduler</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span> <span class="nx">act</span><span class="p">,</span> <span class="s">'_scheduler'</span><span class="p">,</span>
<span class="nv">get: </span><span class="o">-></span>
<span class="nv">len = </span><span class="nx">act</span><span class="p">.</span><span class="nx">_transactionBuilders</span><span class="p">.</span><span class="nx">length</span>
<span class="k">if</span> <span class="nx">len</span> <span class="k">then</span> <span class="nx">act</span><span class="p">.</span><span class="nx">_transactionBuilders</span><span class="p">[</span><span class="nx">len</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="nx">act</span><span class="p">.</span><span class="nx">_rootScheduler</span>
<span class="nv">enumerable: </span><span class="kc">false</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actcommit">act.commit</h2>
<p>Stop defining a transaction and add it to its parent transaction</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act.commit = </span><span class="nf">() -></span>
<span class="nv">builderTop = </span><span class="nx">act</span><span class="p">.</span><span class="nx">_transactionBuilders</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nv">scheduler = </span><span class="nx">@_scheduler</span>
<span class="nx">scheduler</span><span class="p">.</span><span class="nx">addTask</span> <span class="nx">builderTop</span><span class="p">.</span><span class="nx">transaction</span><span class="p">()</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actproperty">act.property</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nv">act.property = </span><span class="nf">(obj, key, val, options) -></span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Default options to actOptions[k]</p></div></div><div class="code"><div class="wrapper"> <span class="k">if</span> <span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span> <span class="nx">options</span><span class="p">)</span> <span class="o">and</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span>
<span class="nv">options = </span><span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span><span class="p">()[</span><span class="nx">key</span><span class="p">]</span>
<span class="k">else</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Close over animatable value</p></div></div><div class="code"><div class="wrapper"> <span class="nv">store = value: </span><span class="nx">val</span>
<span class="nv">setter = </span><span class="nf">(v) -></span> <span class="nx">act</span> <span class="nx">store</span><span class="p">,</span> <span class="nv">value: </span><span class="nx">v</span><span class="p">,</span> <span class="nx">options</span>
<span class="nv">setter._actStore = </span><span class="nx">store</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">defineProperty</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span>
<span class="nv">get: </span><span class="o">-></span> <span class="nx">store</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">set: </span><span class="nx">setter</span>
<span class="nv">act._implicitPropertyStore = </span><span class="nf">(obj, key) -></span>
<span class="nv">d = </span><span class="nb">Object</span><span class="p">.</span><span class="nx">getOwnPropertyDescriptor</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span>
<span class="k">return</span> <span class="nx">d</span><span class="o">?</span><span class="p">.</span><span class="nx">set</span><span class="o">?</span><span class="p">.</span><span class="nx">_actStore</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actproperties">act.properties</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nv">act.properties = </span><span class="nf">(obj, properties, options) -></span>
<span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">properties</span>
<span class="nx">act</span><span class="p">.</span><span class="nx">property</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span><span class="p">,</span> <span class="nx">options</span><span class="o">?</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actimplicit">act.implicit</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"> <span class="nv">act.implicit = </span><span class="nf">(obj, options = {}) -></span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Default animation options</p></div></div><div class="code"><div class="wrapper"> <span class="nv">options = </span><span class="nx">_</span><span class="p">.</span><span class="nx">clone</span> <span class="nx">options</span>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">defaults</span> <span class="nx">options</span><span class="p">,</span> <span class="p">(</span><span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span> <span class="k">then</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span><span class="p">()</span> <span class="k">else</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">actOptions</span><span class="p">)</span>
<span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">obj</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Null means omit</p></div></div><div class="code"><div class="wrapper"> <span class="k">if</span> <span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">==</span> <span class="kc">null</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="nv">animator: </span><span class="kc">null</span><span class="p">}</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Undefined means default animator</p></div></div><div class="code"><div class="wrapper"> <span class="k">else</span> <span class="k">if</span> <span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">==</span> <span class="kc">undefined</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="nv">animator: </span><span class="nx">_defaultInterpolationForValue</span> <span class="nx">v</span><span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isString</span> <span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">or</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span> <span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="nv">animator: </span><span class="nx">options</span><span class="p">[</span><span class="nx">k</span><span class="p">]}</span>
<span class="k">else</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">"act: animator is not string or function"</span>
<span class="k">new</span> <span class="nx">Implicit</span> <span class="nx">act</span><span class="p">,</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">options</span>
<span class="nv">_defaultInterpolationForValue = </span><span class="nf">(v) -></span>
<span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isNumber</span> <span class="nx">v</span> <span class="k">then</span> <span class="nx">linearAnimator</span> <span class="k">else</span> <span class="nx">setAtEndAnimator</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="-rootscheduler">_rootScheduler</h2>
<p>act root scheduler</p></div></div><div class="code"><div class="wrapper"> <span class="nv">act._rootScheduler = </span><span class="k">new</span> <span class="nx">Scheduler</span><span class="p">()</span>
<span class="nx">act</span><span class="p">.</span><span class="nx">play</span><span class="p">()</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>End actGenerator</p></div></div><div class="code"><div class="wrapper"> <span class="k">return</span> <span class="nx">act</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="actanimator">act.Animator</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="nv">linearAnimator = </span><span class="nf">(obj, destinations) -></span>
<span class="nv">initials = </span><span class="p">{}</span>
<span class="nv">finals = </span><span class="p">{}</span>
<span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">destinations</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Handle operators</p></div></div><div class="code"><div class="wrapper"> <span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isObject</span> <span class="nx">v</span>
<span class="nv">ops = </span><span class="nx">_</span><span class="p">.</span><span class="nx">keys</span> <span class="nx">v</span>
<span class="k">throw</span> <span class="p">(</span><span class="k">new</span> <span class="nb">Error</span> <span class="s">"act: expected only one operator (</span><span class="si">#{</span><span class="nx">ops</span><span class="si">}</span><span class="s">) for key </span><span class="si">#{</span><span class="nx">k</span><span class="si">}</span><span class="s">"</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">ops</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">1</span>
<span class="nx">destinations</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nv">op: </span><span class="nx">ops</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nv">value: </span><span class="nx">v</span><span class="p">[</span><span class="nx">ops</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
<span class="k">else</span>
<span class="nx">destinations</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nv">op: </span><span class="s">'='</span><span class="p">,</span> <span class="nv">value: </span><span class="nx">v</span>
<span class="nx">initials</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span>
<span class="nx">finals</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">_final</span> <span class="nx">initials</span><span class="p">[</span><span class="nx">k</span><span class="p">],</span> <span class="nx">destinations</span><span class="p">[</span><span class="nx">k</span><span class="p">][</span><span class="s">'op'</span><span class="p">],</span> <span class="nx">destinations</span><span class="p">[</span><span class="nx">k</span><span class="p">][</span><span class="s">'value'</span><span class="p">]</span>
<span class="nf">(t) -></span>
<span class="nv">changed = </span><span class="p">{}</span>
<span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">finals</span>
<span class="nx">changed</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">_interp</span> <span class="nx">initials</span><span class="p">[</span><span class="nx">k</span><span class="p">],</span> <span class="nx">finals</span><span class="p">[</span><span class="nx">k</span><span class="p">],</span> <span class="nx">t</span>
<span class="nx">changed</span>
<span class="nv">_interp = </span><span class="nf">(a, b, t) -></span> <span class="nx">a</span> <span class="o">*</span> <span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="nx">t</span><span class="p">)</span> <span class="o">+</span> <span class="nx">b</span> <span class="o">*</span> <span class="nx">t</span>
<span class="nv">_final = </span><span class="nf">(initial, op, value) -></span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">==</span> <span class="s">'=='</span> <span class="o">or</span> <span class="nx">op</span> <span class="o">==</span> <span class="s">'='</span>
<span class="k">return</span> <span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">op</span> <span class="o">==</span> <span class="s">'/='</span>
<span class="k">return</span> <span class="nx">initial</span> <span class="o">/</span> <span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">op</span> <span class="o">==</span> <span class="s">'*='</span>
<span class="k">return</span> <span class="nx">initial</span> <span class="o">*</span> <span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">op</span> <span class="o">==</span> <span class="s">'-='</span>
<span class="k">return</span> <span class="nx">initial</span> <span class="o">-</span> <span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">op</span> <span class="o">==</span> <span class="s">'+='</span>
<span class="k">return</span> <span class="nx">initial</span> <span class="o">+</span> <span class="nx">value</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="setatendanimator">setAtEndAnimator</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="nv">setAtEndAnimator = </span><span class="nf">(obj, destinations) -></span>
<span class="nv">initials = </span><span class="nx">_</span><span class="p">.</span><span class="nx">pick</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">destinations</span><span class="p">)...</span>
<span class="nv">finals = </span><span class="nx">_</span><span class="p">.</span><span class="nx">clone</span> <span class="nx">destinations</span>
<span class="nf">(t) -></span> <span class="nx">_</span><span class="p">.</span><span class="nx">clone</span> <span class="p">(</span><span class="k">if</span> <span class="nx">t</span> <span class="o"><</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">initials</span> <span class="k">else</span> <span class="nx">finals</span><span class="p">)</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="animator-short-names">Animator short names</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="nv">mapAnimatorFromName =</span>
<span class="s">'setAtEnd'</span><span class="o">:</span> <span class="nx">setAtEndAnimator</span>
<span class="s">'linear'</span><span class="o">:</span> <span class="nx">linearAnimator</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>'type': typeByItemAnimator # Works on arrays and strings
'typeByWord': typeByWordAnimator # Works on strings only
'step': stepAnimator
'color': colorAnimator
'region': regionAnimator
'stringTypeWord': stringTypeByWordAnimator</p></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="acttask">act.Task</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="k">class</span> <span class="nx">Task</span>
<span class="nv">constructor: </span><span class="nf">(@obj, @destination, options = {}) -></span>
<span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">@destination</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s">'act: functions cannot be animated'</span><span class="p">)</span> <span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span> <span class="nx">v</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">duration</span><span class="o">?</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">duration</span> <span class="o"><=</span> <span class="mi">0</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">'act: duration must be positive'</span>
<span class="vi">@duration = </span><span class="nx">options</span><span class="p">.</span><span class="nx">duration</span> <span class="o">||</span> <span class="mi">1</span>
<span class="vi">@started = </span><span class="nx">options</span><span class="p">.</span><span class="nx">started</span> <span class="o">||</span> <span class="o">-></span>
<span class="vi">@completed = </span><span class="nx">options</span><span class="p">.</span><span class="nx">completed</span> <span class="o">||</span> <span class="o">-></span>
<span class="vi">@_easing = </span><span class="nx">options</span><span class="p">.</span><span class="nx">easing</span> <span class="o">||</span> <span class="nx">EaseLinear</span>
<span class="vi">@_animator = </span><span class="k">if</span> <span class="nx">_</span><span class="p">.</span><span class="nx">isString</span> <span class="nx">options</span><span class="p">.</span><span class="nx">animator</span>
<span class="nx">mapAnimatorFromName</span><span class="p">[</span><span class="nx">options</span><span class="p">.</span><span class="nx">animator</span><span class="p">]</span>
<span class="k">else</span>
<span class="nx">options</span><span class="p">.</span><span class="nx">animator</span> <span class="o">||</span> <span class="nx">linearAnimator</span>
<span class="vi">@startTime = </span><span class="mi">0</span>
<span class="vi">@_elapsed = </span><span class="mi">0</span>
<span class="nv">update: </span><span class="nf">(time) -></span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Start if we need to</p></div></div><div class="code"><div class="wrapper"> <span class="nv">elapsed = </span><span class="nx">time</span> <span class="o">-</span> <span class="nx">@startTime</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">@_elapsed</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">return</span> <span class="c1"># Haven't started yet</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">@_elapsed</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span>
<span class="nx">@_start</span><span class="p">()</span> <span class="c1"># Forwards over start point</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">@_elapsed</span> <span class="o">>=</span> <span class="nx">@duration</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">>=</span> <span class="nx">@duration</span><span class="p">)</span>
<span class="k">return</span> <span class="c1"># Already completed</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
<span class="nv">elapsed = </span><span class="mi">0</span> <span class="c1"># Clamp elapsed at start time</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">></span> <span class="nx">@duration</span><span class="p">)</span>
<span class="nv">elapsed = </span><span class="nx">@duration</span> <span class="c1"># Clamp elapsed at end time</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Update the children</p></div></div><div class="code"><div class="wrapper"> <span class="nv">eased = </span><span class="nx">@_easing</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">/</span> <span class="nx">@duration</span><span class="p">)</span>
<span class="nv">extender = </span><span class="p">(</span><span class="nx">@_interpolator</span> <span class="nx">eased</span><span class="p">)</span>
<span class="k">for</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">extender</span>
<span class="k">if</span> <span class="nv">store = </span><span class="nx">act</span><span class="p">.</span><span class="nx">_implicitPropertyStore</span> <span class="nx">@obj</span><span class="p">,</span> <span class="nx">k</span>
<span class="nv">store.value = </span><span class="nx">v</span>
<span class="k">else</span>
<span class="nx">@obj</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">v</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">>=</span> <span class="nx">@duration</span><span class="p">)</span>
<span class="nx">@_complete</span><span class="p">()</span>
<span class="vi">@_elapsed = </span><span class="nx">elapsed</span>
<span class="nv">_start: </span><span class="o">-></span>
<span class="vi">@_interpolator = </span><span class="nx">@_animator</span> <span class="nx">@obj</span><span class="p">,</span> <span class="nx">@destination</span>
<span class="nv">finalValue = </span><span class="nx">@_interpolator</span> <span class="mi">1</span>
<span class="nv">initialValue = </span><span class="nx">@_interpolator</span> <span class="mi">0</span>
<span class="nx">@obj</span><span class="p">.</span><span class="nx">actBefore</span><span class="o">?</span> <span class="nx">initialValue</span><span class="p">,</span> <span class="nx">finalValue</span>
<span class="nx">@started</span><span class="o">?</span><span class="p">()</span>
<span class="nv">_complete: </span><span class="o">-></span>
<span class="nv">initialValue = </span><span class="nx">@_interpolator</span> <span class="mi">0</span>
<span class="nv">finalValue = </span><span class="nx">@_interpolator</span> <span class="mi">1</span>
<span class="nx">@obj</span><span class="p">.</span><span class="nx">actAfter</span><span class="o">?</span> <span class="nx">initialValue</span><span class="p">,</span> <span class="nx">finalValue</span>
<span class="nx">@completed</span><span class="o">?</span><span class="p">()</span>
<span class="nv">_maxEndTime = </span><span class="nf">(tasks) -></span> <span class="nx">_</span><span class="p">.</span><span class="nx">reduce</span> <span class="nx">tasks</span><span class="p">,</span> <span class="p">(</span><span class="nf">(acc,task) -></span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span> <span class="nx">acc</span><span class="p">,</span> <span class="p">(</span><span class="nx">task</span><span class="p">.</span><span class="nx">startTime</span> <span class="o">+</span> <span class="nx">task</span><span class="p">.</span><span class="nx">duration</span><span class="p">)),</span> <span class="mi">0</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="easing">Easing</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="nv">Ease = </span><span class="p">{}</span>
<span class="nv">Ease.EaseLinear = </span> <span class="nv">EaseLinear = </span><span class="nf">(v) -></span> <span class="nx">v</span>
<span class="nv">Ease.EaseIn = </span> <span class="nv">EaseIn = </span><span class="nf">(v) -></span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span>
<span class="nv">Ease.EaseOut = </span> <span class="nv">EaseOut = </span><span class="nf">(v) -></span> <span class="mf">1.0</span> <span class="o">-</span> <span class="nx">EaseIn</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="nx">v</span><span class="p">)</span>
<span class="nv">Ease.EaseIn2 = </span> <span class="nv">EaseIn2 = </span><span class="nf">(v) -></span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span>
<span class="nv">Ease.EaseOut2 = </span> <span class="nv">EaseOut2 = </span><span class="nf">(v) -></span> <span class="mf">1.0</span> <span class="o">-</span> <span class="nx">EaseIn</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="nx">v</span><span class="p">)</span>
<span class="nv">Ease.EaseInOut = </span> <span class="nv">EaseInOut = </span><span class="nf">(v) -></span> <span class="k">if</span> <span class="nx">v</span> <span class="o"><</span> <span class="mf">0.5</span> <span class="k">then</span> <span class="nx">EaseIn</span><span class="p">(</span><span class="nx">v</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="k">else</span> <span class="nx">EaseOut</span><span class="p">(</span><span class="nx">v</span> <span class="o">*</span> <span class="mi">2</span> <span class="o">-</span> <span class="mf">1.0</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">+</span> <span class="mf">0.5</span>
<span class="nv">Ease.EaseInOut2 = </span> <span class="nv">EaseInOut2 = </span><span class="nf">(v) -></span> <span class="p">(</span><span class="mi">3</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span><span class="p">)</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span>
<span class="nv">Ease.EaseOutBounce = </span> <span class="nv">EaseOutBounce = </span><span class="nf">(v) -></span>
<span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o"><</span> <span class="mi">1</span> <span class="o">/</span> <span class="mf">2.75</span><span class="p">)</span>
<span class="mf">7.5625</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o"><</span> <span class="mi">2</span> <span class="o">/</span> <span class="mf">2.75</span><span class="p">)</span>
<span class="nx">v</span> <span class="o">-=</span> <span class="mf">1.5</span> <span class="o">/</span> <span class="mf">2.75</span>
<span class="mf">7.5625</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">+</span> <span class="mf">0.75</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">v</span> <span class="o"><</span> <span class="mf">2.5</span> <span class="o">/</span> <span class="mf">2.75</span><span class="p">)</span>
<span class="nx">v</span> <span class="o">-=</span> <span class="mf">2.25</span> <span class="o">/</span> <span class="mf">2.75</span>
<span class="mf">7.5625</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">+</span> <span class="mf">0.9375</span>
<span class="k">else</span>
<span class="nx">v</span> <span class="o">-=</span> <span class="mf">2.625</span> <span class="o">/</span> <span class="mf">2.75</span>
<span class="mf">7.5625</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">*</span> <span class="nx">v</span> <span class="o">+</span> <span class="mf">0.984375</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="transaction">Transaction</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="k">class</span> <span class="nx">Transaction</span>
<span class="nv">constructor: </span><span class="nf">(fields) -></span>
<span class="vi">@_serial = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">serial</span>
<span class="vi">@_rate = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">rate</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">'act: rate must be positive'</span> <span class="nx">unless</span> <span class="nx">@_rate</span> <span class="o">></span> <span class="mi">0</span>
<span class="vi">@_easing = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">easing</span>
<span class="vi">@_tasks = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">tasks</span>
<span class="vi">@_reverseTasks = </span><span class="p">(</span><span class="nx">@_tasks</span><span class="p">.</span><span class="nx">slice</span> <span class="mi">0</span><span class="p">).</span><span class="nx">reverse</span><span class="p">()</span>
<span class="vi">@_started = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">started</span>
<span class="vi">@_completed = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">completed</span>
<span class="vi">@_elapsed = </span><span class="mi">0</span>
<span class="vi">@duration = </span><span class="p">(</span><span class="nx">_maxEndTime</span> <span class="nx">@_tasks</span><span class="p">)</span> <span class="o">/</span> <span class="nx">@_rate</span>
<span class="vi">@startTime = </span><span class="mi">0</span>
<span class="nv">update: </span><span class="nf">(time) -></span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Start if we need to</p></div></div><div class="code"><div class="wrapper"> <span class="nv">elapsed = </span><span class="nx">time</span> <span class="o">-</span> <span class="nx">@startTime</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">@_elapsed</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">return</span> <span class="c1"># Haven't started yet</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">@_elapsed</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span>
<span class="nx">@_start</span><span class="p">()</span> <span class="c1"># Forwards over start point</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">@_elapsed</span> <span class="o">>=</span> <span class="nx">@duration</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">>=</span> <span class="nx">@duration</span><span class="p">)</span>
<span class="k">return</span> <span class="c1"># Already completed</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span>
<span class="nv">elapsed = </span><span class="mi">0</span> <span class="c1"># Clamp elapsed at start time</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">></span> <span class="nx">@duration</span><span class="p">)</span>
<span class="nv">elapsed = </span><span class="nx">@duration</span> <span class="c1"># Clamp elapsed at end time</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Update the children</p></div></div><div class="code"><div class="wrapper"> <span class="nv">tasks = </span><span class="k">if</span> <span class="nx">elapsed</span> <span class="o">>=</span> <span class="nx">@_elapsed</span> <span class="k">then</span> <span class="nx">@_tasks</span> <span class="k">else</span> <span class="nx">@_reverseTasks</span>
<span class="nv">eased = </span><span class="p">(</span><span class="nx">@_easing</span> <span class="nx">elapsed</span> <span class="o">/</span> <span class="nx">@duration</span><span class="p">)</span> <span class="o">*</span> <span class="nx">@duration</span> <span class="o">*</span> <span class="nx">@_rate</span>
<span class="k">for</span> <span class="nx">task</span> <span class="k">in</span> <span class="nx">@_tasks</span>
<span class="nx">task</span><span class="p">.</span><span class="nx">update</span> <span class="nx">eased</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">elapsed</span> <span class="o">>=</span> <span class="nx">@duration</span><span class="p">)</span>
<span class="nx">@_complete</span><span class="p">()</span>
<span class="vi">@_elapsed = </span><span class="nx">elapsed</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Start calcuates duration and sets up everything</p></div></div><div class="code"><div class="wrapper"> <span class="nv">_start: </span><span class="o">-></span>
<span class="nx">@_started</span><span class="o">?</span><span class="p">()</span>
<span class="nv">_complete: </span><span class="o">-></span>
<span class="nx">@_completed</span><span class="o">?</span><span class="p">()</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="transactionbuilder">TransactionBuilder</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="nv">_default = </span><span class="nf">(a = b, b) -></span>
<span class="nx">a</span>
<span class="k">class</span> <span class="nx">TransactionBuilder</span>
<span class="nv">constructor: </span><span class="nf">(fields = {}) -></span>
<span class="vi">@rate = </span><span class="nx">_default</span> <span class="nx">fields</span><span class="p">.</span><span class="nx">rate</span><span class="p">,</span> <span class="mi">1</span>
<span class="vi">@started = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">started</span> <span class="o">||</span> <span class="o">-></span>
<span class="vi">@completed = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">completed</span> <span class="o">||</span> <span class="o">-></span>
<span class="vi">@serial = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">serial</span> <span class="o">||</span> <span class="kc">false</span>
<span class="vi">@easing = </span><span class="nx">fields</span><span class="p">.</span><span class="nx">easing</span> <span class="o">||</span> <span class="nx">EaseLinear</span>
<span class="vi">@_tasks = </span><span class="p">[]</span>
<span class="nv">addTask: </span><span class="nf">(task) -></span>
<span class="nx">@_tasks</span><span class="p">.</span><span class="nx">push</span> <span class="nx">task</span>
<span class="nv">transaction: </span><span class="o">-></span>
<span class="k">if</span> <span class="nx">@serial</span>
<span class="nv">t = </span><span class="mi">0</span>
<span class="k">for</span> <span class="nx">task</span> <span class="k">in</span> <span class="nx">@_tasks</span>
<span class="nv">task.startTime = </span><span class="nx">t</span>
<span class="nx">t</span> <span class="o">+=</span> <span class="nx">task</span><span class="p">.</span><span class="nx">duration</span>
<span class="k">new</span> <span class="nx">Transaction</span>
<span class="nv">rate: </span><span class="nx">@rate</span>
<span class="nv">started: </span><span class="nx">@started</span>
<span class="nv">completed: </span><span class="nx">@completed</span>
<span class="nv">serial: </span><span class="nx">@serial</span>
<span class="nv">easing: </span><span class="nx">@easing</span>
<span class="nv">tasks: </span><span class="nx">@_tasks</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><h2 id="scheduler">Scheduler</h2>
<p>Transactions are added to the scheduler