Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: experimental/docs/animationCommon.js

Issue 1342523002: json based animation toy (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: wip whats next? Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | experimental/docs/backend.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 var animationState = {};
2 animationState.reset = function (engine) {
3 if ('string' === typeof engine) {
4 this.defaultEngine = engine;
5 }
6 this.defaults = {};
7 this.displayList = [];
8 this.displayDict = {};
9 this.start = null;
10 this.time = 0;
11 this.timeline = [];
12 this.timelineIndex = 0;
13 this.requestID = null;
14 this.paused = false;
15 this.displayEngine = 'undefined' === typeof engine ? this.defaultEngine : en gine;
16 }
17
18 function addActions(frame, timeline) {
19 var keyframe = keyframes[frame];
20 var len = keyframe.length;
21 for (var i = 0; i < len; ++i) {
22 var action = keyframe[i];
23 loopOver(action, timeline);
24 }
25 }
26
27 function animateList(now) {
28 if (animationState.paused) {
29 return;
30 }
31 if (animationState.start == null) {
32 animationState.start = now - animationState.time;
33 }
34 animationState.time = now - animationState.start;
35 var stillAnimating = false;
36 for (var index = animationState.timelineIndex; index < animationState.timeli ne.length; ++index) {
37 var animation = animationState.timeline[index];
38 if (animation.time > animationState.time) {
39 stillAnimating = true;
40 break;
41 }
42 if (animation.time + animation.duration < animationState.time) {
43 if (animation.finalized) {
44 continue;
45 }
46 animation.finalized = true;
47 }
48 stillAnimating = true;
49 var actions = animation.actions;
50 for (var aIndex = 0; aIndex < actions.length; ++aIndex) {
51 var action = actions[aIndex];
52 var hasDraw = 'draw' in action;
53 var hasRef = 'ref' in action;
54 var displayIndex;
55 if (hasDraw) {
56 var ref = hasRef ? action.ref : "anonymous_" + index + "_" + aIn dex;
57 assert('string' == typeof(ref));
58 if (ref in animationState.displayDict) {
59 displayIndex = animationState.displayDict[ref];
60 } else {
61 assert('string' == typeof(action.draw));
62 var draw = (new Function("return " + action.draw))();
63 assert('object' == typeof(draw));
64 var paint;
65 if ('paint' in action) {
66 assert('string' == typeof(action.paint));
67 paint = (new Function("return " + action.paint))();
68 assert('object' == typeof(paint) && !isArray(paint));
69 } else {
70 paint = animationState.defaults.paint;
71 }
72 displayIndex = animationState.displayList.length;
73 animationState.displayList.push( { "ref":ref, "draw":draw, " paint":paint,
74 "drawSpec":action.draw, "paintSpec":action.paint,
75 "drawCopied":false, "paintCopied":false,
76 "drawDirty":true, "paintDirty":true, "once":false } );
77 animationState.displayDict[ref] = displayIndex;
78 }
79 } else if (hasRef) {
80 assert('string' == typeof(action.ref));
81 displayIndex = animationState.displayDict[action.ref];
82 } else {
83 assert(actions.length == 1);
84 for (var prop in action) {
85 if ('paint' == prop) {
86 assert('string' == typeof(action[prop]));
87 var obj = (new Function("return " + action[prop]))();
88 assert('object' == typeof(obj) && !isArray(obj));
89 animationState.defaults[prop] = obj;
90 } else {
91 animationState.defaults[prop] = action[prop];
92 }
93 }
94 continue;
95 }
96 var targetSpec = 'target' in action ? action.target : animationState .defaults.target;
97 assert(targetSpec);
98 assert('string' == typeof(targetSpec));
99 assert(displayIndex < animationState.displayList.length);
100 var display = animationState.displayList[displayIndex];
101 var modDraw = targetSpec.startsWith('draw');
102 assert(modDraw || targetSpec.startsWith('paint'));
103 var modType = modDraw ? "draw" : "paint";
104 var copied = modDraw ? display.drawCopied : action.paintCopied;
105 if (!copied) {
106 var copy;
107 if (!modDraw || display.drawSpec.startsWith("text")) {
108 copy = {};
109 var original = modDraw ? display.draw : display.paint;
110 for (var p in original) {
111 copy[p] = original[p];
112 }
113 } else if (display.drawSpec.startsWith("paths")) {
114 copy = [];
115 for (var i = 0; i < display.draw.length; ++i) {
116 var curves = display.draw[i];
117 var curve = Object.keys(curves)[0];
118 copy[i] = {};
119 copy[i][curve] = curves[curve].slice(0); // clone the a rray of curves
120 }
121 } else {
122 assert(display.drawSpec.startsWith("pictures"));
123 copy = [];
124 for (var i = 0; i < display.draw.length; ++i) {
125 var entry = display.draw[i];
126 copy[i] = { "draw":entry.draw, "paint":entry.paint };
127 }
128 }
129 display[modType] = copy;
130 display[modType + "Copied"] = true;
131 }
132 var targetField, targetObject, fieldOffset;
133 if (targetSpec.endsWith("]")) {
134 fieldOffset = targetSpec.lastIndexOf("[");
135 assert(fieldOffset >= 0);
136 targetField = targetSpec.substring(fieldOffset + 1, targetSpec.l ength - 1);
137 var arrayIndex = +targetField;
138 if (!isNaN(arrayIndex) && targetField.length > 0) {
139 targetField = arrayIndex;
140 }
141
142 } else {
143 fieldOffset = targetSpec.lastIndexOf(".");
144 if (fieldOffset >= 0) {
145 targetField = targetSpec.substring(fieldOffset + 1, targetSp ec.length);
146 } else {
147 targetObject = display;
148 targetField = targetSpec;
149 }
150 }
151 if (fieldOffset >= 0) {
152 var sub = targetSpec.substring(0, fieldOffset);
153 targetObject = (new Function('display', "return display." + sub) )(display);
154 }
155 assert(null != targetObject[targetField]);
156 if (!('start' in action) || action.start < animation.time) {
157 for (var p in animationState.defaults) {
158 if ('draw' == p || 'paint' == p || 'ref' == p) {
159 continue;
160 }
161 assert('range' == p || 'target' == p || 'formula' == p || 'p arams' == p);
162 if (!(p in action)) {
163 action[p] = animationState.defaults[p];
164 }
165 }
166 if ('number' == typeof(action.formula)) {
167 targetObject[targetField] = action.formula;
168 action.once = true;
169 }
170 action.start = animation.time;
171 }
172 if (action.once) {
173 continue;
174 }
175 var value = Math.min(1, (animationState.time - animation.time) / ani mation.duration);
176 var scaled = action.range[0] + (action.range[1] - action.range[0]) * value;
177 if ('params' in action) {
178 if (!('func' in action)) {
179 if (isArray(action.params)) {
180 action.funcParams = [];
181 var len = action.params.length;
182 for (var i = 0; i < len; ++i) {
183 action.funcParams[i] = 'target' == action.params[i]
184 ? targetObject[targetField]
185 : (new Function("return " + action.params[i]))() ;
186 }
187 } else {
188 action.funcParams = 'target' == action.params
189 ? targetObject[targetField]
190 : (new Function("return " + action.params))();
191 }
192 assert('formula' in action && 'string' == typeof(action.form ula));
193 // evaluate inline function to get value
194 action.func = new Function('value', 'params', "return " + ac tion.formula);
195 }
196 scaled = action.func(scaled, action.funcParams);
197 }
198 if (targetObject[targetField] != scaled) {
199 if (modDraw) {
200 display.drawDirty = true;
201 } else {
202 display.paintDirty = true;
203 }
204 targetObject[targetField] = scaled;
205 }
206 }
207 }
208 displayBackend(animationState.displayEngine, animationState.displayList);
209
210 if (stillAnimating) {
211 animationState.requestID = requestAnimationFrame(animateList);
212 }
213 }
214
215 function flattenPaint(paint) {
216 if (!paint.paint) {
217 return;
218 }
219 var parent = paints[paint.paint];
220 flattenPaint(parent);
221 for (var prop in parent) {
222 if (!(prop in paint)) {
223 paint[prop] = parent[prop];
224 }
225 }
226 paint.paint = null;
227 }
228
229 function init(engine, keyframe) {
230 animationState.reset(engine);
231 setupPaint();
232 setupBackend(animationState.displayEngine);
233 keyframeInit(keyframe);
234 }
235
236 function keyframeInit(frame) {
237 animationState.reset();
238 addActions("_default", animationState.timeline);
239 addActions(frame, animationState.timeline);
240 for (var index = 0; index < animationState.timeline.length; ++index) {
241 animationState.timeline[index].position = index;
242 }
243 animationState.timeline.sort(function(a, b) {
244 if (a.time == b.time) {
245 return a.position - b.position;
246 }
247 return a.time - b.time;
248 });
249 keyframeBackendInit(animationState.displayEngine, animationState.displayList ,
250 keyframes[frame][0]);
251 animationState.requestID = requestAnimationFrame(animateList);
252 }
253
254 function loopAddProp(action, propName) {
255 var funcStr = "";
256 var prop = action[propName];
257 if ('draw' != propName && isArray(prop)) {
258 funcStr += '[';
259 for (var index = 0; index < prop.length; ++index) {
260 funcStr += loopAddProp(prop, index);
261 if (index + 1 < prop.length) {
262 funcStr += ", ";
263 }
264 }
265 funcStr += ']';
266 return funcStr;
267 }
268 assert("object" != typeof(prop));
269 var useString = "string" == typeof(prop) && isAlpha(prop.charCodeAt(0));
270 if (useString) {
271 funcStr += "'";
272 }
273 funcStr += prop;
274 if (useString) {
275 funcStr += "'";
276 }
277 return funcStr;
278 }
279
280 function loopOver(rec, timeline) {
281 var funcStr = "";
282 if (rec.for) {
283 funcStr += "for (" + rec.for[0] + "; " + rec.for[1] + "; " + rec.for[2] + ") {\n";
284 }
285 funcStr += " var time = " + ('time' in rec ? rec.time : 0) + ";\n";
286 funcStr += " var duration = " + ('duration' in rec ? rec.duration : 0) + ";\n";
287 funcStr += " var actions = [];\n";
288 var len = rec.actions.length;
289 for (var i = 0; i < len; ++i) {
290 funcStr += " var action" + i + " = {\n";
291 var action = rec.actions[i];
292 for (var p in action) {
293 funcStr += " '" + p + "':";
294 funcStr += loopAddProp(action, p);
295 funcStr += ",\n";
296 }
297 funcStr = funcStr.substring(0, funcStr.length - 2);
298 funcStr += "\n };\n";
299 funcStr += " actions.push(action" + i + ");\n";
300 }
301 funcStr += " timeline.push( { 'time':time, 'duration':duration, 'actions' :actions,"
302 + "'finalized':false } );\n";
303 if (rec.for) {
304 funcStr += "}\n";
305 }
306 var func = new Function('rec', 'timeline', funcStr);
307 func(rec, timeline);
308 }
309
310 function setupPaint() {
311 for (var prop in paints) {
312 flattenPaint(paints[prop]);
313 }
314 }
OLDNEW
« no previous file with comments | « no previous file | experimental/docs/backend.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698