bodymovin_parser.jsx 118 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023
  1. var Gtlym = {};var bodymovinWindow = this;
  2. (function(){
  3. /****** INIT JSON PARSER ******/
  4. if (typeof JSON !== 'object') {
  5. JSON = {};
  6. }
  7. (function () {
  8. 'use strict';
  9. function f(n) {
  10. return n < 10 ? '0' + n : n;
  11. }
  12. if (typeof Date.prototype.toJSON !== 'function') {
  13. Date.prototype.toJSON = function () {
  14. return isFinite(this.valueOf())
  15. ? this.getUTCFullYear() + '-' +
  16. f(this.getUTCMonth() + 1) + '-' +
  17. f(this.getUTCDate()) + 'T' +
  18. f(this.getUTCHours()) + ':' +
  19. f(this.getUTCMinutes()) + ':' +
  20. f(this.getUTCSeconds()) + 'Z'
  21. : null;
  22. };
  23. String.prototype.toJSON =
  24. Number.prototype.toJSON =
  25. Boolean.prototype.toJSON = function () {
  26. return this.valueOf();
  27. };
  28. }
  29. var cx,
  30. escapable,
  31. gap,
  32. indent,
  33. meta,
  34. rep;
  35. function quote(string) {
  36. escapable.lastIndex = 0;
  37. return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
  38. var c = meta[a];
  39. return typeof c === 'string'
  40. ? c
  41. : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  42. }) + '"' : '"' + string + '"';
  43. }
  44. function str(key, holder) {
  45. var i,
  46. k,
  47. v,
  48. length,
  49. mind = gap,
  50. partial,
  51. value = holder[key];
  52. if (value && typeof value === 'object' &&
  53. typeof value.toJSON === 'function') {
  54. value = value.toJSON(key);
  55. }
  56. if (typeof rep === 'function') {
  57. value = rep.call(holder, key, value);
  58. }
  59. switch (typeof value) {
  60. case 'string':
  61. return quote(value);
  62. case 'number':
  63. return isFinite(value) ? String(value) : 'null';
  64. case 'boolean':
  65. case 'null':
  66. return String(value);
  67. case 'object':
  68. if (!value) {
  69. return 'null';
  70. }
  71. gap += indent;
  72. partial = [];
  73. if (Object.prototype.toString.apply(value) === '[object Array]') {
  74. length = value.length;
  75. for (i = 0; i < length; i += 1) {
  76. partial[i] = str(i, value) || 'null';
  77. }
  78. v = partial.length === 0
  79. ? '[]'
  80. : gap
  81. ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
  82. : '[' + partial.join(',') + ']';
  83. gap = mind;
  84. return v;
  85. }
  86. if (rep && typeof rep === 'object') {
  87. length = rep.length;
  88. for (i = 0; i < length; i += 1) {
  89. if (typeof rep[i] === 'string') {
  90. k = rep[i];
  91. v = str(k, value);
  92. if (v) {
  93. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  94. }
  95. }
  96. }
  97. } else {
  98. for (k in value) {
  99. if (Object.prototype.hasOwnProperty.call(value, k)) {
  100. v = str(k, value);
  101. if (v) {
  102. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  103. }
  104. }
  105. }
  106. }
  107. v = partial.length === 0
  108. ? '{}'
  109. : gap
  110. ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
  111. : '{' + partial.join(',') + '}';
  112. gap = mind;
  113. return v;
  114. }
  115. }
  116. if (typeof JSON.stringify !== 'function') {
  117. escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  118. meta = {
  119. '\b': '\\b',
  120. '\t': '\\t',
  121. '\n': '\\n',
  122. '\f': '\\f',
  123. '\r': '\\r',
  124. '"' : '\\"',
  125. '\\': '\\\\'
  126. };
  127. JSON.stringify = function (value, replacer, space) {
  128. var i;
  129. gap = '';
  130. indent = '';
  131. if (typeof space === 'number') {
  132. for (i = 0; i < space; i += 1) {
  133. indent += ' ';
  134. }
  135. } else if (typeof space === 'string') {
  136. indent = space;
  137. }
  138. rep = replacer;
  139. if (replacer && typeof replacer !== 'function' &&
  140. (typeof replacer !== 'object' ||
  141. typeof replacer.length !== 'number')) {
  142. throw new Error('JSON.stringify');
  143. }
  144. return str('', {'': value});
  145. };
  146. }
  147. if (typeof JSON.parse !== 'function') {
  148. cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
  149. JSON.parse = function (text, reviver) {
  150. var j;
  151. function walk(holder, key) {
  152. var k, v, value = holder[key];
  153. if (value && typeof value === 'object') {
  154. for (k in value) {
  155. if (Object.prototype.hasOwnProperty.call(value, k)) {
  156. v = walk(value, k);
  157. if (v !== undefined) {
  158. value[k] = v;
  159. } else {
  160. delete value[k];
  161. }
  162. }
  163. }
  164. }
  165. return reviver.call(holder, key, value);
  166. }
  167. text = String(text);
  168. cx.lastIndex = 0;
  169. if (cx.test(text)) {
  170. text = text.replace(cx, function (a) {
  171. return '\\u' +
  172. ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  173. });
  174. }
  175. if (/^[\],:{}\s]*$/
  176. .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
  177. .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
  178. .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
  179. j = eval('(' + text + ')');
  180. return typeof reviver === 'function'
  181. ? walk({'': j}, '')
  182. : j;
  183. }
  184. throw new SyntaxError('JSON.parse');
  185. };
  186. }
  187. }());
  188. /****** END JSON PARSER ******/
  189. /****** INIT ARRAY POLYFILLS ******/
  190. if (!Array.prototype.forEach) {
  191. Array.prototype.forEach = function(callback, thisArg) {
  192. var T, k;
  193. if (this == null) {
  194. throw new TypeError(' this is null or not defined');
  195. }
  196. var O = Object(this);
  197. var len = O.length >>> 0;
  198. if (typeof callback !== "function") {
  199. throw new TypeError(callback + ' is not a function');
  200. }
  201. if (arguments.length > 1) {
  202. T = thisArg;
  203. }
  204. k = 0;
  205. while (k < len) {
  206. var kValue;
  207. if (k in O) {
  208. kValue = O[k];
  209. callback.call(T, kValue, k, O);
  210. }
  211. k++;
  212. }
  213. };
  214. }
  215. if (!Array.prototype.map) {
  216. Array.prototype.map = function(callback, thisArg) {
  217. var T, A, k;
  218. if (this == null) {
  219. throw new TypeError(' this is null or not defined');
  220. }
  221. var O = Object(this);
  222. var len = O.length >>> 0;
  223. if (typeof callback !== 'function') {
  224. throw new TypeError(callback + ' is not a function');
  225. }
  226. if (arguments.length > 1) {
  227. T = thisArg;
  228. }
  229. A = new Array(len);
  230. k = 0;
  231. while (k < len) {
  232. var kValue, mappedValue;
  233. if (k in O) {
  234. kValue = O[k];
  235. mappedValue = callback.call(T, kValue, k, O);
  236. A[k] = mappedValue;
  237. }
  238. k++;
  239. }
  240. return A;
  241. };
  242. }
  243. /****** END ARRAY POLYFILLS ******/
  244. var console = {
  245. log : function(){
  246. $.writeln.call($,arguments);
  247. }
  248. };
  249. /****** INIT Var Declarations ******/
  250. var helperSolidComp;
  251. var helperFootage;
  252. //Solid for anchor point fix on shape layers
  253. var helperSolid;
  254. //Destination export folder
  255. var exportFolder;
  256. //Interval objects container
  257. //var Gtlym = {};
  258. Gtlym.CALL = {};
  259. //Render cancelled flag
  260. var renderCancelled = false;
  261. //modules
  262. var LayerConverter;
  263. var rqManager;
  264. var extrasInstance;
  265. var AsyncManager;
  266. var DOMAnimationManager;
  267. var CompConverter;
  268. var ShapesParser;
  269. var EffectsParser;
  270. var UI;
  271. /****** INIT Assets Manager ******/
  272. (function(){
  273. var ob = {};
  274. var sourceAssets = [];
  275. var sourceExportData = [];
  276. function reset(){
  277. sourceAssets = [];
  278. sourceExportData = [];
  279. }
  280. function associateLayerToSource(layer, source){
  281. var i=0, len = sourceAssets.length;
  282. while(i<len){
  283. if(sourceAssets[i].s === source){
  284. sourceAssets[i].l.push(layer);
  285. break;
  286. }
  287. i+=1;
  288. }
  289. }
  290. function exportFileFromLayer(layer, filesDirectory){
  291. var i = 0, len = sourceAssets.length;
  292. var j, jLen, found = false;
  293. while(i<len){
  294. j = 0;
  295. jLen = sourceAssets[i].l.length;
  296. while(j<jLen){
  297. if(sourceAssets[i].l[j] === layer){
  298. found = true;
  299. if(sourceAssets[i].exported === false){
  300. var imageName = 'imagen_'+i;
  301. var imageExtension = 'png';
  302. var destinationFile = new File(filesDirectory.fullName+'/'+imageName+'.'+imageExtension);
  303. sourceAssets[i].f.copy(destinationFile);
  304. sourceAssets[i].exported = true;
  305. sourceAssets[i].path = 'files/'+imageName+'.'+imageExtension;
  306. }
  307. }
  308. j+=1;
  309. }
  310. if(found === true){
  311. return i;
  312. }
  313. i+=1;
  314. }
  315. }
  316. function createAssetsDataForExport(){
  317. sourceAssets.forEach(function(item){
  318. if(item.exported === true){
  319. sourceExportData.push({path:item.path});
  320. }
  321. })
  322. }
  323. function createLayerSource(file, layer, source){
  324. sourceAssets.push({s:source,f:file,l:[layer], exported:false});
  325. }
  326. function getAssetsData(){
  327. return sourceExportData;
  328. }
  329. ob.getAssetsData = getAssetsData;
  330. ob.reset = reset;
  331. ob.associateLayerToSource = associateLayerToSource;
  332. ob.createLayerSource = createLayerSource;
  333. ob.createAssetsDataForExport = createAssetsDataForExport;
  334. ob.exportFileFromLayer = exportFileFromLayer;
  335. AssetsManager = ob;
  336. }());
  337. /****** END Assets Manager ******/
  338. /**** Async Manager ****/
  339. (function(){
  340. var ob = {};
  341. var asyncCount = 0;
  342. var callback;
  343. var asyncElements = [];
  344. function executeCall(item){
  345. item.call();
  346. }
  347. function executeAsyncCalls(){
  348. var executingElements = asyncElements.splice(0,asyncElements.length);
  349. asyncElements.length = 0;
  350. executingElements.forEach(executeCall);
  351. asyncCount -= 1;
  352. if(asyncCount == 0){
  353. callback.apply();
  354. }
  355. }
  356. function addAsyncCall(fn){
  357. asyncElements.push(fn);
  358. if(asyncElements.length == 1){
  359. asyncCount += 1;
  360. //Todo Create async call
  361. extrasInstance.setTimeout(executeAsyncCalls,1);
  362. }
  363. }
  364. function addAsyncCounter(){
  365. asyncCount += 1;
  366. }
  367. function removeAsyncCounter(){
  368. asyncCount -= 1;
  369. if(asyncCount == 0){
  370. callback.apply();
  371. }
  372. }
  373. function getAsyncCounter(){
  374. return asyncCount;
  375. }
  376. function setCallBack(cb){
  377. callback = cb;
  378. }
  379. ob.addAsyncCall = addAsyncCall;
  380. ob.addAsyncCount = addAsyncCounter;
  381. ob.removeAsyncCounter = removeAsyncCounter;
  382. ob.getAsyncCounter = getAsyncCounter;
  383. ob.setCallBack = setCallBack;
  384. AsyncManager = ob;
  385. }());
  386. /**** END Async Manager ****/
  387. /****** INIT DOMAnimationMAnager ******/
  388. (function(){
  389. var frameRate = 0;
  390. var totalFrames = 0;
  391. var firstFrame = 0;
  392. var currentRenderFrame = 0;
  393. var currentTime = 0;
  394. var imageCount = 0;
  395. var zCount = 0;
  396. var isRenderReady = false;
  397. var mainComp;
  398. var mainLayers = [];
  399. var filesDirectory;
  400. var callback;
  401. var pendingLayers = [];
  402. var totalLayers = 0;
  403. var exportedComps = [];
  404. function getCompositionAnimationData(compo, compositionData,fDirectory){
  405. exportedComps = [];
  406. mainComp = compo;
  407. frameRate = mainComp.frameRate;
  408. currentRenderFrame = 0;
  409. imageCount = 0;
  410. zCount = 0;
  411. mainLayers = [];
  412. totalFrames = mainComp.workAreaDuration*mainComp.frameRate;
  413. firstFrame = mainComp.workAreaStart*mainComp.frameRate;
  414. //totalFrames = 1;
  415. var animationOb = {};
  416. compositionData.animation = animationOb;
  417. compositionData.assets = AssetsManager.getAssetsData();
  418. compositionData.v = '2.0.6';
  419. animationOb.layers = mainLayers;
  420. animationOb.totalFrames = totalFrames;
  421. animationOb.frameRate = frameRate;
  422. animationOb.ff = mainComp.workAreaStart;
  423. animationOb.compWidth = mainComp.width;
  424. animationOb.compHeight = mainComp.height;
  425. filesDirectory = fDirectory;
  426. iterateComposition();
  427. }
  428. function getMaskMode (num){
  429. switch(num){
  430. case MaskMode.NONE:
  431. return 'n';
  432. case MaskMode.ADD:
  433. return 'a';
  434. case MaskMode.SUBTRACT:
  435. return 's';
  436. case MaskMode.INTERSECT:
  437. return 'i';
  438. case MaskMode.LIGHTEN:
  439. return 'l';
  440. case MaskMode.DARKEN:
  441. return 'd';
  442. case MaskMode.DIFFERENCE:
  443. return 'f';
  444. }
  445. }
  446. function addMasksToLayer(layerInfo,layerOb,time){
  447. layerOb.mk = [];
  448. var i, len = layerInfo.mask.numProperties, maskShape, maskElement;
  449. for(i=0;i<len;i++){
  450. maskElement = layerInfo.mask(i+1);
  451. maskShape = layerInfo.mask(i+1).property('maskShape').valueAtTime(time,false);
  452. layerOb.mk.push({v:extrasInstance.roundNumber(maskShape.vertices,3), i:extrasInstance.roundNumber(maskShape.inTangents,3), o:extrasInstance.roundNumber(maskShape.outTangents,3), t:extrasInstance.roundNumber(maskElement.property('Mask Opacity').valueAtTime(time,false)/100,3)});
  453. }
  454. }
  455. function setMasks(masks,layerOb){
  456. layerOb.masksProperties = [];
  457. var i, len = masks.numProperties, maskShape, maskElement;
  458. for(i=0;i<len;i++){
  459. maskElement = masks(i+1);
  460. maskShape = maskElement.property('maskShape').value;
  461. var shapeData = {
  462. cl:maskShape.closed,
  463. inv:maskElement.inverted,
  464. mode:getMaskMode(maskElement.maskMode)
  465. };
  466. extrasInstance.convertToBezierValues(maskElement.property('maskShape'), frameRate, shapeData,'pt');
  467. extrasInstance.convertToBezierValues(maskElement.property('Mask Opacity'), frameRate, shapeData,'o');
  468. layerOb.masksProperties.push(shapeData);
  469. }
  470. }
  471. function addStillAsset(layerOb,layerInfo){
  472. layerOb.assetId = AssetsManager.exportFileFromLayer(layerInfo,filesDirectory);
  473. }
  474. function removeExtraData(layersData){
  475. var i, len = layersData.length,j, jLen, shapes;
  476. for(i = 0;i<len;i++){
  477. var layerOb = layersData[i];
  478. if(layerOb.enabled == false){
  479. layersData.splice(i,1);
  480. i -= 1;
  481. len -= 1;
  482. continue;
  483. }
  484. layerOb.lastData = null ;
  485. delete layerOb.lastData;
  486. if(layerOb.type == 'ShapeLayer'){
  487. shapes = layerOb.shapes;
  488. jLen = shapes.length;
  489. for(j=0;j<jLen;j++){
  490. shapes[j].lastData = null;
  491. delete shapes[j].lastData;
  492. }
  493. }
  494. if(layerOb.type == 'PreCompLayer' && layerOb.layers){
  495. removeExtraData(layerOb.layers);
  496. }
  497. EffectsParser.saveEffectData(layerOb);
  498. }
  499. }
  500. function processFinalData(layersData){
  501. var i, len = layersData.length;
  502. for(i = 0;i<len;i++){
  503. var layerOb = layersData[i];
  504. if(layerOb.type == 'ShapeLayer'){
  505. layerOb.rectData.w = extrasInstance.roundNumber(layerOb.rectData.r - layerOb.rectData.l,3);
  506. layerOb.rectData.h = extrasInstance.roundNumber(layerOb.rectData.b - layerOb.rectData.t,3);
  507. }
  508. if(layerOb.type == 'PreCompLayer' && layerOb.layers){
  509. processFinalData(layerOb.layers);
  510. }
  511. }
  512. }
  513. function buildTextData(textDocument){
  514. var textDataOb = {};
  515. textDataOb.font = textDocument.font;
  516. textDataOb.fontSize = textDocument.fontSize;
  517. textDataOb.fillColor = extrasInstance.arrayRgbToHex(textDocument.fillColor);
  518. textDataOb.text = textDocument.text;
  519. var justification = '';
  520. switch(textDocument.justification){
  521. case ParagraphJustification.LEFT_JUSTIFY:
  522. justification = 'left';
  523. break;
  524. case ParagraphJustification.RIGHT_JUSTIFY:
  525. justification = 'right';
  526. break;
  527. case ParagraphJustification.CENTER_JUSTIFY:
  528. justification = 'center';
  529. break;
  530. case ParagraphJustification.FULL_JUSTIFY_LASTLINE_LEFT:
  531. case ParagraphJustification.FULL_JUSTIFY_LASTLINE_RIGHT:
  532. case ParagraphJustification.FULL_JUSTIFY_LASTLINE_CENTER:
  533. case ParagraphJustification.FULL_JUSTIFY_LASTLINE_FULL:
  534. justification = 'justify';
  535. break;
  536. default:
  537. justification = 'left';
  538. break;
  539. }
  540. textDataOb.justification = justification;
  541. return textDataOb;
  542. }
  543. function analyzeNextLayer(){
  544. if(pendingLayers.length == 0){
  545. renderNextFrame();
  546. }else{
  547. var pendingItem = pendingLayers.pop();
  548. UI.setProgress(pendingLayers.length/totalLayers);
  549. var layerOb = pendingItem.lOb;
  550. var layerInfo = pendingItem.lInfo;
  551. var frameRate = pendingItem.frameRate;
  552. var lType = extrasInstance.layerType(layerInfo);
  553. if(lType == 'AudioLayer' || lType == 'CameraLayer' || (layerInfo.enabled == false && !layerInfo.isTrackMatte)){
  554. //TODO add audios
  555. layerOb.enabled = false;
  556. extrasInstance.setTimeout(analyzeNextLayer,100);
  557. return;
  558. }else if(lType == 'TextLayer'){
  559. var textProp = layerInfo.property("Source Text");
  560. var textDocument = textProp.value;
  561. layerOb.textData = buildTextData(textDocument);
  562. var r = layerInfo.sourceRectAtTime(0, false);
  563. layerOb.textData.xOffset = r.left;
  564. layerOb.textData.yOffset = r.top;
  565. layerOb.textData.width = r.width;
  566. layerOb.textData.height = r.height;
  567. }
  568. //EffectsParser.createEffects(layerInfo,layerOb);
  569. if(layerInfo.mask.numProperties>0){
  570. setMasks(layerInfo.mask,layerOb);
  571. layerOb.hasMask = true;
  572. }
  573. layerOb.type = lType;
  574. if(lType == 'ShapeLayer'){
  575. ShapesParser.createShapes(layerInfo,layerOb, frameRate);
  576. layerOb.rectData = {l:0,t:0,b:0,r:0,w:0,h:0};
  577. }
  578. if(layerInfo.parent != null){
  579. layerOb.parent = layerInfo.parent.index - 1;
  580. }
  581. layerOb.layerName = layerInfo.name;
  582. layerOb.threeD = layerInfo.threeDLayer;
  583. layerOb.an = {};
  584. if(lType=='PreCompLayer'){
  585. layerOb.width = layerInfo.source.width;
  586. layerOb.height = layerInfo.source.height;
  587. }else if(lType == 'StillLayer'){
  588. addStillAsset(layerOb,layerInfo);
  589. layerOb.width = layerInfo.source.width;
  590. layerOb.height = layerInfo.source.height;
  591. }else if(lType == 'SolidLayer'){
  592. layerOb.width = layerInfo.source.width;
  593. layerOb.height = layerInfo.source.height;
  594. layerOb.color = extrasInstance.arrayRgbToHex(layerInfo.source.mainSource.color);
  595. }else if(lType == 'ShapeLayer'){
  596. layerOb.width = layerInfo.width;
  597. layerOb.height = layerInfo.height;
  598. }
  599. layerOb.inPoint = layerInfo.inPoint*frameRate;
  600. layerOb.outPoint = layerInfo.outPoint*frameRate;
  601. layerOb.startTime = layerInfo.startTime*frameRate;
  602. layerOb.lastData = {};
  603. layerOb.ks = {};
  604. if(layerInfo.transform.opacity.numKeys>1){
  605. extrasInstance.convertToBezierValues(layerInfo.transform.opacity, frameRate, layerOb.ks,'o');
  606. }else{
  607. layerOb.ks.o = extrasInstance.roundNumber(layerInfo.transform.opacity.valueAtTime(0,false),3);
  608. }
  609. if(layerInfo.transform.rotation.numKeys>1){
  610. extrasInstance.convertToBezierValues(layerInfo.transform.rotation, frameRate, layerOb.ks,'r');
  611. }else{
  612. layerOb.ks.r = extrasInstance.roundNumber(layerInfo.transform.rotation.valueAtTime(0,false),3);
  613. }
  614. if(layerInfo.transform.position.dimensionsSeparated){
  615. layerOb.ks.p = {s:true};
  616. extrasInstance.convertToBezierValues(layerInfo.transform['X Position'], frameRate, layerOb.ks.p,'x');
  617. extrasInstance.convertToBezierValues(layerInfo.transform['Y Position'], frameRate, layerOb.ks.p,'y');
  618. }else{
  619. if(layerInfo.transform.position.numKeys>1){
  620. extrasInstance.convertToBezierValues(layerInfo.transform.position, frameRate, layerOb.ks,'p');
  621. }else{
  622. layerOb.ks.p = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(0,false),3);
  623. }
  624. }
  625. if(layerInfo.transform['Anchor Point'].numKeys>1){
  626. if(lType == 'ShapeLayer'){
  627. prepareHelperSolid(layerInfo.transform['Anchor Point'],frameRate,layerOb.ks,'a');
  628. }else{
  629. extrasInstance.convertToBezierValues(layerInfo.transform['Anchor Point'], frameRate, layerOb.ks,'a');
  630. }
  631. }else{
  632. layerOb.ks.a = extrasInstance.roundNumber(layerInfo.transform['Anchor Point'].valueAtTime(0,false),3);
  633. }
  634. if(layerInfo.transform['Scale'].numKeys>1){
  635. extrasInstance.convertToBezierValues(layerInfo.transform['Scale'], frameRate, layerOb.ks,'s');
  636. }else{
  637. layerOb.ks.s = extrasInstance.roundNumber(layerInfo.transform['Scale'].valueAtTime(0,false),3);
  638. }
  639. if(layerInfo.canSetTimeRemapEnabled && layerInfo.timeRemapEnabled){
  640. extrasInstance.convertToBezierValues(layerInfo['Time Remap'], frameRate, layerOb,'tm');
  641. }
  642. checkLayerReady();
  643. }
  644. }
  645. function checkLayerReady(){
  646. if(renderCancelled){
  647. callback.apply();
  648. }else{
  649. extrasInstance.setTimeout(analyzeNextLayer,100);
  650. }
  651. }
  652. function prepareHelperSolid(property,frameRate,ob,param){
  653. var currentKeyframe = 1;
  654. var helperPosition = helperSolid.transform["Anchor Point"];
  655. var jLen = helperPosition.numKeys;
  656. while(jLen > 0){
  657. helperPosition.removeKey(1);
  658. jLen -= 1;
  659. }
  660. helperSolidComp.frameRate = frameRate;
  661. jLen = property.numKeys;
  662. var keyIn, keyOut;
  663. var keyInHelper, keyOutHelper;
  664. var propertyValueDelta, helperValueDelta;
  665. function adjustNextHelperSpeed(){
  666. var j;
  667. for(j = 0; j<jLen; j+=1){
  668. keyIn = property.keyInTemporalEase(j+1)[0];
  669. keyOut = property.keyOutTemporalEase(j+1)[0];
  670. keyInHelper = new KeyframeEase(keyIn.speed, keyIn.influence);
  671. keyOutHelper = new KeyframeEase(keyOut.speed, keyOut.influence);
  672. helperPosition.addKey(property.keyTime(j+1));
  673. helperPosition.setValueAtTime(property.keyTime(j+1),property.valueAtTime(property.keyTime(j+1),true));
  674. helperPosition.setTemporalEaseAtKey(j+1, [keyInHelper], [keyOutHelper]);
  675. }
  676. correctNextKey();
  677. }
  678. function correctNextKey(){
  679. var i= 0, len = 20;
  680. if(currentKeyframe !== jLen + 1){
  681. keyIn = property.keyInTemporalEase(currentKeyframe)[0];
  682. keyOut = property.keyOutTemporalEase(currentKeyframe)[0];
  683. propertyValueDelta = property.valueAtTime(property.keyTime(currentKeyframe)+0.01,false);
  684. keyOutHelper = helperPosition.keyOutTemporalEase(currentKeyframe);
  685. keyInHelper = helperPosition.keyInTemporalEase(currentKeyframe);
  686. var flag = true;
  687. var currentSpeed, deltaSpeed = 10, dir = 0;
  688. var helpValue,helpValue2;
  689. if(currentKeyframe != 1){
  690. helpValue = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe),false);
  691. helpValue2 = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe-1),false);
  692. propertyValueDelta = property.valueAtTime(property.keyTime(currentKeyframe)-0.01,false);
  693. helperValueDelta = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe)-0.01,false);
  694. currentSpeed = keyInHelper[0].speed;
  695. deltaSpeed = Math.abs(keyInHelper[0].speed);
  696. if(Math.abs(helperValueDelta[0]) > Math.abs(propertyValueDelta[0]) || Math.abs(helperValueDelta[1]) > Math.abs(propertyValueDelta[1])){
  697. dir = 1;
  698. }else{
  699. dir = -1;
  700. }
  701. while(flag){
  702. helpValue = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe),false);
  703. helpValue2 = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe - 1),false);
  704. helperValueDelta = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe)-0.01,false);
  705. if(Math.abs(helperValueDelta[0]-propertyValueDelta[0]) < 0.001 && Math.abs(helperValueDelta[1]-propertyValueDelta[1]) < 0.001){
  706. flag = false;
  707. }else{
  708. if(Math.abs(helperValueDelta[0]) > Math.abs(propertyValueDelta[0]) || Math.abs(helperValueDelta[1]) > Math.abs(propertyValueDelta[1])){
  709. if(dir == 1){
  710. deltaSpeed /= 2;
  711. }
  712. dir = -1;
  713. currentSpeed += deltaSpeed;
  714. keyInHelper[0].speed = currentSpeed;
  715. helperPosition.setTemporalEaseAtKey(currentKeyframe, keyInHelper, keyOutHelper);
  716. }else{
  717. if(dir == -1){
  718. deltaSpeed /= 2;
  719. }
  720. dir = 1;
  721. currentSpeed -= deltaSpeed;
  722. keyInHelper[0].speed = currentSpeed;
  723. helperPosition.setTemporalEaseAtKey(currentKeyframe, keyInHelper, keyOutHelper);
  724. }
  725. }
  726. i += 1;
  727. if(i == len){
  728. keyInHelper[0].speed = keyIn.speed;
  729. helperPosition.setTemporalEaseAtKey(currentKeyframe, keyInHelper, keyOutHelper);
  730. flag = false;
  731. }
  732. }
  733. }
  734. if(currentKeyframe != jLen){
  735. i = 0;
  736. flag = true;
  737. propertyValueDelta = property.valueAtTime(property.keyTime(currentKeyframe)+0.01,false);
  738. helperValueDelta = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe)+0.01,false);
  739. helpValue = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe),false);
  740. currentSpeed = keyOutHelper[0].speed;
  741. deltaSpeed = Math.abs(keyOutHelper[0].speed);
  742. if(Math.abs(helperValueDelta[0]) > Math.abs(propertyValueDelta[0]) || Math.abs(helperValueDelta[1]) > Math.abs(propertyValueDelta[1])){
  743. dir = -1;
  744. }else{
  745. dir = 1;
  746. }
  747. while(flag){
  748. helpValue = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe),false);
  749. helperValueDelta = helperPosition.valueAtTime(helperPosition.keyTime(currentKeyframe)+0.01,false);
  750. if(Math.abs(helperValueDelta[0]-propertyValueDelta[0]) < 0.001 && Math.abs(helperValueDelta[1]-propertyValueDelta[1]) < 0.001){
  751. flag = false;
  752. }else{
  753. if(Math.abs(helperValueDelta[0]) > Math.abs(propertyValueDelta[0]) || Math.abs(helperValueDelta[1]) > Math.abs(propertyValueDelta[1]) ){
  754. if(dir == -1){
  755. deltaSpeed /= 2;
  756. }
  757. dir = 1;
  758. currentSpeed -= deltaSpeed;
  759. keyOutHelper[0].speed = currentSpeed;
  760. helperPosition.setTemporalEaseAtKey(currentKeyframe, keyInHelper, keyOutHelper);
  761. }else{
  762. if(dir == 1){
  763. deltaSpeed /= 2;
  764. }
  765. dir = -1;
  766. currentSpeed += deltaSpeed;
  767. keyOutHelper[0].speed = currentSpeed;
  768. helperPosition.setTemporalEaseAtKey(currentKeyframe, keyInHelper, keyOutHelper);
  769. }
  770. }
  771. i += 1;
  772. if(i == len){
  773. keyOutHelper[0].speed = keyOut.speed;
  774. helperPosition.setTemporalEaseAtKey(currentKeyframe, keyInHelper, keyOutHelper);
  775. flag = false;
  776. }
  777. }
  778. }
  779. currentKeyframe += 1;
  780. correctNextKey();
  781. }else{
  782. extrasInstance.convertToBezierValues(helperPosition, frameRate, ob,param);
  783. }
  784. }
  785. adjustNextHelperSpeed();
  786. }
  787. function createLayers(compo, layersData, frameRate){
  788. var i, len = compo.layers.length;
  789. var pendingType;
  790. for(i = 0;i<len;i++){
  791. var layerOb = {};
  792. layerOb.ind = i;
  793. var layerInfo = compo.layers[i+1];
  794. var lType = extrasInstance.layerType(layerInfo);
  795. //$.writeln('layerInfo.isTrackMatte: ',layerInfo.isTrackMatte);
  796. //$.writeln('layerInfo.hasTrackMatte: ',layerInfo.hasTrackMatte);
  797. layersData.push(layerOb);
  798. if(lType == 'AudioLayer' || lType == 'CameraLayer' || (layerInfo.enabled == false && !layerInfo.isTrackMatte)){
  799. //TODO add audios
  800. layerOb.enabled = false;
  801. continue;
  802. }
  803. if(layerInfo.hasTrackMatte){
  804. switch(layerInfo.trackMatteType){
  805. case TrackMatteType.ALPHA:
  806. pendingType = 1;
  807. break;
  808. case TrackMatteType.ALPHA_INVERTED:
  809. pendingType = 2;
  810. break;
  811. case TrackMatteType.LUMA:
  812. pendingType = 3;
  813. break;
  814. case TrackMatteType.LUMA_INVERTED :
  815. pendingType = 4;
  816. break;
  817. }
  818. layerOb.tt = pendingType;
  819. }else if(layerInfo.isTrackMatte){
  820. layerOb.td = 1;
  821. }
  822. pendingLayers.push({lInfo:layerInfo,lOb:layerOb,frameRate:frameRate});
  823. if(lType=='PreCompLayer'){
  824. var j = 0, jLen = exportedComps.length, isRendered = false;
  825. while(j<jLen){
  826. if(exportedComps[j].lInfo.source == layerInfo.source){
  827. isRendered = true;
  828. break;
  829. }
  830. j+=1;
  831. }
  832. if(isRendered){
  833. if(!exportedComps[j].lOb.compId){
  834. exportedComps[j].lOb.compId = extrasInstance.getRandomName(7);
  835. }
  836. layerOb.refId = exportedComps[j].lOb.compId;
  837. }else{
  838. layerOb.layers = [];
  839. createLayers(layerInfo.source,layerOb.layers,layerInfo.source.frameRate);
  840. exportedComps.push({
  841. lInfo: layerInfo,
  842. lOb: layerOb
  843. })
  844. }
  845. }
  846. }
  847. }
  848. function getParentSize (name,layers){
  849. var i=0, len = layers.length;
  850. while(i<len){
  851. if(layers[i].layerName == name){
  852. return {width:layers[i].width,height:layers[i].height};
  853. }
  854. i++;
  855. }
  856. return {width:0,height:0};
  857. }
  858. function traverseAnimation(compo,layersData, frameNum, time){
  859. var i, len = compo.layers.length;
  860. for(i = 0;i<len;i++){
  861. var layerInfo = compo.layers[i+1];
  862. var lType = extrasInstance.layerType(layerInfo);
  863. if(lType == 'AudioLayer' || lType == 'CameraLayer' || (layerInfo.enabled == false && !layerInfo.isTrackMatte)){
  864. //TODO add audios
  865. continue;
  866. }
  867. var layerOb = layersData[i];
  868. var animData = {};
  869. if(layerOb.hasMask){
  870. addMasksToLayer(layerInfo,animData,time);
  871. }
  872. animData.tr = {};
  873. animData.tr.p = [];
  874. animData.tr.a = [];
  875. animData.tr.r = [];
  876. animData.tr.s = [];
  877. animData.tr.o = {};
  878. if(layerOb.parent != null){
  879. var parentSize = getParentSize(layerOb.parent,layersData);
  880. animData.tr.p[0] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[0],3);
  881. animData.tr.p[1] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[1],3);
  882. }else{
  883. animData.tr.p[0] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[0],3);
  884. animData.tr.p[1] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[1],3);
  885. }
  886. if(layerOb.threeD){
  887. animData.tr.p[2] = extrasInstance.roundNumber(-layerInfo.transform.position.valueAtTime(time,false)[2],3);
  888. }else{
  889. animData.tr.p[2] = -zCount;
  890. zCount++;
  891. }
  892. if(lType=='ShapeLayer'){
  893. var r = layerInfo.sourceRectAtTime(frameNum, false);
  894. layerOb.rectData.l = extrasInstance.roundNumber(Math.min(r.left,layerOb.rectData.l),3);
  895. layerOb.rectData.t = extrasInstance.roundNumber(Math.min(r.top,layerOb.rectData.t),3);
  896. layerOb.rectData.r = extrasInstance.roundNumber(Math.max(r.left+r.width,layerOb.rectData.r),3);
  897. layerOb.rectData.b = extrasInstance.roundNumber(Math.max(r.top+r.height,layerOb.rectData.b),3);
  898. }
  899. animData.tr.a[0] = extrasInstance.roundNumber(layerInfo.transform['Anchor Point'].valueAtTime(time,false)[0],3);
  900. animData.tr.a[1] = extrasInstance.roundNumber(layerInfo.transform['Anchor Point'].valueAtTime(time,false)[1],3);
  901. animData.tr.a[2] = extrasInstance.roundNumber(-layerInfo.transform['Anchor Point'].valueAtTime(time,false)[2],3);
  902. animData.tr.s = extrasInstance.roundNumber([(layerInfo.transform['Scale'].valueAtTime(time,false)[0]/100),(layerInfo.transform['Scale'].valueAtTime(time,false)[1]/100),(layerInfo.transform['Scale'].valueAtTime(time,false)[2]/100)],3);
  903. if(layerOb.threeD){
  904. animData.tr.r[0] = extrasInstance.roundNumber((layerInfo.transform['X Rotation'].valueAtTime(time,false)+layerInfo.transform['Orientation'].valueAtTime(time,false)[0])*Math.PI/180,3);
  905. animData.tr.r[1] = extrasInstance.roundNumber(-(layerInfo.transform['Y Rotation'].valueAtTime(time,false)+layerInfo.transform['Orientation'].valueAtTime(time,false)[1])*Math.PI/180,3);
  906. animData.tr.r[2] = extrasInstance.roundNumber((layerInfo.transform['Rotation'].valueAtTime(time,false)+layerInfo.transform['Orientation'].valueAtTime(time,false)[2])*Math.PI/180,3);
  907. }else{
  908. animData.tr.r[0] = 0;
  909. animData.tr.r[1] = 0;
  910. animData.tr.r[2] = extrasInstance.roundNumber(layerInfo.transform['Rotation'].valueAtTime(time,false)*Math.PI/180,3);
  911. }
  912. animData.tr.o = extrasInstance.roundNumber(layerInfo.transform['Opacity'].valueAtTime(time,false)/100,3);
  913. if(lType == 'ShapeLayer'){
  914. ShapesParser.addFrameData(layerInfo,layerOb, frameNum, time);
  915. }
  916. if(lType == 'PreCompLayer'){
  917. var compoInTime = -layerInfo.startTime;
  918. traverseAnimation(layerInfo.source,layerOb.layers, frameNum, time+compoInTime);
  919. }
  920. //THIS IS REPLACED WITH THE KEYFRAMES. LEAVE THIS FOR NOW.
  921. /*if(layerOb.lastData.an == null || extrasInstance.compareObjects(animData,layerOb.lastData.an)==false){
  922. layerOb.an[frameNum] = animData;
  923. layerOb.lastData.an = animData;
  924. }*/
  925. EffectsParser.renderFrame(layerOb,frameNum);
  926. }
  927. }
  928. function iterateComposition(){
  929. createLayers(mainComp, mainLayers, mainComp.frameRate);
  930. // TO TRAVERSE LAYER BY LAYER. NEEDED FOR TIME REMAP?
  931. /*renderCompo(mainComp, mainLayers);
  932. AssetsManager.createAssetsDataForExport();
  933. removeExtraData(mainLayers);
  934. processFinalData(mainLayers);
  935. callback.apply();*/
  936. // END TO TRAVERSE LAYER BY LAYER. NEEDED FOR TIME REMAP?
  937. totalLayers = pendingLayers.length;
  938. extrasInstance.setTimeout(analyzeNextLayer,100);
  939. }
  940. function iterateLayer(layerInfo, layerOb,frameRate){
  941. var duration =layerInfo.duration;
  942. layerOb.st = layerInfo.startTime;
  943. var frameNum = 0;
  944. var time = layerInfo.startTime;
  945. var lType = extrasInstance.layerType(layerInfo);
  946. if(lType == 'AudioLayer' || lType == 'CameraLayer' || (layerInfo.enabled == false && !layerInfo.isTrackMatte)){
  947. //TODO add audios
  948. return;
  949. }
  950. while(frameNum < duration*frameRate){
  951. var layerOb = layersData[i];
  952. var animData = {};
  953. if(layerOb.hasMask){
  954. addMasksToLayer(layerInfo,animData,time);
  955. }
  956. animData.tr = {};
  957. animData.tr.p = [];
  958. animData.tr.a = [];
  959. animData.tr.r = [];
  960. animData.tr.s = [];
  961. animData.tr.o = {};
  962. if(layerOb.parent != null){
  963. var parentSize = getParentSize(layerOb.parent,layersData);
  964. animData.tr.p[0] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[0],3);
  965. animData.tr.p[1] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[1],3);
  966. }else{
  967. animData.tr.p[0] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[0],3);
  968. animData.tr.p[1] = extrasInstance.roundNumber(layerInfo.transform.position.valueAtTime(time,false)[1],3);
  969. }
  970. if(layerOb.threeD){
  971. animData.tr.p[2] = extrasInstance.roundNumber(-layerInfo.transform.position.valueAtTime(time,false)[2],3);
  972. }else{
  973. animData.tr.p[2] = -zCount;
  974. zCount++;
  975. }
  976. if(lType=='ShapeLayer'){
  977. var r = layerInfo.sourceRectAtTime(frameNum, false);
  978. layerOb.rectData.l = extrasInstance.roundNumber(Math.min(r.left,layerOb.rectData.l),3);
  979. layerOb.rectData.t = extrasInstance.roundNumber(Math.min(r.top,layerOb.rectData.t),3);
  980. layerOb.rectData.r = extrasInstance.roundNumber(Math.max(r.left+r.width,layerOb.rectData.r),3);
  981. layerOb.rectData.b = extrasInstance.roundNumber(Math.max(r.top+r.height,layerOb.rectData.b),3);
  982. }
  983. animData.tr.a[0] = extrasInstance.roundNumber(layerInfo.transform['Anchor Point'].valueAtTime(time,false)[0],3);
  984. animData.tr.a[1] = extrasInstance.roundNumber(layerInfo.transform['Anchor Point'].valueAtTime(time,false)[1],3);
  985. animData.tr.a[2] = extrasInstance.roundNumber(-layerInfo.transform['Anchor Point'].valueAtTime(time,false)[2],3);
  986. animData.tr.s = extrasInstance.roundNumber([(layerInfo.transform['Scale'].valueAtTime(time,false)[0]/100),(layerInfo.transform['Scale'].valueAtTime(time,false)[1]/100),(layerInfo.transform['Scale'].valueAtTime(time,false)[2]/100)],3);
  987. if(layerOb.threeD){
  988. animData.tr.r[0] = extrasInstance.roundNumber((layerInfo.transform['X Rotation'].valueAtTime(time,false)+layerInfo.transform['Orientation'].valueAtTime(time,false)[0])*Math.PI/180,3);
  989. animData.tr.r[1] = extrasInstance.roundNumber(-(layerInfo.transform['Y Rotation'].valueAtTime(time,false)+layerInfo.transform['Orientation'].valueAtTime(time,false)[1])*Math.PI/180,3);
  990. animData.tr.r[2] = extrasInstance.roundNumber((layerInfo.transform['Rotation'].valueAtTime(time,false)+layerInfo.transform['Orientation'].valueAtTime(time,false)[2])*Math.PI/180,3);
  991. }else{
  992. animData.tr.r[0] = 0;
  993. animData.tr.r[1] = 0;
  994. animData.tr.r[2] = extrasInstance.roundNumber(layerInfo.transform['Rotation'].valueAtTime(time,false)*Math.PI/180,3);
  995. }
  996. animData.tr.o = extrasInstance.roundNumber(layerInfo.transform['Opacity'].valueAtTime(time,false)/100,3);
  997. if(lType == 'ShapeLayer'){
  998. ShapesParser.addFrameData(layerInfo,layerOb, frameNum, time);
  999. }
  1000. //THIS IS REPLACED WITH THE KEYFRAMES. BUT SHOULD BE USED FOR EXPRESSION LAYERS.
  1001. if(layerOb.lastData.an == null || extrasInstance.compareObjects(animData,layerOb.lastData.an)==false){
  1002. layerOb.an[frameNum] = animData;
  1003. layerOb.lastData.an = animData;
  1004. }
  1005. //END FOR EXPRESSION LAYERS
  1006. EffectsParser.renderFrame(layerOb,frameNum);
  1007. frameNum += 1;
  1008. time += 1/frameRate;
  1009. }
  1010. //traverseAnimation(layerInfo.source,layerOb.layers, frameNum, time+compoInTime);
  1011. if(lType == 'PreCompLayer'){
  1012. var i, len = layerInfo.source.layers.length;
  1013. for(i = 0;i<len;i++){
  1014. iterateLayer(layerInfo.source.layers[i+1],layerOb.layers[i],layerInfo.source.frameRate);
  1015. }
  1016. }
  1017. }
  1018. function renderCompo(compo, mainLayers){
  1019. //var duration = compo.duration;
  1020. var i, len = compo.layers.length;
  1021. for(i = 0;i<len;i++){
  1022. iterateLayer(compo.layers[i+1],mainLayers[i],compo.frameRate);
  1023. }
  1024. }
  1025. function renderNextFrame(){
  1026. /*if(currentRenderFrame < totalFrames && renderCancelled === false){
  1027. renderFrame();
  1028. currentRenderFrame +=1;
  1029. renderNextFrame();
  1030. //extrasInstance.setTimeout(renderNextFrame,50);
  1031. }else{
  1032. isRenderReady = true;
  1033. checkRenderReady();
  1034. }*/
  1035. isRenderReady = true;
  1036. checkRenderReady();
  1037. }
  1038. function checkRenderReady(){
  1039. if(AsyncManager.getAsyncCounter() == 0 && isRenderReady == true){
  1040. AssetsManager.createAssetsDataForExport();
  1041. removeExtraData(mainLayers);
  1042. processFinalData(mainLayers);
  1043. callback.apply();
  1044. }
  1045. }
  1046. function renderFrame(){
  1047. currentTime = (currentRenderFrame+firstFrame)/frameRate;
  1048. zCount = 0;
  1049. traverseAnimation(mainComp,mainLayers, currentRenderFrame,currentTime);
  1050. }
  1051. function setCallback(cb){
  1052. callback = cb;
  1053. }
  1054. AsyncManager.setCallBack(checkRenderReady);
  1055. var ob = {};
  1056. ob.getCompositionAnimationData = getCompositionAnimationData;
  1057. ob.setCallback = setCallback;
  1058. DOMAnimationManager = ob;
  1059. }());
  1060. /****** END DOMAnimationMAnager ******/
  1061. /****** INIT Effects Parser ******/
  1062. (function(){
  1063. var ob = {};
  1064. var registeredEffects = {};
  1065. function createEffects(layerInfo,layerOb){
  1066. if(layerInfo.effect.numProperties>0){
  1067. layerOb.eff = [];
  1068. var i, len = layerInfo.effect.numProperties, name;
  1069. for(i=0;i<len;i++){
  1070. name = layerInfo.effect(i+1).name;
  1071. if(registeredEffects[name] != null){
  1072. layerOb.eff.push({parser: registeredEffects[name], id:registeredEffects[name].registerElement(layerInfo.effect(i+1))});
  1073. }
  1074. }
  1075. }
  1076. }
  1077. function renderFrame(layerOb,frameNum){
  1078. if(layerOb.eff){
  1079. layerOb.eff.forEach(function(item){
  1080. item.parser.renderFrame(frameNum);
  1081. });
  1082. }
  1083. }
  1084. function saveEffectData(layerOb){
  1085. if(layerOb.eff){
  1086. layerOb.eff = layerOb.eff.map(function(item){
  1087. return item.parser.getData(item.id);
  1088. });
  1089. }
  1090. }
  1091. function registerEffect(name,object){
  1092. registeredEffects[name] = object;
  1093. }
  1094. ob.registerEffect = registerEffect;
  1095. ob.createEffects = createEffects;
  1096. ob.renderFrame = renderFrame;
  1097. ob.saveEffectData = saveEffectData;
  1098. EffectsParser = ob;
  1099. }());
  1100. /****** END Effects Parser ******/
  1101. /****** INIT Effects Stroke Parser ******/
  1102. (function(){
  1103. var ob = {};
  1104. var registeredElements = [];
  1105. var lastValues = {};
  1106. function renderFrame(frameNum, id){
  1107. var effectData = registeredElements[id];
  1108. var effectInfo = effectData.elem;
  1109. for(var s in effectData.animated){
  1110. var propertyValue = getPropertyValue(effectInfo[s].value,getPropertyType(s));
  1111. if(lastValues[s] == null || !extrasInstance.compareObjects(propertyValue,lastValues[s])){
  1112. effectData.animated[s][frameNum] = propertyValue;
  1113. lastValues[s] = propertyValue;
  1114. }
  1115. }
  1116. }
  1117. function getPropertyValue(value,type){
  1118. switch(type)
  1119. {
  1120. case 'color':
  1121. return extrasInstance.arrayRgbToHex(value);
  1122. break;
  1123. default:
  1124. return value;
  1125. break;
  1126. }
  1127. }
  1128. function getPropertyType(propertyName){
  1129. var i = 0;len = animatableProperties.length;
  1130. while(i<len){
  1131. if(animatableProperties[i].name == propertyName){
  1132. return animatableProperties[i].type;
  1133. }
  1134. i++;
  1135. }
  1136. return '';
  1137. }
  1138. function getData(id){
  1139. return registeredElements[id];
  1140. }
  1141. function registerElement(elem){
  1142. var effectData = {
  1143. type: 'Stroke',
  1144. effectInfo : elem,
  1145. effectDataPath : elem['Path'].value,
  1146. allMasks : elem['All Masks'].value,
  1147. strokeSequentially : elem['Stroke Sequentially'].value,
  1148. animated: {},
  1149. singleValue: {}
  1150. };
  1151. registeredElements.push(effectData);
  1152. animatableProperties.forEach(function(item){
  1153. if(elem[item.name].numKeys == 0){
  1154. effectData.singleValue[item.name] = getPropertyValue(effectInfo[item.name].value, item.type);
  1155. }else{
  1156. effectData.animated[item.name] = {};
  1157. }
  1158. });
  1159. return registeredElements.length;
  1160. }
  1161. var animatableProperties = [{name:'Color',type:'color'},{name:'Brush Size',type:'simple'},{name:'Brush Hardness',type:'simple'},{name:'Opacity',type:'simple'},{name:'Start',type:'simple'},{name:'End',type:'simple'},{name:'Spacing',type:'simple'},{name:'Paint Style',type:'simple'}];
  1162. var i, len = animatableProperties.length;
  1163. ob.renderFrame = renderFrame;
  1164. ob.getData = getData;
  1165. ob.registerElement = registerElement;
  1166. EffectsParser.registerEffect('Stroke',ob);
  1167. }());
  1168. /****** END Effects Stroke Parser ******/
  1169. /****** INIT extras******/
  1170. (function (){
  1171. function getItemByName(name,collection){
  1172. for(var i=0;i<collection.length;i++){
  1173. if(collection[i+1].name==name){
  1174. return collection[i+1];
  1175. }
  1176. }
  1177. return null;
  1178. }
  1179. function compareObjects(object1,object2){
  1180. return JSON.stringify(object1) === JSON.stringify(object2);
  1181. }
  1182. function roundNumber(num, decimals){
  1183. if( typeof num == 'number'){
  1184. return parseFloat(num.toFixed(decimals));
  1185. }else{
  1186. return roundArray(num,decimals);
  1187. }
  1188. }
  1189. function roundArray(arr, decimals){
  1190. var i, len = arr.length;
  1191. var retArray = [];
  1192. for( i = 0; i < len ; i += 1){
  1193. if( typeof arr[i] == 'number'){
  1194. retArray.push(roundNumber(arr[i],decimals));
  1195. }else{
  1196. retArray.push(roundArray(arr[i],decimals));
  1197. }
  1198. }
  1199. return retArray;
  1200. }
  1201. function setInterval(func,millis){
  1202. var guid = getRandomName(10);
  1203. Gtlym.CALL["interval_"+guid] = func;
  1204. return app.scheduleTask('Gtlym.CALL["interval_'+guid+'"]();',millis,true);
  1205. }
  1206. function setTimeout(func,millis){
  1207. var guid = getRandomName(10);
  1208. Gtlym.CALL["interval_"+guid] = func;
  1209. return app.scheduleTask('Gtlym.CALL["interval_'+guid+'"]();',millis,false);
  1210. }
  1211. function cancelTimeout(id){
  1212. app.cancelTask(id);
  1213. }
  1214. function cancelInterval(id){
  1215. app.cancelTask(id);
  1216. }
  1217. function removeDirectoryContent(f, callback){
  1218. var removeNextItem = function(){
  1219. currentFileIndex++;
  1220. if(currentFileIndex == len){
  1221. callback.apply();
  1222. }else{
  1223. removeFileFromDisk(files[currentFileIndex],removeNextItem);
  1224. }
  1225. };
  1226. var files = f.getFiles();
  1227. var len = files.length;
  1228. var currentFileIndex = 0;
  1229. if(len==0){
  1230. callback.apply();
  1231. }else{
  1232. removeFileFromDisk(files[currentFileIndex],removeNextItem);
  1233. }
  1234. }
  1235. function removeFileFromDisk(f, cb){
  1236. var callback = cb;
  1237. var currentFileIndex =0;
  1238. var removeNextItem = function(){
  1239. currentFileIndex++;
  1240. if(currentFileIndex >= len){
  1241. if(f.remove()){
  1242. callback.apply();
  1243. }else{
  1244. }
  1245. }else{
  1246. removeFileFromDisk(files[currentFileIndex],removeNextItem);
  1247. }
  1248. };
  1249. if (f instanceof File){
  1250. if(f.remove()){
  1251. callback.apply();
  1252. }else{
  1253. }
  1254. }else{
  1255. var files = f.getFiles();
  1256. var len = files.length;
  1257. if(len==0){
  1258. removeNextItem();
  1259. }else{
  1260. removeFileFromDisk(files[currentFileIndex],removeNextItem);
  1261. }
  1262. }
  1263. }
  1264. function getRandomName(length){
  1265. var sequence = 'abcdefghijklmnoqrstuvwxyz1234567890';
  1266. var returnString ='';
  1267. for(var i=0;i<length;i++){
  1268. returnString += sequence.charAt(Math.floor(Math.random()*sequence.length));
  1269. }
  1270. return returnString;
  1271. }
  1272. function iterateProperty(property, space){
  1273. if(space === null || space === undefined){
  1274. space = 0;
  1275. }
  1276. var spaceString ='';
  1277. for(var a=0;a<space;a++){
  1278. spaceString+=' ';
  1279. }
  1280. if(property.numProperties){
  1281. $.writeln(spaceString+'--- new iteration '+property.name+' ---');
  1282. var i=0, len = property.numProperties;
  1283. while(i<len){
  1284. $.writeln(spaceString+'-> '+property(i+1).name +" | "+property(i+1).matchName );
  1285. iterateProperty(property(i+1), space+1);
  1286. i++;
  1287. }
  1288. }else{
  1289. if(property.propertyValueType != PropertyValueType.NO_VALUE && property.value != undefined){
  1290. $.writeln(spaceString+'--- Value:'+property.value.toString()+' ---');
  1291. }else{
  1292. $.writeln(spaceString+'--- No Value:'+' ---');
  1293. }
  1294. }
  1295. }
  1296. function rgbToHex(r, g, b) {
  1297. return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
  1298. }
  1299. function arrayRgbToHex(values) {
  1300. return rgbToHex(Math.round(values[0]*255),Math.round(values[1]*255),Math.round(values[2]*255));
  1301. }
  1302. function layerType(layerOb){
  1303. function avLayerType(lObj){
  1304. var lSource = lObj.source;
  1305. if(lSource instanceof CompItem){
  1306. return "PreCompLayer";
  1307. }
  1308. var lMainSource = lSource.mainSource;
  1309. var lFile = lMainSource.file;
  1310. if(!lObj.hasVideo){
  1311. return "AudioLayer";
  1312. }else if(lSource instanceof CompItem){
  1313. return "PreCompLayer";
  1314. }else if(lSource.frameDuration < 1){
  1315. if(lMainSource instanceof PlaceholderSource){
  1316. return "PlaceholderVideoLayer";
  1317. }else if(lSource.name.toString().indexOf("].") != -1){
  1318. return "ImageSequenceLayer";
  1319. }else{
  1320. return "VideoLayer";
  1321. }
  1322. }else if(lSource.frameDuration == 1){
  1323. if(lMainSource instanceof PlaceholderSource){
  1324. return "PlaceholderStillLayer";
  1325. }else if(lMainSource.color){
  1326. return "SolidLayer";
  1327. }else{
  1328. return "StillLayer";
  1329. }
  1330. }
  1331. }
  1332. try{
  1333. var curLayer,instanceOfArray,instanceOfArrayLength,result;
  1334. curLayer = layerOb;
  1335. instanceOfArray = [AVLayer, CameraLayer, LightLayer, ShapeLayer, TextLayer];
  1336. instanceOfArrayLength = instanceOfArray.length;
  1337. if(curLayer.guideLayer){
  1338. return "GuideLayer";
  1339. }else if(curLayer.adjustmentLayer){
  1340. return "AdjustmentLayer";
  1341. }else if (curLayer.nullLayer)
  1342. {
  1343. return "NullLayer";
  1344. }
  1345. for(var i = 0;i<instanceOfArrayLength;i++){
  1346. if(curLayer instanceof instanceOfArray[i]){
  1347. result = instanceOfArray[i].name;
  1348. break;
  1349. }
  1350. }
  1351. if(result == "AVLayer"){
  1352. result = avLayerType(curLayer);
  1353. };
  1354. return result;
  1355. }catch(err){alert(err.line.toString+" "+err.toString())}
  1356. }
  1357. function getprojectItemType(item){
  1358. var getType = {};
  1359. var type = getType.toString.call(item);
  1360. var itemType = '';
  1361. switch(type){
  1362. case "[object FolderItem]":
  1363. itemType = 'Folder';
  1364. break;
  1365. case "[object FootageItem]":
  1366. itemType = 'Footage';
  1367. break;
  1368. case "[object CompItem]":
  1369. itemType = 'Comp';
  1370. break;
  1371. default:
  1372. itemType = type;
  1373. break;
  1374. }
  1375. return itemType;
  1376. }
  1377. function convertToBezierValues(property, frameRate, ob,propertyName){
  1378. function getPropertyValue(value, roundFlag){
  1379. switch(property.propertyValueType){
  1380. case PropertyValueType.SHAPE:
  1381. var elem = {
  1382. i : roundFlag ? extrasInstance.roundNumber(value.inTangents,3) : value.inTangents,
  1383. o : roundFlag ? extrasInstance.roundNumber(value.outTangents,3) : value.outTangents,
  1384. v : roundFlag ? extrasInstance.roundNumber(value.vertices,3) : value.vertices
  1385. };
  1386. return elem;
  1387. case PropertyValueType.COLOR:
  1388. var i, len = value.length;
  1389. for(i = 0; i < len; i+=1){
  1390. value[i] = Math.round(value[i]*255);
  1391. }
  1392. return value;
  1393. default:
  1394. return roundFlag ? extrasInstance.roundNumber(value,3) : value;
  1395. }
  1396. }
  1397. var j = 1, jLen = property.numKeys;
  1398. var beziersArray = [];
  1399. var averageSpeed, duration;
  1400. var bezierIn, bezierOut;
  1401. function buildSegment(segmentOb, indexTime){
  1402. function getCurveLength(initPos,endPos, outBezier, inBezier){
  1403. var k, curveSegments = 200;
  1404. var point,lastPoint = null;
  1405. var ptDistance;
  1406. var absToCoord,absTiCoord;
  1407. var triCoord1,triCoord2,triCoord3,liCoord1,liCoord2,ptCoord,perc,addedLength = 0;
  1408. for(k=0;k<curveSegments;k+=1){
  1409. point = [];
  1410. perc = k/(curveSegments-1);
  1411. ptDistance = 0;
  1412. absToCoord = [];
  1413. absTiCoord = [];
  1414. outBezier.forEach(function(item,index){
  1415. if(absToCoord[index] == null){
  1416. absToCoord[index] = initPos[index] + outBezier[index];
  1417. absTiCoord[index] = endPos[index] + inBezier[index];
  1418. }
  1419. triCoord1 = initPos[index] + (absToCoord[index] - initPos[index])*perc;
  1420. triCoord2 = absToCoord[index] + (absTiCoord[index] - absToCoord[index])*perc;
  1421. triCoord3 = absTiCoord[index] + (endPos[index] - absTiCoord[index])*perc;
  1422. liCoord1 = triCoord1 + (triCoord2 - triCoord1)*perc;
  1423. liCoord2 = triCoord2 + (triCoord3 - triCoord2)*perc;
  1424. ptCoord = liCoord1 + (liCoord2 - liCoord1)*perc;
  1425. point.push(ptCoord);
  1426. if(lastPoint !== null){
  1427. ptDistance += Math.pow(point[index] - lastPoint[index],2);
  1428. }
  1429. });
  1430. ptDistance = Math.sqrt(ptDistance);
  1431. addedLength += ptDistance;
  1432. lastPoint = point;
  1433. }
  1434. return addedLength;
  1435. }
  1436. var i, len;
  1437. var key = {};
  1438. var lastKey = {};
  1439. var interpolationType = '';
  1440. key.time = property.keyTime(indexTime+1);
  1441. lastKey.time = property.keyTime(indexTime);
  1442. key.value = getPropertyValue(property.keyValue(indexTime+1), false);
  1443. lastKey.value = getPropertyValue(property.keyValue(indexTime), false);
  1444. if(!(key.value instanceof Array)){
  1445. key.value = [key.value];
  1446. lastKey.value = [lastKey.value];
  1447. }
  1448. if(property.keyOutInterpolationType(indexTime) == KeyframeInterpolationType.HOLD){
  1449. interpolationType = 'hold';
  1450. }else{
  1451. if(property.keyOutInterpolationType(indexTime) == KeyframeInterpolationType.LINEAR && property.keyInInterpolationType(indexTime + 1) == KeyframeInterpolationType.LINEAR){
  1452. interpolationType = 'linear';
  1453. }
  1454. buildKeyInfluence(key, lastKey, indexTime);
  1455. switch(property.propertyValueType){
  1456. case PropertyValueType.ThreeD_SPATIAL:
  1457. case PropertyValueType.TwoD_SPATIAL:
  1458. lastKey.to = property.keyOutSpatialTangent(indexTime);
  1459. key.ti = property.keyInSpatialTangent(indexTime+1);
  1460. break;
  1461. }
  1462. }
  1463. if(interpolationType == 'hold'){
  1464. segmentOb.t = extrasInstance.roundNumber(lastKey.time*frameRate,3);
  1465. segmentOb.s = getPropertyValue(property.keyValue(j), true);
  1466. if(!(segmentOb.s instanceof Array)){
  1467. segmentOb.s = [segmentOb.s];
  1468. }
  1469. segmentOb.h = 1;
  1470. j += 1;
  1471. buildNextSegment();
  1472. return;
  1473. }
  1474. duration = key.time - lastKey.time;
  1475. len = key.value.length;
  1476. bezierIn = {};
  1477. bezierOut = {};
  1478. averageSpeed = 0;
  1479. var infOut,infIn;
  1480. switch(property.propertyValueType){
  1481. case PropertyValueType.ThreeD_SPATIAL:
  1482. case PropertyValueType.TwoD_SPATIAL:
  1483. var curveLength = getCurveLength(lastKey.value,key.value, lastKey.to, key.ti);
  1484. averageSpeed = curveLength/duration;
  1485. if(curveLength === 0){
  1486. infOut = lastKey.easeOut.influence;
  1487. infIn = key.easeIn.influence;
  1488. }else{
  1489. infOut = Math.min(100*curveLength/(lastKey.easeOut.speed*duration), lastKey.easeOut.influence);
  1490. infIn = Math.min(100*curveLength/(key.easeIn.speed*duration), key.easeIn.influence);
  1491. }
  1492. bezierIn.x = 1 - infIn / 100;
  1493. bezierOut.x = infOut / 100;
  1494. break;
  1495. case PropertyValueType.SHAPE:
  1496. averageSpeed = 1;
  1497. infOut = Math.min(100/lastKey.easeOut.speed, lastKey.easeOut.influence);
  1498. infIn = Math.min(100/key.easeIn.speed, key.easeIn.influence);
  1499. bezierIn.x = 1 - infIn / 100;
  1500. bezierOut.x = infOut / 100;
  1501. break;
  1502. case PropertyValueType.ThreeD:
  1503. case PropertyValueType.TwoD:
  1504. case PropertyValueType.OneD:
  1505. case PropertyValueType.COLOR:
  1506. bezierIn.x = [];
  1507. bezierOut.x = [];
  1508. key.easeIn.forEach(function(item, index){
  1509. bezierIn.x[index] = 1 - item.influence / 100;
  1510. bezierOut.x[index] = lastKey.easeOut[index].influence / 100;
  1511. });
  1512. averageSpeed = [];
  1513. for(i=0;i<len;i+=1){
  1514. averageSpeed[i] = (key.value[i] - lastKey.value[i])/duration;
  1515. }
  1516. break;
  1517. }
  1518. if(averageSpeed == 0){
  1519. bezierIn.y = bezierIn.x;
  1520. bezierOut.y = bezierOut.x;
  1521. }else{
  1522. switch(property.propertyValueType){
  1523. case PropertyValueType.ThreeD_SPATIAL:
  1524. case PropertyValueType.TwoD_SPATIAL:
  1525. case PropertyValueType.SHAPE:
  1526. if(interpolationType == 'linear'){
  1527. bezierIn.y = bezierIn.x;
  1528. bezierOut.y = bezierOut.x;
  1529. }else{
  1530. bezierIn.y = 1 - ((key.easeIn.speed) / averageSpeed) * (infIn / 100);
  1531. bezierOut.y = ((lastKey.easeOut.speed) / averageSpeed) * bezierOut.x;
  1532. }
  1533. break;
  1534. case PropertyValueType.ThreeD:
  1535. case PropertyValueType.TwoD:
  1536. case PropertyValueType.OneD:
  1537. case PropertyValueType.COLOR:
  1538. bezierIn.y = [];
  1539. bezierOut.y = [];
  1540. key.easeIn.forEach(function(item,index){
  1541. if(averageSpeed[index] == 0 || interpolationType == 'linear'){
  1542. bezierIn.y[index] = bezierIn.x[index];
  1543. bezierOut.y[index] = bezierOut.x[index];
  1544. }else{
  1545. bezierIn.y[index] = 1 - ((item.speed) / averageSpeed[index]) * (item.influence / 100);
  1546. bezierOut.y[index] = ((lastKey.easeOut[index].speed) / averageSpeed[index]) * bezierOut.x[index];
  1547. }
  1548. });
  1549. break;
  1550. }
  1551. }
  1552. bezierIn.x = extrasInstance.roundNumber(bezierIn.x,3);
  1553. bezierIn.y = extrasInstance.roundNumber(bezierIn.y,3);
  1554. bezierOut.x = extrasInstance.roundNumber(bezierOut.x,3);
  1555. bezierOut.y = extrasInstance.roundNumber(bezierOut.y,3);
  1556. segmentOb.i = bezierIn;
  1557. segmentOb.o = bezierOut;
  1558. segmentOb.n = (bezierIn.x.toString()+'_'+bezierIn.y.toString()+'_'+bezierOut.x.toString()+'_'+bezierOut.y.toString()).replace(/\./g, 'p');
  1559. segmentOb.t = extrasInstance.roundNumber(lastKey.time*frameRate,3);
  1560. segmentOb.s = getPropertyValue(property.keyValue(j), true);
  1561. segmentOb.e = getPropertyValue(property.keyValue(j+1), true);
  1562. if(!(segmentOb.s instanceof Array)){
  1563. segmentOb.s = [segmentOb.s];
  1564. segmentOb.e = [segmentOb.e];
  1565. }
  1566. if(property.propertyValueType == PropertyValueType.ThreeD_SPATIAL || property.propertyValueType == PropertyValueType.TwoD_SPATIAL ){
  1567. segmentOb.to = lastKey.to;
  1568. segmentOb.ti = key.ti;
  1569. }
  1570. j += 1;
  1571. buildNextSegment();
  1572. }
  1573. if(property.numKeys <= 1){
  1574. //beziersArray.push(getPropertyValue(property.valueAtTime(0,true), true));
  1575. ob[propertyName] = getPropertyValue(property.valueAtTime(0,true), true);
  1576. return;
  1577. }
  1578. function buildKeyInfluence(key,lastKey, indexTime){
  1579. switch(property.propertyValueType){
  1580. case PropertyValueType.ThreeD_SPATIAL:
  1581. case PropertyValueType.TwoD_SPATIAL:
  1582. case PropertyValueType.SHAPE:
  1583. key.easeIn = {
  1584. influence : property.keyInTemporalEase(indexTime+1)[0].influence,
  1585. speed : property.keyInTemporalEase(indexTime+1)[0].speed
  1586. };
  1587. lastKey.easeOut = {
  1588. influence : property.keyOutTemporalEase(indexTime)[0].influence,
  1589. speed : property.keyOutTemporalEase(indexTime)[0].speed
  1590. };
  1591. break;
  1592. default:
  1593. key.easeIn = [];
  1594. lastKey.easeOut = [];
  1595. var inEase = property.keyInTemporalEase(indexTime+1);
  1596. var outEase = property.keyOutTemporalEase(indexTime);
  1597. inEase.forEach(function(item,index){
  1598. key.easeIn.push({influence : item.influence, speed:item.speed});
  1599. lastKey.easeOut.push({influence : outEase[index].influence, speed:outEase[index].speed});
  1600. });
  1601. }
  1602. }
  1603. function buildNextSegment(){
  1604. if(j<jLen){
  1605. var segmentOb = {};
  1606. beziersArray.push(segmentOb);
  1607. buildSegment(segmentOb,j);
  1608. }
  1609. }
  1610. buildNextSegment();
  1611. beziersArray.push({t:property.keyTime(j)*frameRate});
  1612. ob[propertyName] = beziersArray;
  1613. }
  1614. var ob = {};
  1615. ob.getItemByName = getItemByName;
  1616. ob.compareObjects = compareObjects;
  1617. ob.roundNumber = roundNumber;
  1618. ob.roundArray = roundArray;
  1619. ob.setInterval = setInterval;
  1620. ob.setTimeout = setTimeout;
  1621. ob.cancelTimeout = cancelTimeout;
  1622. ob.cancelInterval = cancelInterval;
  1623. ob.removeDirectoryContent = removeDirectoryContent;
  1624. ob.removeFileFromDisk = removeFileFromDisk;
  1625. ob.getRandomName = getRandomName;
  1626. ob.iterateProperty = iterateProperty;
  1627. ob.rgbToHex = rgbToHex;
  1628. ob.arrayRgbToHex = arrayRgbToHex;
  1629. ob.layerType = layerType;
  1630. ob.getprojectItemType = getprojectItemType;
  1631. ob.convertToBezierValues = convertToBezierValues;
  1632. extrasInstance = ob;
  1633. }());
  1634. (function(){
  1635. var rqCollection;
  1636. var proj = null;
  1637. var queueItem;
  1638. var moduleItem;
  1639. var destinationFile;
  1640. var counter = 0;
  1641. var templateName = 'HTML_bodyMoving_template';
  1642. var filesDirectory;
  1643. function addComposition(comp){
  1644. filesDirectory = new Folder(exportFolder.fullName+'/temp');
  1645. if(!filesDirectory.exists){
  1646. filesDirectory.create();
  1647. }
  1648. unqueueAllItems();
  1649. queueItem = rqCollection.add(comp);
  1650. queueItem.render = true;
  1651. moduleItem = queueItem.outputModule(1);
  1652. moduleItem.applyTemplate(templateName);
  1653. destinationFile = new File(filesDirectory.fullName+'/'+'tempFile_'+counter+'.png');
  1654. moduleItem.file = destinationFile;
  1655. proj.renderQueue.render();
  1656. counter++;
  1657. }
  1658. function importHelperProject(){
  1659. var i=0, len = helperFootage.items.length;
  1660. var helperComp;
  1661. while(i<len){
  1662. if(extrasInstance.getprojectItemType(helperFootage.item(i+1)) == 'Comp'){
  1663. helperComp = helperFootage.item(i+1);
  1664. break;
  1665. }
  1666. i += 1;
  1667. }
  1668. var renderer = searchHelperRenderer(helperComp);
  1669. var helperModule = renderer.outputModule(1);
  1670. var templates = helperModule.templates;
  1671. i = 0;
  1672. len = templates.length;
  1673. var found = false;
  1674. while(i<len){
  1675. if(templates[i] === templateName){
  1676. found = true;
  1677. break;
  1678. }
  1679. i+=1;
  1680. }
  1681. if(found === false){
  1682. helperModule.saveAsTemplate(templateName);
  1683. }
  1684. renderer.remove();
  1685. }
  1686. function searchHelperRenderer(helperComp){
  1687. var i=0,len = proj.renderQueue.items.length;
  1688. var item;
  1689. while(i<len){
  1690. item = proj.renderQueue.items[i+1];
  1691. if(item.comp == helperComp){
  1692. return item;
  1693. }
  1694. i++;
  1695. }
  1696. }
  1697. function unqueueAllItems(){
  1698. var item;
  1699. var i,len = proj.renderQueue.items.length;
  1700. for(i=0;i<len;i++){
  1701. item = proj.renderQueue.items[i+1];
  1702. if(verifyIfRenderable(item.status)){
  1703. proj.renderQueue.items[i+1].render = false;
  1704. }
  1705. }
  1706. }
  1707. function verifyIfRenderable(status){
  1708. switch(status){
  1709. case RQItemStatus.USER_STOPPED:
  1710. case RQItemStatus.ERR_STOPPED:
  1711. case RQItemStatus.DONE:
  1712. case RQItemStatus.RENDERING:
  1713. return false;
  1714. }
  1715. return true;
  1716. }
  1717. function getStatus(){
  1718. var status = queueItem.status;
  1719. if(status==RQItemStatus.DONE){
  1720. queueItem.remove();
  1721. renameFile();
  1722. }
  1723. return status;
  1724. }
  1725. function renameFile(){
  1726. if(destinationFile.exists){
  1727. if(destinationFile.remove()){
  1728. var renamingFile = new File(destinationFile.fullName+'00000');
  1729. renamingFile.rename(destinationFile.name);
  1730. }else{
  1731. //TODO handle error when removing file
  1732. }
  1733. }else{
  1734. var renamingFile = new File(destinationFile.fullName+'00000');
  1735. renamingFile.rename(destinationFile.name);
  1736. }
  1737. }
  1738. function getFile(){
  1739. return destinationFile;
  1740. }
  1741. function setProject(project){
  1742. if(proj == null){
  1743. proj = project;
  1744. rqCollection = project.renderQueue.items;
  1745. importHelperProject();
  1746. }
  1747. }
  1748. var ob = {};
  1749. ob.addComposition = addComposition;
  1750. ob.getStatus = getStatus;
  1751. ob.getFile = getFile;
  1752. ob.setProject = setProject;
  1753. rqManager = ob;
  1754. }());
  1755. /****** END rqManager ******/
  1756. /****** INIT LayerConverter ******/
  1757. (function(){
  1758. var pendingComps = [];
  1759. var convertedSources = [];
  1760. var duplicatedSources = [];
  1761. var helperFolder;
  1762. var currentLayerNum = 0;
  1763. var currentCompositionNum = 0;
  1764. var totalLayers;
  1765. var tempConverterComp;
  1766. var currentComposition;
  1767. var currentSource;
  1768. var currentLayerInfo;
  1769. var duplicateMainComp;
  1770. var callback;
  1771. function convertComposition(comp){
  1772. var i=0, len = helperFootage.items.length;
  1773. while(i<len){
  1774. if(extrasInstance.getprojectItemType(helperFootage.item(i+1)) == 'Folder'){
  1775. helperFolder = helperFootage.item(i+1);
  1776. break;
  1777. }
  1778. i += 1;
  1779. }
  1780. AssetsManager.reset();
  1781. duplicateMainComp = comp.duplicate();
  1782. //duplicateMainComp.openInViewer() ;
  1783. duplicateMainComp.parentFolder = helperFolder;
  1784. currentLayerNum = 0;
  1785. currentCompositionNum = 0;
  1786. pendingComps = [];
  1787. convertedSources = [];
  1788. duplicatedSources = [];
  1789. pendingComps.push(duplicateMainComp);
  1790. if(pendingComps.length == 1){
  1791. extrasInstance.setTimeout(iterateNextComposition,100);
  1792. }
  1793. };
  1794. function iterateNextComposition(){
  1795. UI.setExportText('Searching next comp');
  1796. if(currentCompositionNum == pendingComps.length){
  1797. UI.setExportText('Done');
  1798. //TODO dar acceso externo a main comp
  1799. //TODO despachar evento de fin
  1800. callback.apply(null,[duplicateMainComp]);
  1801. return;
  1802. }
  1803. currentComposition = pendingComps[currentCompositionNum];
  1804. currentLayerNum = 0;
  1805. totalLayers = currentComposition.layers.length;
  1806. extrasInstance.setTimeout(verifyNextItem,100);
  1807. }
  1808. function verifyNextItem(){
  1809. if(currentLayerNum<totalLayers){
  1810. var layerInfo = currentComposition.layers[currentLayerNum+1];
  1811. UI.setExportText('Verifying item: ' + currentLayerNum + ' from '+ layerInfo.name);
  1812. var lType = extrasInstance.layerType(layerInfo);
  1813. if(lType == 'StillLayer' && layerInfo.enabled){
  1814. currentSource = layerInfo.source;
  1815. var convertedSource = searchConvertedSource(currentSource);
  1816. if(convertedSource==null){
  1817. currentLayerInfo = layerInfo;
  1818. tempConverterComp = app.project.items.addComp('tempConverterComp',Math.max(4,currentSource.width),Math.max(4,currentSource.height),1,1,1);
  1819. tempConverterComp.layers.add(currentSource);
  1820. rqManager.addComposition(tempConverterComp);
  1821. waitForRenderDone();
  1822. }else{
  1823. AssetsManager.associateLayerToSource(layerInfo,currentSource);
  1824. //replaceCurrentLayerSource(convertedSource); //NOT REPLACING FOOTAGE. NOT SURE IF NEEDED.
  1825. currentLayerNum++;
  1826. extrasInstance.setTimeout(verifyNextItem,100);
  1827. }
  1828. }else{
  1829. if(lType=='PreCompLayer'){
  1830. var copy = searchCompositionDuplicate(layerInfo);
  1831. layerInfo.replaceSource(copy, false);
  1832. pendingComps.push(copy);
  1833. copy.parentFolder = helperFolder;
  1834. }
  1835. currentLayerNum++;
  1836. extrasInstance.setTimeout(verifyNextItem,100);
  1837. }
  1838. }else{
  1839. currentCompositionNum++;
  1840. extrasInstance.setTimeout(iterateNextComposition,100);
  1841. }
  1842. }
  1843. function searchCompositionDuplicate(layerInfo){
  1844. var i=0,len = duplicatedSources.length;
  1845. while(i<len){
  1846. if(duplicatedSources[i].s == layerInfo.source){
  1847. return duplicatedSources[i].c;
  1848. }
  1849. i++;
  1850. }
  1851. var copy = layerInfo.source.duplicate();
  1852. UI.setExportText('Duplicating: '+layerInfo.name);
  1853. //copy.openInViewer() ;
  1854. duplicatedSources.push({s:layerInfo.source,c:copy});
  1855. return copy;
  1856. }
  1857. function searchConvertedSource(source){
  1858. var i = 0, len = convertedSources.length;
  1859. while(i<len){
  1860. if(source == convertedSources[i].c){
  1861. return convertedSources[i].r;
  1862. }
  1863. i++;
  1864. }
  1865. return null;
  1866. }
  1867. function waitForRenderDone(){
  1868. if(checkRender()){
  1869. replaceCurrentLayer();
  1870. currentLayerNum++;
  1871. extrasInstance.setTimeout(verifyNextItem,100);
  1872. }else{
  1873. extrasInstance.setTimeout(waitForRenderDone,100);
  1874. }
  1875. }
  1876. function checkRender(){
  1877. if(rqManager.getStatus() == RQItemStatus.DONE){
  1878. return true;
  1879. }
  1880. return false;
  1881. }
  1882. function replaceCurrentLayerSource(source){
  1883. var layerInfo = currentComposition.layers[currentLayerNum+1];
  1884. layerInfo.replaceSource(source, false);
  1885. }
  1886. function replaceCurrentLayer(){
  1887. var myFile = rqManager.getFile();
  1888. var myImportOptions = new ImportOptions();
  1889. myImportOptions.file = myFile;
  1890. var myFootage =app.project.importFile(myImportOptions);
  1891. myFootage.parentFolder = helperFolder;
  1892. convertedSources.push({c:currentSource,r:myFootage});
  1893. AssetsManager.createLayerSource(myFile,currentLayerInfo,currentSource);
  1894. //currentLayerInfo.replaceSource(myFootage, false); //NOT REPLACING FOOTAGE. NOT SURE IF NEEDED.
  1895. if(tempConverterComp!=null){
  1896. tempConverterComp.remove();
  1897. }
  1898. }
  1899. function setCallback(cb){
  1900. callback = cb;
  1901. }
  1902. var ob = {};
  1903. ob.convertComposition = convertComposition;
  1904. ob.setCallback = setCallback;
  1905. LayerConverter = ob;
  1906. }());
  1907. /****** END LayerConverter ******/
  1908. /****** INIT shapesParser ******/
  1909. (function (){
  1910. var currentShape;
  1911. var currentOb;
  1912. var currentFrame;
  1913. function parsePaths(paths,array,lastData,time){
  1914. var i, len = paths.length;
  1915. var frames =[];
  1916. var framesI =[];
  1917. var framesO =[];
  1918. var framesV =[];
  1919. for(i=0;i<len;i+=1){
  1920. var path = paths[i].property('Path').valueAtTime(time,false);
  1921. var frame = {};
  1922. var frameI = {};
  1923. var frameO = {};
  1924. var frameV = {};
  1925. frame.v = extrasInstance.roundNumber(path.vertices,3);
  1926. frame.i = extrasInstance.roundNumber(path.inTangents,3);
  1927. frame.o = extrasInstance.roundNumber(path.outTangents,3);
  1928. frameI = extrasInstance.roundNumber(path.inTangents,3);
  1929. frameO = extrasInstance.roundNumber(path.outTangents,3);
  1930. frameV = extrasInstance.roundNumber(path.vertices,3);
  1931. frames .push(frame);
  1932. framesI .push(frameI);
  1933. framesO .push(frameO);
  1934. framesV .push(frameV);
  1935. }
  1936. /*if(lastData.path == null || extrasInstance.compareObjects(lastData.path,frames) == false){
  1937. array[currentFrame]=frames;
  1938. lastData.path = frames;
  1939. }*/
  1940. if(lastData.pathI == null || extrasInstance.compareObjects(lastData.pathI,framesI) == false){
  1941. array.i[currentFrame]=framesI;
  1942. lastData.pathI = framesI;
  1943. }
  1944. if(lastData.pathO == null || extrasInstance.compareObjects(lastData.pathO,framesO) == false){
  1945. array.o[currentFrame]=framesO;
  1946. lastData.pathO = framesO;
  1947. }
  1948. if(lastData.pathV== null || extrasInstance.compareObjects(lastData.pathV,framesV) == false){
  1949. array.v[currentFrame]=framesV;
  1950. lastData.pathV = framesV;
  1951. }
  1952. }
  1953. function parseStar(){
  1954. }
  1955. function parseRect(info,array, lastData, time){
  1956. //Todo Use this when property has expressions
  1957. return;
  1958. var frame = {};
  1959. frame.size = info.property('Size').valueAtTime(time,false);
  1960. frame.p = extrasInstance.roundNumber(info.property('Position').valueAtTime(time,false),3);
  1961. frame.roundness = extrasInstance.roundNumber(info.property('Roundness').valueAtTime(time,false),3);
  1962. if(lastData.rect == null || extrasInstance.compareObjects(lastData.rect,frame) == false){
  1963. array[currentFrame]=frame;
  1964. lastData.rect = frame;
  1965. }else{
  1966. //array.push(new Object());
  1967. }
  1968. }
  1969. function parseEllipse(info,array, lastData, time){
  1970. //Todo Use this when property has expressions
  1971. return;
  1972. var frame = {};
  1973. frame.size = info.property('Size').valueAtTime(time,false);
  1974. frame.p = extrasInstance.roundNumber(info.property('Position').valueAtTime(time,false),3);
  1975. if(lastData.rect == null || extrasInstance.compareObjects(lastData.rect,frame) == false){
  1976. array[currentFrame]=frame;
  1977. lastData.rect = frame;
  1978. }else{
  1979. //array.push(new Object());
  1980. }
  1981. return frame.size;
  1982. }
  1983. function parseStroke(info,array, lastData, time){
  1984. //Todo Use this when property has expressions
  1985. return;
  1986. var frame = {};
  1987. var color = info.property('Color').valueAtTime(time,false);
  1988. frame.color =extrasInstance.rgbToHex(Math.round(color[0]*255),Math.round(color[1]*255),Math.round(color[2]*255));
  1989. frame.opacity = extrasInstance.roundNumber(info.property('Opacity').valueAtTime(time,false),3);
  1990. frame.width = info.property('Stroke Width').valueAtTime(time,false);
  1991. if(lastData.stroke == null || extrasInstance.compareObjects(lastData.stroke,frame) == false){
  1992. array[currentFrame]=frame;
  1993. lastData.stroke = frame;
  1994. }else{
  1995. //array.push(new Object());
  1996. }
  1997. }
  1998. function parseFill(info,array, lastData, time){
  1999. //Todo Use this when property has expressions
  2000. return;
  2001. var frame = {};
  2002. var color = info.property('Color').valueAtTime(time,false);
  2003. frame.color =extrasInstance.rgbToHex(Math.round(color[0]*255),Math.round(color[1]*255),Math.round(color[2]*255));
  2004. frame.opacity = extrasInstance.roundNumber(info.property('Opacity').valueAtTime(time,false),3);
  2005. if(lastData.fill == null || extrasInstance.compareObjects(lastData.fill,frame) == false){
  2006. array[currentFrame]=frame;
  2007. lastData.fill = frame;
  2008. }else{
  2009. //array.push(new Object());
  2010. }
  2011. }
  2012. function parseTransform(info,array, lastData, time){
  2013. //Todo Use this when property has expressions
  2014. return;
  2015. var frame = {};
  2016. frame.p = extrasInstance.roundNumber(info.property('Position').valueAtTime(time,false),3);
  2017. frame.a = extrasInstance.roundNumber(info.property('Anchor Point').valueAtTime(time,false),3);
  2018. frame.s = [];
  2019. frame.s[0] = extrasInstance.roundNumber(info.property('Scale').valueAtTime(time,false)[0]/100,3);
  2020. frame.s[1] = extrasInstance.roundNumber(info.property('Scale').valueAtTime(time,false)[1]/100,3);
  2021. frame.r = extrasInstance.roundNumber(info.property('Rotation').valueAtTime(time,false)*Math.PI/180,3);
  2022. frame.o = extrasInstance.roundNumber(info.property('Opacity').valueAtTime(time,false),3);
  2023. if(lastData.transform == null || extrasInstance.compareObjects(lastData.transform,frame) == false){
  2024. array[currentFrame]=frame;
  2025. lastData.transform = frame;
  2026. }else{
  2027. //array.push(new Object());
  2028. }
  2029. }
  2030. function parseTrim(info,trim,lastData,time){
  2031. //Todo Use this when property has expressions
  2032. return;
  2033. var frame = {};
  2034. var trimS = extrasInstance.roundNumber(info.property('Start').valueAtTime(time,false),3);
  2035. var trimE = extrasInstance.roundNumber(info.property('End').valueAtTime(time,false),3);
  2036. var trimO = extrasInstance.roundNumber(info.property('Offset').valueAtTime(time,false),3);
  2037. if(lastData.trimS == null || extrasInstance.compareObjects(trimS,lastData.trimS)==false){
  2038. trim.s[currentFrame] = trimS;
  2039. lastData.trimS = trimS;
  2040. }
  2041. if(lastData.trimE == null || extrasInstance.compareObjects(trimE,lastData.trimE)==false){
  2042. trim.e[currentFrame] = trimE;
  2043. lastData.trimE = trimE;
  2044. }
  2045. if(lastData.trimO == null || extrasInstance.compareObjects(trimO ,lastData.trimO )==false){
  2046. trim.o[currentFrame] = trimO ;
  2047. lastData.trimO = trimO ;
  2048. }
  2049. }
  2050. function parseShape(shapeInfo, shapeOb, time){
  2051. //iterateProperty(shapeInfo,0);
  2052. var shapeContents = shapeInfo.property('Contents');
  2053. var paths = [];
  2054. var numProperties = shapeContents.numProperties;
  2055. for(var i = 0;i<numProperties;i+=1){
  2056. if(shapeContents(i+1).matchName == 'ADBE Vector Shape - Group'){
  2057. paths.push(shapeContents(i+1));
  2058. }
  2059. }
  2060. if(shapeContents.property('ADBE Vector Graphic - Stroke')){
  2061. parseStroke(shapeContents.property('ADBE Vector Graphic - Stroke'),shapeOb.an.stroke, shapeOb.lastData, time);
  2062. }
  2063. if(shapeContents.property('ADBE Vector Graphic - Fill')){
  2064. parseFill(shapeContents.property('ADBE Vector Graphic - Fill'),shapeOb.an.fill, shapeOb.lastData, time);
  2065. }
  2066. if(paths.length>0){
  2067. if(shapeOb.an.path){
  2068. parsePaths(paths,shapeOb.an.path, shapeOb.lastData, time);
  2069. }
  2070. }
  2071. if(shapeContents.property('ADBE Vector Shape - Rect')){
  2072. parseRect(shapeContents.property('ADBE Vector Shape - Rect'),shapeOb.an.rect, shapeOb.lastData, time);
  2073. }
  2074. if(shapeContents.property('ADBE Vector Shape - Ellipse')){
  2075. parseEllipse(shapeContents.property('ADBE Vector Shape - Ellipse'),shapeOb.an.ell, shapeOb.lastData, time);
  2076. }
  2077. if(shapeContents.property('ADBE Vector Filter - Trim')){
  2078. parseTrim(shapeContents.property('ADBE Vector Filter - Trim'),shapeOb.trim, shapeOb.lastData, time);
  2079. }
  2080. parseTransform(shapeInfo.property('Transform'),shapeOb.an.tr, shapeOb.lastData, time);
  2081. }
  2082. function addFrameData(layerInfo,layerOb, frameNum, time){
  2083. currentFrame = frameNum;
  2084. var contents = layerInfo.property('Contents');
  2085. /** Todo Use for expressions
  2086. if(contents.property('ADBE Vector Filter - Trim')){
  2087. var trim = layerOb.trim;
  2088. var trimS = extrasInstance.roundNumber(contents.property('ADBE Vector Filter - Trim').property('Start').valueAtTime(time,false),3);
  2089. var trimE = extrasInstance.roundNumber(contents.property('ADBE Vector Filter - Trim').property('End').valueAtTime(time,false),3);
  2090. var trimO = extrasInstance.roundNumber(contents.property('ADBE Vector Filter - Trim').property('Offset').valueAtTime(time,false),3);
  2091. if(layerOb.lastData.trimS == null || extrasInstance.compareObjects(trimS,layerOb.lastData.trimS)==false){
  2092. trim.s[currentFrame] = trimS;
  2093. layerOb.lastData.trimS = trimS;
  2094. }
  2095. if(layerOb.lastData.trimE == null || extrasInstance.compareObjects(trimE,layerOb.lastData.trimE)==false){
  2096. trim.e[currentFrame] = trimE;
  2097. layerOb.lastData.trimE = trimE;
  2098. }
  2099. if(layerOb.lastData.trimO == null || extrasInstance.compareObjects(trimO ,layerOb.lastData.trimO )==false){
  2100. trim.o[currentFrame] = trimO ;
  2101. layerOb.lastData.trimO = trimO ;
  2102. }
  2103. }
  2104. **/
  2105. var shapes = layerOb.shapes;
  2106. var i,len = shapes.length;
  2107. for(i=0;i<len;i++){
  2108. parseShape(contents.property(shapes[i].name), shapes[i], time);
  2109. }
  2110. }
  2111. function iterateProperties(iteratable,array,frameRate){
  2112. var i, len = iteratable.numProperties;
  2113. var ob, prop;
  2114. for(i=0;i<len;i+=1){
  2115. prop = iteratable.property(i+1);
  2116. if(!prop.enabled){
  2117. continue;
  2118. }
  2119. var itemType = getItemType(prop.matchName);
  2120. if(itemType == 'sh'){
  2121. ob = {};
  2122. ob.ty = itemType;
  2123. ob.closed = prop.property('Path').value.closed;
  2124. extrasInstance.convertToBezierValues(prop.property('Path'), frameRate, ob,'ks');
  2125. array.push(ob);
  2126. }else if(itemType == 'rc'){
  2127. ob = {};
  2128. ob.ty = itemType;
  2129. extrasInstance.convertToBezierValues(prop.property('Size'), frameRate, ob,'s');
  2130. extrasInstance.convertToBezierValues(prop.property('Position'), frameRate, ob,'p');
  2131. extrasInstance.convertToBezierValues(prop.property('Roundness'), frameRate, ob,'r');
  2132. array.push(ob);
  2133. }else if(itemType == 'el'){
  2134. ob = {};
  2135. ob.ty = itemType;
  2136. extrasInstance.convertToBezierValues(prop.property('Size'), frameRate, ob,'s');
  2137. extrasInstance.convertToBezierValues(prop.property('Position'), frameRate, ob,'p');
  2138. array.push(ob);
  2139. }else if(itemType == 'fl'){
  2140. ob = {};
  2141. ob.ty = itemType;
  2142. ob.fillEnabled = prop.enabled;
  2143. extrasInstance.convertToBezierValues(prop.property('Color'), frameRate, ob,'c');
  2144. extrasInstance.convertToBezierValues(prop.property('Opacity'), frameRate, ob,'o');
  2145. array.push(ob);
  2146. }else if(itemType == 'st'){
  2147. ob = {};
  2148. ob.ty = itemType;
  2149. ob.fillEnabled = prop.enabled;
  2150. extrasInstance.convertToBezierValues(prop.property('Color'), frameRate, ob,'c');
  2151. extrasInstance.convertToBezierValues(prop.property('Opacity'), frameRate, ob,'o');
  2152. extrasInstance.convertToBezierValues(prop.property('Stroke Width'), frameRate, ob,'w');
  2153. var j, jLen = prop.property('Dashes').numProperties;
  2154. var dashesData = [];
  2155. var changed = false;
  2156. for(j=0;j<jLen;j+=1){
  2157. if(prop.property('Dashes').property(j+1).numKeys > 0 || (prop.property('Dashes').property(j+1).name == 'Offset' && changed)) {
  2158. changed = true;
  2159. var dashData = {};
  2160. var name = '';
  2161. if(prop.property('Dashes').property(j+1).name == 'Dash'){
  2162. name = 'd';
  2163. }else if(prop.property('Dashes').property(j+1).name == 'Gap'){
  2164. name = 'g';
  2165. }else if(prop.property('Dashes').property(j+1).name == 'Offset'){
  2166. name = 'o';
  2167. }
  2168. dashData.n = name;
  2169. extrasInstance.convertToBezierValues(prop.property('Dashes').property(j+1), frameRate, dashData,'v');
  2170. dashesData.push(dashData)
  2171. }
  2172. /*$.writeln('matchName: ',prop.property('Dashes').property(j+1).matchName);
  2173. $.writeln('value: ',prop.property('Dashes').property(j+1).value);
  2174. $.writeln('enabled: ',prop.property('Dashes').property(j+1).enabled);*/
  2175. }
  2176. if(changed){
  2177. ob.d = dashesData;
  2178. }
  2179. //extrasInstance.iterateProperty(prop);
  2180. array.push(ob);
  2181. }else if(itemType == 'mm'){
  2182. ob = {};
  2183. ob.ty = itemType;
  2184. ob.mm = prop.property('ADBE Vector Merge Type').value;
  2185. array.push(ob);
  2186. }else if(itemType == 'tm'){
  2187. ob = {};
  2188. ob.ty = itemType;
  2189. extrasInstance.convertToBezierValues(prop.property('Start'), frameRate, ob,'s');
  2190. extrasInstance.convertToBezierValues(prop.property('End'), frameRate, ob,'e');
  2191. extrasInstance.convertToBezierValues(prop.property('Offset'), frameRate, ob,'o');
  2192. ob.m = prop.property('Trim Multiple Shapes').value;
  2193. //extrasInstance.iterateProperty(prop);
  2194. array.push(ob);
  2195. }else if(itemType == 'gr'){
  2196. ob = {
  2197. ty : itemType,
  2198. it: []
  2199. };
  2200. iterateProperties(prop.property('Contents'),ob.it,frameRate);
  2201. var trOb = {};
  2202. var transformProperty = prop.property('Transform');
  2203. trOb.ty = 'tr';
  2204. extrasInstance.convertToBezierValues(transformProperty.property('Position'), frameRate, trOb,'p');
  2205. extrasInstance.convertToBezierValues(transformProperty.property('Anchor Point'), frameRate, trOb,'a');
  2206. extrasInstance.convertToBezierValues(transformProperty.property('Scale'), frameRate, trOb,'s');
  2207. extrasInstance.convertToBezierValues(transformProperty.property('Rotation'), frameRate, trOb,'r');
  2208. extrasInstance.convertToBezierValues(transformProperty.property('Opacity'), frameRate, trOb,'o');
  2209. ob.it.push(trOb);
  2210. array.push(ob);
  2211. }
  2212. }
  2213. }
  2214. function createShapes(layerInfo,layerOb, frameRate){
  2215. var shapes = [];
  2216. layerOb.shapes = shapes;
  2217. var contents = layerInfo.property('Contents');
  2218. iterateProperties(contents,shapes,frameRate);
  2219. }
  2220. function getItemType(matchName){
  2221. //$.writeln('matchName: ',matchName);
  2222. switch(matchName){
  2223. case 'ADBE Vector Shape - Group':
  2224. return 'sh';
  2225. case 'ADBE Vector Shape - Rect':
  2226. return 'rc';
  2227. case 'ADBE Vector Shape - Ellipse':
  2228. return 'el';
  2229. case 'ADBE Vector Graphic - Fill':
  2230. return 'fl';
  2231. case 'ADBE Vector Graphic - Stroke':
  2232. return 'st';
  2233. case 'ADBE Vector Graphic - Merge':
  2234. return 'mm';
  2235. case 'ADBE Vector Graphic - Trim':
  2236. case 'ADBE Vector Filter - Trim':
  2237. return 'tm';
  2238. case 'ADBE Vector Group':
  2239. return 'gr';
  2240. default:
  2241. //$.writeln('unsupported: ',matchName);
  2242. return '';
  2243. }
  2244. }
  2245. var ob = {};
  2246. ob.createShapes = createShapes;
  2247. ob.addFrameData = addFrameData;
  2248. ShapesParser = ob;
  2249. }());
  2250. /****** END shapesParser ******/
  2251. /****** INIT CompConverter ******/
  2252. (function(){
  2253. var isExportDirectoryCreated = false;
  2254. var directoryCreationFailed = false;
  2255. var compositionsList;
  2256. var currentCompositionData;
  2257. var filesDirectory;
  2258. var mainProject = app.project;
  2259. var scriptPath = ((File($.fileName)).path);
  2260. var mainComp;
  2261. var endCallback;
  2262. var compositionData = {};
  2263. function saveData(){
  2264. if(!renderCancelled){
  2265. var dataFile = new File(exportFolder.fullName+'/data.json');
  2266. dataFile.open('w','TEXT','????');
  2267. var string = JSON.stringify(compositionData);
  2268. string = string.replace(/\n/g,'') ;
  2269. dataFile.write(string); //DO NOT ERASE, JSON UNFORMATTED
  2270. //dataFile.write(JSON.stringify(compositionData, null, ' ')); //DO NOT ERASE, JSON FORMATTED
  2271. dataFile.close();
  2272. }
  2273. currentCompositionData.rendered = true;
  2274. searchNextComposition();
  2275. }
  2276. function layersConverted(duplicateMainComp){
  2277. DOMAnimationManager.setCallback(saveData);
  2278. //FOR DOM
  2279. DOMAnimationManager.getCompositionAnimationData(duplicateMainComp,compositionData,filesDirectory);
  2280. }
  2281. function animationSaved(){
  2282. saveData();
  2283. }
  2284. function directoryRemoved(){
  2285. filesDirectory = new Folder(exportFolder.fullName+'/files');
  2286. if(filesDirectory.create()){
  2287. isExportDirectoryCreated = true;
  2288. }
  2289. }
  2290. function createExportDirectory(){
  2291. exportFolder = new Folder(currentCompositionData.destination+'/'+currentCompositionData.comp.name+'/');
  2292. filesDirectory = new Folder(exportFolder.fullName+'/files');
  2293. if(filesDirectory.exists){
  2294. isExportDirectoryCreated = true;
  2295. }else{
  2296. if(filesDirectory.create()){
  2297. isExportDirectoryCreated = true;
  2298. }else{
  2299. directoryCreationFailed = true;
  2300. }
  2301. }
  2302. }
  2303. function waitForDirectoryCreated(){
  2304. if(isExportDirectoryCreated){
  2305. start();
  2306. }else if(directoryCreationFailed){
  2307. alert(UITextsData.alertMessages.directoryCreationFailed);
  2308. }else{
  2309. $.sleep(100);
  2310. waitForDirectoryCreated();
  2311. }
  2312. }
  2313. function searchHelperRenderer(helperComp){
  2314. var i=0,len = app.project.renderQueue.items.length;
  2315. var item;
  2316. while(i<len){
  2317. item = app.project.renderQueue.items[i+1];
  2318. if(item.comp == helperComp){
  2319. return item;
  2320. }
  2321. i++;
  2322. }
  2323. }
  2324. function start(){
  2325. UI.setExportText('Starting export');
  2326. LayerConverter.convertComposition(mainComp);
  2327. }
  2328. function exportNextComposition(){
  2329. isExportDirectoryCreated = false;
  2330. directoryCreationFailed = false;
  2331. mainComp = currentCompositionData.comp;
  2332. createExportDirectory();
  2333. waitForDirectoryCreated();
  2334. }
  2335. function searchNextComposition(){
  2336. if(!renderCancelled){
  2337. var len = compositionsList.length;
  2338. var i = 0;
  2339. while(i < len){
  2340. if(compositionsList[i].queued === true && compositionsList[i].rendered == false){
  2341. currentCompositionData = compositionsList[i];
  2342. exportNextComposition();
  2343. return;
  2344. }
  2345. i+=1;
  2346. }
  2347. }
  2348. //If it gets here there are no more compositions to render and callback is executed
  2349. helperFootage.remove();
  2350. endCallback.apply();
  2351. }
  2352. function renderCompositions(list){
  2353. var helperFile = new File(scriptPath+'/helperProject.aep');
  2354. var helperImportOptions = new ImportOptions();
  2355. helperImportOptions.file = helperFile;
  2356. helperFootage = mainProject.importFile(helperImportOptions);
  2357. var i=0, len = helperFootage.items.length;
  2358. var helperFolder;
  2359. while(i<len){
  2360. if(extrasInstance.getprojectItemType(helperFootage.item(i+1)) == 'Folder'){
  2361. helperFolder = helperFootage.item(i+1);
  2362. break;
  2363. }
  2364. i += 1;
  2365. }
  2366. i = 0;
  2367. len = helperFolder.items.length;
  2368. while(i<len){
  2369. if(helperFolder.item(i+1).name == 'helperSolidComp'){
  2370. helperSolidComp = helperFolder.item(i+1);
  2371. }
  2372. i += 1;
  2373. }
  2374. helperSolid = helperSolidComp.layer(1);
  2375. var helperPosition = helperSolid.transform["Anchor Point"];
  2376. helperPosition.expression = "valueAtTime(time)";
  2377. rqManager.setProject(app.project);
  2378. LayerConverter.setCallback(layersConverted);
  2379. compositionsList = list;
  2380. len = compositionsList.length;
  2381. for(i=0;i<len;i+=1){
  2382. compositionsList[i].rendered = false;
  2383. }
  2384. searchNextComposition();
  2385. }
  2386. function setFinishCallback(cb){
  2387. endCallback = cb;
  2388. }
  2389. var ob = {};
  2390. ob.renderCompositions = renderCompositions;
  2391. ob.setFinishCallback = setFinishCallback;
  2392. CompConverter = ob;
  2393. }());
  2394. /****** END CompConverter ******/
  2395. (function(){
  2396. var UITextsData = {
  2397. generalButtons : {render:'Render'},
  2398. alertMessages : {
  2399. noComps:'You don\'t have compositions to render',
  2400. directoryCreationFailed:'Error trying to create directory'
  2401. },
  2402. tabs : {comps:'Compositions',images:'Images'},
  2403. compsButtons : {add:'Add to render queue',remove:'Remove from render queue',destination:'Destination Folder',refresh:'Refresh'},
  2404. compsColumns : {name:'Name',queue:'In Queue',destination:'Destination Path'},
  2405. imagesButtons : {refresh:'Refresh', exportTxt:'Export', notExportTxt:'Do not export'},
  2406. imagesColumns : {name:'Name',exportTxt:'Export'},
  2407. renderTexts : {cancel:'Cancel Render'}
  2408. }
  2409. var availableCompositions = [];
  2410. var bodyMovinPanel;
  2411. var settingsGroup;
  2412. var renderGroup;
  2413. var compsList;
  2414. var imagesList;
  2415. var compTab;
  2416. var imagesTab;
  2417. var compsSelectionButton;
  2418. var compsDestinationButton;
  2419. var imagesCompsDropDown;
  2420. var toggleImagesExportButton;
  2421. var isPanelFocused = false;
  2422. var ignoreEvent = true;
  2423. function myScript_buildUI(thisObj){
  2424. bodyMovinPanel = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Body Movin Exporter", undefined, {resizeable:true});
  2425. ////bodyMovinPanel.addEventListener('focus', panelFocusHandler, true);
  2426. bodyMovinPanel.onActivate = panelFocusHandler;
  2427. ////bodyMovinPanel.addEventListener('blur', panelBlurHandler, true);
  2428. bodyMovinPanel.onDeactivate = panelBlurHandler;
  2429. ////bodyMovinPanel.addEventListener('close',closePanel);
  2430. bodyMovinPanel.onClose = closePanel;
  2431. /**** WINDOW VIEW *****/
  2432. var mainGroupRes = "group{orientation:'stack',alignment:['fill','fill'],alignChildren:['fill',fill']}";
  2433. bodyMovinPanel.mainGroup = bodyMovinPanel.add(mainGroupRes);
  2434. /**** SETTINGS GROUP ****/
  2435. var settingsGroupRes = "group{orientation:'column',alignment:['fill','fill'],alignChildren:['fill',fill'],\
  2436. myTabbedPanel: Panel{type:'tabbedpanel', text:'',alignment:['fill','fill'],alignChildren:['fill',fill'],\
  2437. compTab: Panel{type:'tab', text:'"+UITextsData.tabs.comps+"',orientation:'columns',\
  2438. },\
  2439. imagesTab: Panel{type:'tab', text: '"+UITextsData.tabs.images+"',\
  2440. },\
  2441. },\
  2442. generalButtonsGroup: Group{orientation:'row',alignment:['fill','bottom'],alignChildren:['fill',fill'],\
  2443. renderButton: Button{text:'"+UITextsData.generalButtons.render+"',alignment:['right','bottom']},\
  2444. }\
  2445. }";
  2446. settingsGroup = bodyMovinPanel.mainGroup.add(settingsGroupRes);
  2447. ////settingsGroup.myTabbedPanel.addEventListener('change',tabChangedHandler);
  2448. settingsGroup.myTabbedPanel.onChange = tabChangedHandler;
  2449. ////settingsGroup.generalButtonsGroup.renderButton.addEventListener('click', startRender);
  2450. settingsGroup.generalButtonsGroup.renderButton.onClick = startRender;
  2451. /**** COMPOSITION TAB VIEW *****/
  2452. var compGroup = "Group{orientation:'column',alignment:['fill','fill'],alignChildren:['fill',fill'],\
  2453. buttonGroup: Group{orientation:'row',alignment:['fill','top'],alignChildren:['left',top'],\
  2454. compsSelectionButton: Button{text:'"+UITextsData.compsButtons.remove+"'},\
  2455. compsDestinationButton: Button{text:'"+UITextsData.compsButtons.destination+"'},\
  2456. compsRefreshButton: Button{text:'"+UITextsData.compsButtons.refresh+"',alignment:['right','top']},\
  2457. }\
  2458. list: ListBox{text:'Components List',alignment:['fill','fill'],alignChildren:['fill',fill'],\
  2459. properties:{numberOfColumns: 3,multiselect:true, showHeaders: true,columnTitles: ['"+UITextsData.compsColumns.name+"', '"+UITextsData.compsColumns.queue+"','"+UITextsData.compsColumns.destination+"']}\
  2460. }\
  2461. }";
  2462. settingsGroup.myTabbedPanel.compTab.compGroup = settingsGroup.myTabbedPanel.compTab.add(compGroup);
  2463. compsList = settingsGroup.myTabbedPanel.compTab.compGroup.list;
  2464. compsSelectionButton = settingsGroup.myTabbedPanel.compTab.compGroup.buttonGroup.compsSelectionButton;
  2465. compsDestinationButton = settingsGroup.myTabbedPanel.compTab.compGroup.buttonGroup.compsDestinationButton;
  2466. ////compsSelectionButton.addEventListener('click',compRenderButtonClickHandler);
  2467. compsSelectionButton.onClick = compRenderButtonClickHandler;
  2468. ////compsDestinationButton.addEventListener('click',compDestinationButtonClickHandler);
  2469. compsDestinationButton.onClick = compDestinationButtonClickHandler;
  2470. ////settingsGroup.myTabbedPanel.compTab.compGroup.buttonGroup.compsRefreshButton.addEventListener('click',compRefreshButtonClickHandler);
  2471. settingsGroup.myTabbedPanel.compTab.compGroup.buttonGroup.compsRefreshButton.onClick = compRefreshButtonClickHandler;
  2472. compsSelectionButton.hide();
  2473. compsDestinationButton.hide();
  2474. ////compsList.addEventListener('change',listChangeHandler);
  2475. compsList.onChange = listChangeHandler;
  2476. /**** IMAGES TAB VIEW *****/
  2477. var imagesGroup = "Group{orientation:'column',alignment:['fill','fill'],alignChildren:['fill',fill'],\
  2478. optionsGroup: Group{orientation:'row',alignment:['fill','top'],alignChildren:['left',top'],\
  2479. whichCompo : DropDownList { alignment:'left',properties: {items: ['Dummy text']} }, \
  2480. toggleExportButton: Button{text:'"+UITextsData.imagesButtons.notExportTxt+"',alignment:['right','top']},\
  2481. refreshButton: Button{text:'"+UITextsData.imagesButtons.refresh+"',alignment:['right','top']},\
  2482. }\
  2483. list: ListBox{text:'Images List',alignment:['fill','fill'],alignChildren:['fill',fill'],\
  2484. properties:{numberOfColumns: 2,multiselect:true, showHeaders: true,columnTitles: ['"+UITextsData.imagesColumns.name+"', '"+UITextsData.imagesColumns.exportTxt+"']}\
  2485. }\
  2486. }";
  2487. settingsGroup.myTabbedPanel.imagesTab.imagesGroup = settingsGroup.myTabbedPanel.imagesTab.add(imagesGroup);
  2488. imagesCompsDropDown = settingsGroup.myTabbedPanel.imagesTab.imagesGroup.optionsGroup.whichCompo;
  2489. toggleImagesExportButton = settingsGroup.myTabbedPanel.imagesTab.imagesGroup.optionsGroup.toggleExportButton;
  2490. toggleImagesExportButton.hide();
  2491. //toggleImagesExportButton.addEventListener('click',toggleExportImagesHandler);
  2492. imagesList = settingsGroup.myTabbedPanel.imagesTab.imagesGroup.list;
  2493. //imagesList.addEventListener('change',imagesListChangeHandler);
  2494. //imagesCompsDropDown.addEventListener('change',imagesCompsDDChangeHandler);
  2495. //settingsGroup.myTabbedPanel.imagesTab.imagesGroup.optionsGroup.refreshButton.addEventListener('click',imagesRefreshButtonClickHandler);
  2496. /**** RENDER GROUP ****/
  2497. var renderGroupRes = "group{orientation:'column',alignment:['fill','fill'],alignChildren:['fill',fill'],\
  2498. componentText:StaticText{text:'Rendering Composition ',alignment:['left','top']},\
  2499. infoText:StaticText{text:'Exporting images ',alignment:['fill','top']},\
  2500. progress:Progressbar{value:50,alignment:['fill','top']},\
  2501. cancelButton: Button{text:'"+UITextsData.renderTexts.cancel+"',alignment:['center','top']},\
  2502. }";
  2503. bodyMovinPanel.mainGroup.renderGroup = bodyMovinPanel.mainGroup.add(renderGroupRes);
  2504. renderGroup = bodyMovinPanel.mainGroup.renderGroup;
  2505. ////renderGroup.cancelButton.addEventListener('click',cancelRender);
  2506. renderGroup.cancelButton.onClick = cancelRender;
  2507. renderGroup.hide();
  2508. bodyMovinPanel.layout.layout(true);
  2509. settingsGroup.minimumSize = settingsGroup.size;
  2510. bodyMovinPanel.onResizing = bodyMovinPanel.onResize = function () { this.layout.resize(); }
  2511. //panelManager.setPanel(bodyMovinPanel);
  2512. settingsGroup.myTabbedPanel.imagesTab.enabled = false;
  2513. settingsGroup.myTabbedPanel.imagesTab.hide();
  2514. return bodyMovinPanel;
  2515. }
  2516. function closePanel(){
  2517. bodyMovinPanel.removeEventListener('focus', panelFocusHandler);
  2518. bodyMovinPanel.removeEventListener('blur', panelBlurHandler);
  2519. bodyMovinPanel.removeEventListener('close',closePanel);
  2520. settingsGroup.myTabbedPanel.removeEventListener('change',tabChangedHandler);
  2521. settingsGroup.generalButtonsGroup.renderButton.removeEventListener('click', startRender);
  2522. compsSelectionButton.removeEventListener('click',compRenderButtonClickHandler);
  2523. compsDestinationButton.removeEventListener('click',compDestinationButtonClickHandler);
  2524. compsList.removeEventListener('change',listChangeHandler);
  2525. //toggleImagesExportButton.removeEventListener('click',toggleExportImagesHandler);
  2526. //imagesList.removeEventListener('change',imagesListChangeHandler);
  2527. //imagesCompsDropDown.removeEventListener('change',imagesCompsDDChangeHandler);
  2528. //settingsGroup.myTabbedPanel.imagesTab.imagesGroup.optionsGroup.refreshButton.removeEventListener('click',imagesRefreshButtonClickHandler);
  2529. renderGroup.cancelButton.removeEventListener('click',cancelRender);
  2530. settingsGroup.myTabbedPanel.compTab.compGroup.buttonGroup.compsRefreshButton.removeEventListener('click',compRefreshButtonClickHandler);
  2531. bodyMovinPanel.onResizing = bodyMovinPanel.onResize = null;
  2532. }
  2533. function panelFocusHandler(ev){
  2534. if(app.project === null || app.project === undefined){
  2535. return;
  2536. }
  2537. if(isPanelFocused === true){
  2538. return;
  2539. }
  2540. isPanelFocused = true;
  2541. tabChangedHandler(null); //Uncomment this por production
  2542. }
  2543. function panelBlurHandler(ev){
  2544. if(isPanelFocused === false){
  2545. return;
  2546. }
  2547. isPanelFocused = false;
  2548. }
  2549. function setProgress(value){
  2550. renderGroup.progress.value = (1 - value)*100;
  2551. renderGroup.infoText.text = ((1 - value)*100).toFixed(2) + '%';
  2552. }
  2553. function cancelRender(){
  2554. renderCancelled = true;
  2555. renderFinished();
  2556. }
  2557. function renderFinished(){
  2558. renderGroup.hide();
  2559. settingsGroup.show();
  2560. //app.endUndoGroup();
  2561. }
  2562. function startRender(){
  2563. renderCancelled = false;
  2564. var foundComps = false,i=0, len = availableCompositions.length;
  2565. while(i<len){
  2566. if(availableCompositions[i].queued){
  2567. foundComps = true;
  2568. getCompositionImages(availableCompositions[i]);
  2569. }
  2570. i+=1;
  2571. }
  2572. if(foundComps === false){
  2573. alert(UITextsData.alertMessages.noComps);
  2574. return;
  2575. }
  2576. //TODO handle full undo
  2577. //app.beginUndoGroup("Undo Render");
  2578. renderGroup.show();
  2579. settingsGroup.hide();
  2580. CompConverter.setFinishCallback(renderFinished);
  2581. CompConverter.renderCompositions(availableCompositions);
  2582. }
  2583. function getCompositionImages(compositionData){
  2584. if(compositionData.exportableImages === null || compositionData.exportableImages === undefined){
  2585. compositionData.exportableImages = [];
  2586. }
  2587. addImagesFromComposition(compositionData.comp,compositionData.exportableImages);
  2588. }
  2589. function addImagesFromComposition(compo,imagesList){
  2590. var i, len = compo.layers.length;
  2591. for(i = 0;i<len;i+=1){
  2592. var layerInfo = compo.layers[i+1];
  2593. var lType = extrasInstance.layerType(layerInfo);
  2594. if(lType == 'StillLayer'){
  2595. addLayerToImagesList(layerInfo,imagesList);
  2596. }else if(lType == 'PreCompLayer'){
  2597. addImagesFromComposition(layerInfo.source,imagesList);
  2598. }
  2599. }
  2600. }
  2601. function addLayerToImagesList(layer,list){
  2602. var i = 0, len = list.length, existingItem= null;
  2603. while(i<len){
  2604. if(list[i].item === layer){
  2605. existingItem = list.splice(i,1)[0];
  2606. break;
  2607. }
  2608. i+=1;
  2609. }
  2610. var listItem;
  2611. if(existingItem === null){
  2612. listItem = {item: layer, exportable: true, uiItem: null};
  2613. }else{
  2614. listItem = {item:layer, exportable:existingItem.exportable,uiItem:null}
  2615. }
  2616. list.push(listItem);
  2617. }
  2618. function tabChangedHandler(ev){
  2619. if(!settingsGroup || !settingsGroup.myTabbedPanel || !settingsGroup.myTabbedPanel.selection){
  2620. return;
  2621. }
  2622. if(ev !== null && ev.target !== settingsGroup.myTabbedPanel){
  2623. return;
  2624. }
  2625. switch(settingsGroup.myTabbedPanel.selection.text){
  2626. case UITextsData.tabs.comps:
  2627. updateCompositionsTab();
  2628. break;
  2629. case UITextsData.tabs.images:
  2630. //updateImagesTab();
  2631. break;
  2632. }
  2633. }
  2634. function compRefreshButtonClickHandler(ev){
  2635. updateCompositionsTab();
  2636. }
  2637. function compDestinationButtonClickHandler(ev){
  2638. var f = new Folder();
  2639. var outputFolder = f.selectDlg();
  2640. if(outputFolder !== null){
  2641. var selection = compsList.selection;
  2642. var i, len = selection.length;
  2643. var j, jLen = availableCompositions.length;
  2644. for(i=0;i<len;i++){
  2645. selection[i].subItems[1].text = outputFolder.absoluteURI;
  2646. j = 0;
  2647. while(j<jLen){
  2648. if(availableCompositions[j].item === selection[i]){
  2649. availableCompositions[j].destination = outputFolder.absoluteURI;
  2650. break;
  2651. }
  2652. j++;
  2653. }
  2654. }
  2655. updateCompView();
  2656. }
  2657. }
  2658. function compRenderButtonClickHandler(ev){
  2659. updateCompositionsTab();
  2660. var sendToQueue;
  2661. if(compsSelectionButton.text === UITextsData.compsButtons.add){
  2662. sendToQueue = true;
  2663. }else{
  2664. sendToQueue = false;
  2665. }
  2666. var selection = compsList.selection;
  2667. var i, len = selection.length;
  2668. var j, jLen = availableCompositions.length;
  2669. for(i=0;i<len;i++){
  2670. j = 0;
  2671. while(j<jLen){
  2672. if(availableCompositions[j].item === selection[i]){
  2673. availableCompositions[j].queued = sendToQueue;
  2674. break;
  2675. }
  2676. j++;
  2677. }
  2678. }
  2679. listChangeHandler();
  2680. }
  2681. function searchRemovedElements(){
  2682. compsList.selection = null;
  2683. compsList.removeAll();
  2684. var i=0, len = availableCompositions.length;
  2685. while(i<len){
  2686. if(!isValid(availableCompositions[i].comp)){
  2687. availableCompositions.splice(i,1);
  2688. i-=1;
  2689. len-=1;
  2690. }else{
  2691. if(!isValid(availableCompositions[i].imageDdItem)){
  2692. delete availableCompositions[i].imageDdItem;
  2693. }
  2694. }
  2695. i+=1;
  2696. }
  2697. i = 0;
  2698. var j, jLen, images;
  2699. while(i<len){
  2700. if(availableCompositions[i].exportableImages){
  2701. images = availableCompositions[i].exportableImages;
  2702. jLen = images.length;
  2703. j = 0;
  2704. while(j<jLen){
  2705. if(!isValid(images[j].item)){
  2706. images.splice(j,1);
  2707. j-=1;
  2708. jLen-=1;
  2709. }
  2710. j+=1;
  2711. }
  2712. }
  2713. i+=1;
  2714. }
  2715. }
  2716. function updateCompositionsTab(){
  2717. ignoreEvent = true;
  2718. searchRemovedElements();
  2719. var project = app.project;
  2720. var i,numItems = project.numItems;
  2721. var count = 0;
  2722. for(i=0;i<numItems;i+=1){
  2723. if(extrasInstance.getprojectItemType(project.item(i+1))=='Comp'){
  2724. addCompositionToList(project.item(i+1), count);
  2725. count+=1;
  2726. };
  2727. }
  2728. var numComps = availableCompositions.length;
  2729. for(i=0;i<numComps;i++){
  2730. availableCompositions[i].item = compsList.add('item',availableCompositions[i].comp.name);
  2731. if(availableCompositions[i].selected){
  2732. availableCompositions[i].item.selected = true;
  2733. }
  2734. }
  2735. updateCompView();
  2736. ignoreEvent = false;
  2737. }
  2738. function addCompositionToList(item,pos){
  2739. var i=0, len = availableCompositions.length, compItem = null;
  2740. while(i<len){
  2741. if(availableCompositions[i].comp === item){
  2742. compItem = availableCompositions[i];
  2743. availableCompositions.splice(i,1);
  2744. break;
  2745. }
  2746. i++;
  2747. }
  2748. if(compItem === null){
  2749. //app.project.file.path
  2750. compItem = {comp:item, queued:false, selected:false, destination: Folder.myDocuments.absoluteURI};
  2751. }
  2752. availableCompositions.splice(pos,0,compItem);
  2753. }
  2754. function listChangeHandler(ev){
  2755. if(ignoreEvent){
  2756. return;
  2757. }
  2758. var selection = compsList.selection;
  2759. if(selection===null){
  2760. compsSelectionButton.hide();
  2761. compsDestinationButton.hide();
  2762. return;
  2763. }
  2764. availableCompositions.forEach(function(compData){
  2765. compData.selected = false;
  2766. });
  2767. compsSelectionButton.show();
  2768. var i, len = selection.length;
  2769. var j, jLen = availableCompositions.length;
  2770. var areQueued = true;
  2771. selection.forEach(function(selectionItem){
  2772. j = 0;
  2773. while(j<jLen){
  2774. if(availableCompositions[j].item === selectionItem){
  2775. availableCompositions[j].selected = true;
  2776. if(availableCompositions[j].queued == false){
  2777. areQueued = false;
  2778. }
  2779. break;
  2780. }
  2781. j++;
  2782. }
  2783. });
  2784. for(i=0;i<len;i++){
  2785. j = 0;
  2786. while(j<jLen){
  2787. if(availableCompositions[j].item === selection[i]){
  2788. if(availableCompositions[j].queued == false){
  2789. areQueued = false;
  2790. }
  2791. break;
  2792. }
  2793. j++;
  2794. }
  2795. }
  2796. if(areQueued === false){
  2797. compsDestinationButton.hide();
  2798. compsSelectionButton.text = UITextsData.compsButtons.add;
  2799. }else{
  2800. compsDestinationButton.show();
  2801. compsSelectionButton.text = UITextsData.compsButtons.remove;
  2802. }
  2803. updateCompView();
  2804. }
  2805. function updateCompView(){
  2806. var i, len = availableCompositions.length;
  2807. for(i=0;i<len;i++){
  2808. compsList.items[i].subItems[0].text = availableCompositions[i].queued;
  2809. if(availableCompositions[i].queued == false){
  2810. compsList.items[i].subItems[1].text = '';
  2811. }else{
  2812. compsList.items[i].subItems[1].text = availableCompositions[i].destination;
  2813. }
  2814. }
  2815. }
  2816. function setExportText(text){
  2817. bodyMovinPanel.mainGroup.renderGroup.infoText.text = text;
  2818. }
  2819. myScript_buildUI(bodymovinWindow);
  2820. if (bodyMovinPanel != null && bodyMovinPanel instanceof Window){
  2821. bodyMovinPanel.center();
  2822. bodyMovinPanel.show();
  2823. }
  2824. var ob ={};
  2825. ob.setExportText = setExportText;
  2826. ob.setProgress = setProgress;
  2827. UI = ob;
  2828. }());
  2829. }());