13257c12220c411cc9db564e6bf02baba4c1bc061caryclarkvar animationState = {}; 23257c12220c411cc9db564e6bf02baba4c1bc061caryclarkanimationState.reset = function (engine) { 33257c12220c411cc9db564e6bf02baba4c1bc061caryclark if ('string' === typeof engine) { 43257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.defaultEngine = engine; 53257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 63257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.defaults = {}; 73257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.displayList = []; 83257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.displayDict = {}; 93257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.start = null; 103257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.time = 0; 113257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.timeline = []; 123257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.timelineIndex = 0; 133257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.requestID = null; 143257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.paused = false; 153257c12220c411cc9db564e6bf02baba4c1bc061caryclark this.displayEngine = 'undefined' === typeof engine ? this.defaultEngine : engine; 163257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 173257c12220c411cc9db564e6bf02baba4c1bc061caryclark 183257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction addActions(frame, timeline) { 193257c12220c411cc9db564e6bf02baba4c1bc061caryclark var keyframe = keyframes[frame]; 203257c12220c411cc9db564e6bf02baba4c1bc061caryclark var len = keyframe.length; 213257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var i = 0; i < len; ++i) { 223257c12220c411cc9db564e6bf02baba4c1bc061caryclark var action = keyframe[i]; 233257c12220c411cc9db564e6bf02baba4c1bc061caryclark loopOver(action, timeline); 243257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 253257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 263257c12220c411cc9db564e6bf02baba4c1bc061caryclark 273257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction animateList(now) { 283257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (animationState.paused) { 293257c12220c411cc9db564e6bf02baba4c1bc061caryclark return; 303257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 313257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (animationState.start == null) { 323257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.start = now - animationState.time; 333257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 343257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.time = now - animationState.start; 353257c12220c411cc9db564e6bf02baba4c1bc061caryclark var stillAnimating = false; 363257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var index = animationState.timelineIndex; index < animationState.timeline.length; ++index) { 373257c12220c411cc9db564e6bf02baba4c1bc061caryclark var animation = animationState.timeline[index]; 383257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (animation.time > animationState.time) { 393257c12220c411cc9db564e6bf02baba4c1bc061caryclark stillAnimating = true; 403257c12220c411cc9db564e6bf02baba4c1bc061caryclark break; 413257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 423257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (animation.time + animation.duration < animationState.time) { 433257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (animation.finalized) { 443257c12220c411cc9db564e6bf02baba4c1bc061caryclark continue; 453257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 463257c12220c411cc9db564e6bf02baba4c1bc061caryclark animation.finalized = true; 473257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 483257c12220c411cc9db564e6bf02baba4c1bc061caryclark stillAnimating = true; 493257c12220c411cc9db564e6bf02baba4c1bc061caryclark var actions = animation.actions; 503257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var aIndex = 0; aIndex < actions.length; ++aIndex) { 513257c12220c411cc9db564e6bf02baba4c1bc061caryclark var action = actions[aIndex]; 523257c12220c411cc9db564e6bf02baba4c1bc061caryclark var hasDraw = 'draw' in action; 533257c12220c411cc9db564e6bf02baba4c1bc061caryclark var hasRef = 'ref' in action; 543257c12220c411cc9db564e6bf02baba4c1bc061caryclark var displayIndex; 553257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (hasDraw) { 563257c12220c411cc9db564e6bf02baba4c1bc061caryclark var ref = hasRef ? action.ref : "anonymous_" + index + "_" + aIndex; 573257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('string' == typeof(ref)); 583257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (ref in animationState.displayDict) { 593257c12220c411cc9db564e6bf02baba4c1bc061caryclark displayIndex = animationState.displayDict[ref]; 603257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 613257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('string' == typeof(action.draw)); 623257c12220c411cc9db564e6bf02baba4c1bc061caryclark var draw = (new Function("return " + action.draw))(); 633257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('object' == typeof(draw)); 643257c12220c411cc9db564e6bf02baba4c1bc061caryclark var paint; 653257c12220c411cc9db564e6bf02baba4c1bc061caryclark if ('paint' in action) { 663257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('string' == typeof(action.paint)); 673257c12220c411cc9db564e6bf02baba4c1bc061caryclark paint = (new Function("return " + action.paint))(); 683257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('object' == typeof(paint) && !isArray(paint)); 693257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 703257c12220c411cc9db564e6bf02baba4c1bc061caryclark paint = animationState.defaults.paint; 713257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 723257c12220c411cc9db564e6bf02baba4c1bc061caryclark displayIndex = animationState.displayList.length; 733257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.displayList.push( { "ref":ref, "draw":draw, "paint":paint, 743257c12220c411cc9db564e6bf02baba4c1bc061caryclark "drawSpec":action.draw, "paintSpec":action.paint, 753257c12220c411cc9db564e6bf02baba4c1bc061caryclark "drawCopied":false, "paintCopied":false, 763257c12220c411cc9db564e6bf02baba4c1bc061caryclark "drawDirty":true, "paintDirty":true, "once":false } ); 773257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.displayDict[ref] = displayIndex; 783257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 793257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else if (hasRef) { 803257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('string' == typeof(action.ref)); 813257c12220c411cc9db564e6bf02baba4c1bc061caryclark displayIndex = animationState.displayDict[action.ref]; 823257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 833257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert(actions.length == 1); 843257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var prop in action) { 853257c12220c411cc9db564e6bf02baba4c1bc061caryclark if ('paint' == prop) { 863257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('string' == typeof(action[prop])); 873257c12220c411cc9db564e6bf02baba4c1bc061caryclark var obj = (new Function("return " + action[prop]))(); 883257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('object' == typeof(obj) && !isArray(obj)); 893257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.defaults[prop] = obj; 903257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 913257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.defaults[prop] = action[prop]; 923257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 933257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 943257c12220c411cc9db564e6bf02baba4c1bc061caryclark continue; 953257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 963257c12220c411cc9db564e6bf02baba4c1bc061caryclark var targetSpec = 'target' in action ? action.target : animationState.defaults.target; 973257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert(targetSpec); 983257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('string' == typeof(targetSpec)); 993257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert(displayIndex < animationState.displayList.length); 1003257c12220c411cc9db564e6bf02baba4c1bc061caryclark var display = animationState.displayList[displayIndex]; 1013257c12220c411cc9db564e6bf02baba4c1bc061caryclark var modDraw = targetSpec.startsWith('draw'); 1023257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert(modDraw || targetSpec.startsWith('paint')); 1033257c12220c411cc9db564e6bf02baba4c1bc061caryclark var modType = modDraw ? "draw" : "paint"; 1043257c12220c411cc9db564e6bf02baba4c1bc061caryclark var copied = modDraw ? display.drawCopied : action.paintCopied; 1053257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!copied) { 1063257c12220c411cc9db564e6bf02baba4c1bc061caryclark var copy; 1073257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!modDraw || display.drawSpec.startsWith("text")) { 1083257c12220c411cc9db564e6bf02baba4c1bc061caryclark copy = {}; 1093257c12220c411cc9db564e6bf02baba4c1bc061caryclark var original = modDraw ? display.draw : display.paint; 1103257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var p in original) { 1113257c12220c411cc9db564e6bf02baba4c1bc061caryclark copy[p] = original[p]; 1123257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1133257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else if (display.drawSpec.startsWith("paths")) { 1143257c12220c411cc9db564e6bf02baba4c1bc061caryclark copy = []; 1153257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var i = 0; i < display.draw.length; ++i) { 1163257c12220c411cc9db564e6bf02baba4c1bc061caryclark var curves = display.draw[i]; 1173257c12220c411cc9db564e6bf02baba4c1bc061caryclark var curve = Object.keys(curves)[0]; 1183257c12220c411cc9db564e6bf02baba4c1bc061caryclark copy[i] = {}; 1193257c12220c411cc9db564e6bf02baba4c1bc061caryclark copy[i][curve] = curves[curve].slice(0); // clone the array of curves 1203257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1213257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 1223257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert(display.drawSpec.startsWith("pictures")); 1233257c12220c411cc9db564e6bf02baba4c1bc061caryclark copy = []; 1243257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var i = 0; i < display.draw.length; ++i) { 1253257c12220c411cc9db564e6bf02baba4c1bc061caryclark var entry = display.draw[i]; 1263257c12220c411cc9db564e6bf02baba4c1bc061caryclark copy[i] = { "draw":entry.draw, "paint":entry.paint }; 1273257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1283257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1293257c12220c411cc9db564e6bf02baba4c1bc061caryclark display[modType] = copy; 1303257c12220c411cc9db564e6bf02baba4c1bc061caryclark display[modType + "Copied"] = true; 1313257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1323257c12220c411cc9db564e6bf02baba4c1bc061caryclark var targetField, targetObject, fieldOffset; 1333257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (targetSpec.endsWith("]")) { 1343257c12220c411cc9db564e6bf02baba4c1bc061caryclark fieldOffset = targetSpec.lastIndexOf("["); 1353257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert(fieldOffset >= 0); 1363257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetField = targetSpec.substring(fieldOffset + 1, targetSpec.length - 1); 1373257c12220c411cc9db564e6bf02baba4c1bc061caryclark var arrayIndex = +targetField; 1383257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!isNaN(arrayIndex) && targetField.length > 0) { 1393257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetField = arrayIndex; 1403257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1413257c12220c411cc9db564e6bf02baba4c1bc061caryclark 1423257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 1433257c12220c411cc9db564e6bf02baba4c1bc061caryclark fieldOffset = targetSpec.lastIndexOf("."); 1443257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (fieldOffset >= 0) { 1453257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetField = targetSpec.substring(fieldOffset + 1, targetSpec.length); 1463257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 1473257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetObject = display; 1483257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetField = targetSpec; 1493257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1503257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1513257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (fieldOffset >= 0) { 1523257c12220c411cc9db564e6bf02baba4c1bc061caryclark var sub = targetSpec.substring(0, fieldOffset); 1533257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetObject = (new Function('display', "return display." + sub))(display); 1543257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1553257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert(null != targetObject[targetField]); 1563257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!('start' in action) || action.start < animation.time) { 1573257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var p in animationState.defaults) { 1583257c12220c411cc9db564e6bf02baba4c1bc061caryclark if ('draw' == p || 'paint' == p || 'ref' == p) { 1593257c12220c411cc9db564e6bf02baba4c1bc061caryclark continue; 1603257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1613257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('range' == p || 'target' == p || 'formula' == p || 'params' == p); 1623257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!(p in action)) { 1633257c12220c411cc9db564e6bf02baba4c1bc061caryclark action[p] = animationState.defaults[p]; 1643257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1653257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1663257c12220c411cc9db564e6bf02baba4c1bc061caryclark if ('number' == typeof(action.formula)) { 1673257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetObject[targetField] = action.formula; 1683257c12220c411cc9db564e6bf02baba4c1bc061caryclark action.once = true; 1693257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1703257c12220c411cc9db564e6bf02baba4c1bc061caryclark action.start = animation.time; 1713257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1723257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (action.once) { 1733257c12220c411cc9db564e6bf02baba4c1bc061caryclark continue; 1743257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1753257c12220c411cc9db564e6bf02baba4c1bc061caryclark var value = Math.min(1, (animationState.time - animation.time) / animation.duration); 1763257c12220c411cc9db564e6bf02baba4c1bc061caryclark var scaled = action.range[0] + (action.range[1] - action.range[0]) * value; 1773257c12220c411cc9db564e6bf02baba4c1bc061caryclark if ('params' in action) { 1783257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!('func' in action)) { 1793257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (isArray(action.params)) { 1803257c12220c411cc9db564e6bf02baba4c1bc061caryclark action.funcParams = []; 1813257c12220c411cc9db564e6bf02baba4c1bc061caryclark var len = action.params.length; 1823257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var i = 0; i < len; ++i) { 1833257c12220c411cc9db564e6bf02baba4c1bc061caryclark action.funcParams[i] = 'target' == action.params[i] 1843257c12220c411cc9db564e6bf02baba4c1bc061caryclark ? targetObject[targetField] 1853257c12220c411cc9db564e6bf02baba4c1bc061caryclark : (new Function("return " + action.params[i]))(); 1863257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1873257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 1883257c12220c411cc9db564e6bf02baba4c1bc061caryclark action.funcParams = 'target' == action.params 1893257c12220c411cc9db564e6bf02baba4c1bc061caryclark ? targetObject[targetField] 1903257c12220c411cc9db564e6bf02baba4c1bc061caryclark : (new Function("return " + action.params))(); 1913257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1923257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert('formula' in action && 'string' == typeof(action.formula)); 1933257c12220c411cc9db564e6bf02baba4c1bc061caryclark // evaluate inline function to get value 1943257c12220c411cc9db564e6bf02baba4c1bc061caryclark action.func = new Function('value', 'params', "return " + action.formula); 1953257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1963257c12220c411cc9db564e6bf02baba4c1bc061caryclark scaled = action.func(scaled, action.funcParams); 1973257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 1983257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (targetObject[targetField] != scaled) { 1993257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (modDraw) { 2003257c12220c411cc9db564e6bf02baba4c1bc061caryclark display.drawDirty = true; 2013257c12220c411cc9db564e6bf02baba4c1bc061caryclark } else { 2023257c12220c411cc9db564e6bf02baba4c1bc061caryclark display.paintDirty = true; 2033257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2043257c12220c411cc9db564e6bf02baba4c1bc061caryclark targetObject[targetField] = scaled; 2053257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2063257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2073257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2083257c12220c411cc9db564e6bf02baba4c1bc061caryclark displayBackend(animationState.displayEngine, animationState.displayList); 2093257c12220c411cc9db564e6bf02baba4c1bc061caryclark 2103257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (stillAnimating) { 2113257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.requestID = requestAnimationFrame(animateList); 2123257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2133257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 2143257c12220c411cc9db564e6bf02baba4c1bc061caryclark 2153257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction flattenPaint(paint) { 2163257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!paint.paint) { 2173257c12220c411cc9db564e6bf02baba4c1bc061caryclark return; 2183257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2193257c12220c411cc9db564e6bf02baba4c1bc061caryclark var parent = paints[paint.paint]; 2203257c12220c411cc9db564e6bf02baba4c1bc061caryclark flattenPaint(parent); 2213257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var prop in parent) { 2223257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (!(prop in paint)) { 2233257c12220c411cc9db564e6bf02baba4c1bc061caryclark paint[prop] = parent[prop]; 2243257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2253257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2263257c12220c411cc9db564e6bf02baba4c1bc061caryclark paint.paint = null; 2273257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 2283257c12220c411cc9db564e6bf02baba4c1bc061caryclark 2293257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction init(engine, keyframe) { 2303257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.reset(engine); 2313257c12220c411cc9db564e6bf02baba4c1bc061caryclark setupPaint(); 2323257c12220c411cc9db564e6bf02baba4c1bc061caryclark setupBackend(animationState.displayEngine); 2333257c12220c411cc9db564e6bf02baba4c1bc061caryclark keyframeInit(keyframe); 2343257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 2353257c12220c411cc9db564e6bf02baba4c1bc061caryclark 2363257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction keyframeInit(frame) { 2373257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.reset(); 2383257c12220c411cc9db564e6bf02baba4c1bc061caryclark addActions("_default", animationState.timeline); 2393257c12220c411cc9db564e6bf02baba4c1bc061caryclark addActions(frame, animationState.timeline); 2403257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var index = 0; index < animationState.timeline.length; ++index) { 2413257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.timeline[index].position = index; 2423257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2433257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.timeline.sort(function(a, b) { 2443257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (a.time == b.time) { 2453257c12220c411cc9db564e6bf02baba4c1bc061caryclark return a.position - b.position; 2463257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2473257c12220c411cc9db564e6bf02baba4c1bc061caryclark return a.time - b.time; 2483257c12220c411cc9db564e6bf02baba4c1bc061caryclark }); 2493257c12220c411cc9db564e6bf02baba4c1bc061caryclark keyframeBackendInit(animationState.displayEngine, animationState.displayList, 2503257c12220c411cc9db564e6bf02baba4c1bc061caryclark keyframes[frame][0]); 2513257c12220c411cc9db564e6bf02baba4c1bc061caryclark animationState.requestID = requestAnimationFrame(animateList); 2523257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 2533257c12220c411cc9db564e6bf02baba4c1bc061caryclark 2543257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction loopAddProp(action, propName) { 2553257c12220c411cc9db564e6bf02baba4c1bc061caryclark var funcStr = ""; 2563257c12220c411cc9db564e6bf02baba4c1bc061caryclark var prop = action[propName]; 2573257c12220c411cc9db564e6bf02baba4c1bc061caryclark if ('draw' != propName && isArray(prop)) { 2583257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += '['; 2593257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var index = 0; index < prop.length; ++index) { 2603257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += loopAddProp(prop, index); 2613257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (index + 1 < prop.length) { 2623257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += ", "; 2633257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2643257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2653257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += ']'; 2663257c12220c411cc9db564e6bf02baba4c1bc061caryclark return funcStr; 2673257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2683257c12220c411cc9db564e6bf02baba4c1bc061caryclark assert("object" != typeof(prop)); 2693257c12220c411cc9db564e6bf02baba4c1bc061caryclark var useString = "string" == typeof(prop) && isAlpha(prop.charCodeAt(0)); 2703257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (useString) { 2713257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += "'"; 2723257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2733257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += prop; 2743257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (useString) { 2753257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += "'"; 2763257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2773257c12220c411cc9db564e6bf02baba4c1bc061caryclark return funcStr; 2783257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 2793257c12220c411cc9db564e6bf02baba4c1bc061caryclark 2803257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction loopOver(rec, timeline) { 2813257c12220c411cc9db564e6bf02baba4c1bc061caryclark var funcStr = ""; 2823257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (rec.for) { 2833257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += "for (" + rec.for[0] + "; " + rec.for[1] + "; " + rec.for[2] + ") {\n"; 2843257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2853257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += " var time = " + ('time' in rec ? rec.time : 0) + ";\n"; 2863257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += " var duration = " + ('duration' in rec ? rec.duration : 0) + ";\n"; 2873257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += " var actions = [];\n"; 2883257c12220c411cc9db564e6bf02baba4c1bc061caryclark var len = rec.actions.length; 2893257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var i = 0; i < len; ++i) { 2903257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += " var action" + i + " = {\n"; 2913257c12220c411cc9db564e6bf02baba4c1bc061caryclark var action = rec.actions[i]; 2923257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var p in action) { 2933257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += " '" + p + "':"; 2943257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += loopAddProp(action, p); 2953257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += ",\n"; 2963257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 2973257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr = funcStr.substring(0, funcStr.length - 2); 2983257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += "\n };\n"; 2993257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += " actions.push(action" + i + ");\n"; 3003257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 3013257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += " timeline.push( { 'time':time, 'duration':duration, 'actions':actions," 3023257c12220c411cc9db564e6bf02baba4c1bc061caryclark + "'finalized':false } );\n"; 3033257c12220c411cc9db564e6bf02baba4c1bc061caryclark if (rec.for) { 3043257c12220c411cc9db564e6bf02baba4c1bc061caryclark funcStr += "}\n"; 3053257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 3063257c12220c411cc9db564e6bf02baba4c1bc061caryclark var func = new Function('rec', 'timeline', funcStr); 3073257c12220c411cc9db564e6bf02baba4c1bc061caryclark func(rec, timeline); 3083257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 3093257c12220c411cc9db564e6bf02baba4c1bc061caryclark 3103257c12220c411cc9db564e6bf02baba4c1bc061caryclarkfunction setupPaint() { 3113257c12220c411cc9db564e6bf02baba4c1bc061caryclark for (var prop in paints) { 3123257c12220c411cc9db564e6bf02baba4c1bc061caryclark flattenPaint(paints[prop]); 3133257c12220c411cc9db564e6bf02baba4c1bc061caryclark } 3143257c12220c411cc9db564e6bf02baba4c1bc061caryclark} 315