//by bigxixi, contact at xixi@bigxixi.com (function ALL(thisObj) { var drawUI = UI(thisObj); if(drawUI instanceof Window){ drawUI.center(); drawUI.show(); }else{ drawUI.layout.layout(true); }; function UI(thisObj){ var version = "1.0"; var scriptName = "CSS Sprite Exporter"; var Description = "Export CSS Sprite Animation " + version; var HelpText = "This script can help generate css sprite animation from AE comps.\n" + "How to use:\n" + "1.Open a composition in AE.\n" + "2.Run the script.\n" + "3.Make some config if needed.\n" + "4.Hit generate button.\n" + "Then you will get an \"image\" folder whitch contants \n" + "the sprite image(png format) and a html page to show the animation.\n" + "You can copy the css code from the show page.\n" + "Surport transparency.\n" + "Feel free to contact me - xixi@bigxixi.com"; //draw UI var win = (thisObj instanceof Panel) ? thisObj : new Window("palette",scriptName,undefined,{resizeable:false,}); var dsp = win.add("statictext",undefined,Description); dsp.alignment = ["center","center"]; var group0 = win.add("group"); group0.orientation = "row"; var group1 = group0.add("group"); group1.orientation = "column"; group1.alignChildren = "fill"; var pal1 = group1.add("panel"); pal1.text = "Max Width(px):"; pal1.alignChildren = "fill"; var maxWidth = pal1.add("edittext",undefined,5000); var pal3 = group1.add("panel"); pal3.text = "Web Compatibility"; pal3.orientation = "column"; pal3.alignChildren = "fill"; var prefixALL = pal3.add("checkbox",undefined,"add all prefixs"); var prefix1 = pal3.add("checkbox",undefined,"add '-webkit-' prefix"); var prefix2 = pal3.add("checkbox",undefined,"add '-moz-' prefix"); var prefix3 = pal3.add("checkbox",undefined,"add '-ms-' prefix"); var prefix4 = pal3.add("checkbox",undefined,"add '-o-' prefix"); var group2 = group0.add("group"); group2.orientation = "column"; group2.alignChildren = "fill"; group2.alignment = ["right","top"]; var pal2 = group2.add("panel"); pal2.text = "Configs"; pal2.orientation = "column"; pal2.alignChildren = "fill"; var txt3 = pal2.add("statictext",undefined,"ID Name:"); var idName = pal2.add("edittext",undefined,"mySprite"); var txt4 = pal2.add("statictext",undefined,"Animation Name:"); var animationName = pal2.add("edittext",undefined,"myAnimation"); var txt5 = pal2.add("statictext",undefined,"Skip Frames:"); var skipFrame = pal2.add("edittext",undefined,0); var btnGroup = group2.add("group"); btnGroup.orientation = "row"; var btn1 = btnGroup.add("button",undefined,"Generate"); var btn2 = btnGroup.add("button",undefined,"Help"); //functions prefixALL.onClick = function(){ if(prefixALL.value == true){ prefix1.value = true; prefix2.value = true; prefix3.value = true; prefix4.value = true; } } btn1.onClick = function(){ if(!app.preferences.getPrefAsLong("Main Pref Section", "Pref_SCRIPTING_FILE_NETWORK_SECURITY")){ alert("Please check this option:\n'Preferences->General->Allow Scripts to Write Files and Access Network'"); app.executeCommand(2359); alert("Please rerun the script."); return; } if(checkInput(maxWidth.text)[0] == false){ alert("Max width input error, check it."); return; } if(skipFrame.text != 0 && checkInput(skipFrame.text)[0] == false){ alert("SkipFrame value input error, check it."); return; } if(checkInput(idName.text)[1] == false){ alert("id name error, check it."); return; } if(checkInput(animationName.text)[1] == false){ alert("animation name error, check it."); return; } GenerateSprite(); } btn2.onClick = function(){ alert(HelpText); } function GenerateSprite(){ var RQerr = "Render Error."; var endmsg = "Done! Sprite saved at:"; var savetip = "save to..."; var osSlash; if($.os.toLowerCase().indexOf("mac") == 0){ osSlash = "/"; }else{ osSlash = "\\"; } var oriComp = app.project.activeItem; var oriW = oriComp.width; var oriH = oriComp.height; var oriL = Number(oriComp.workAreaDuration).toFixed(2); var oriR = oriComp.frameRate; var theLocation = File.saveDialog(savetip); if(theLocation != null){ var aniFolder = new Folder(theLocation.path+osSlash+theLocation.name); aniFolder.create(); var imgFolder = new Folder(aniFolder.fsName+osSlash+"images"); imgFolder.create(); var htmlName = decodeURIComponent("show_page_"+theLocation.name+".html") var imgPath = decodeURIComponent("images/"+theLocation.name+".png"); theLocation = decodeURIComponent(imgFolder.fsName+osSlash+theLocation.name+".png"); var htmlPath = decodeURIComponent(aniFolder.fsName+osSlash+"index.html"); var cssCodeAni = ""; var cssCodeKeys = ""; var htmlCode; var framePosX=[],framePosY=[]; var skip = Number(skipFrame.text); var rows,columns = 1; var limitW = limitH = maxWidth.text; var imgIdName = idName.text; var aniName = animationName.text; var compR = Number(oriR/(skip+1)).toFixed(3); var compW = oriW*Math.ceil(oriL*compR); var compH = oriH; var posExp = "[thisLayer.width/2+(index-1)*thisLayer.width,value[1]]"; //keep resolution var res = [1,1]; if(oriComp.resolutionFactor != "1,1"){ res = oriComp.resolutionFactor; oriComp.resolutionFactor = [1,1]; } //calculate the size of the final img asset. if((oriW limitW)){ var alertWH = "The picture is warped due to the max width."; for(var j=0;jlimitW){ columns = j; rows = Math.ceil(Math.ceil(oriL*compR)/j); if(oriH*rows>limitH){ alertWH = "Your are generating a large pic, becareful!"; } alert(alertWH); break; } } compW = oriW*columns; compH = oriH*rows; posExp ='var columns =' + columns +';\n' + 'var rows =' + rows +';\n' + 'var x,y;\n' + 'if(index%columns == 0){\n' + ' x = thisLayer.width*(columns-0.5);\n' + '}else{\n' + ' x = thisLayer.width*(index%columns-0.5);\n' + '}\n' + 'y = thisLayer.height*(Math.ceil(index/columns)-0.5);\n' + '[x,y]\n'; } var tempComp = app.project.items.addComp('TempComp',compW,compH,1,oriL,compR); tempComp.openInViewer(); app.project.activeItem.layers.add(oriComp); app.project.activeItem.layer(1).startTime = -Number(oriComp.workAreaStart).toFixed(2); app.project.activeItem.layer(1).position.expression = posExp; for(var i=1;i0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=\"\"}},{key:\"initSelection\",value:function e(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:\"selectFake\",value:function e(){var t=this,n=\"rtl\"==document.documentElement.getAttribute(\"dir\");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=document.body.addEventListener(\"click\",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement(\"textarea\"),this.fakeElem.style.fontSize=\"12pt\",this.fakeElem.style.border=\"0\",this.fakeElem.style.padding=\"0\",this.fakeElem.style.margin=\"0\",this.fakeElem.style.position=\"absolute\",this.fakeElem.style[n?\"right\":\"left\"]=\"-9999px\";var o=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=o+\"px\",this.fakeElem.setAttribute(\"readonly\",\"\"),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()}},{key:\"removeFake\",value:function e(){this.fakeHandler&&(document.body.removeEventListener(\"click\",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)}},{key:\"selectTarget\",value:function e(){this.selectedText=(0,i.default)(this.target),this.copyText()}},{key:\"copyText\",value:function e(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:\"handleResult\",value:function e(t){this.emitter.emit(t?\"success\":\"error\",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:\"clearSelection\",value:function e(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()}},{key:\"destroy\",value:function e(){this.removeFake()}},{key:\"action\",set:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:\"copy\";if(this._action=t,\"copy\"!==this._action&&\"cut\"!==this._action)throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"')},get:function e(){return this._action}},{key:\"target\",set:function e(t){if(void 0!==t){if(!t||\"object\"!==(\"undefined\"==typeof t?\"undefined\":r(t))||1!==t.nodeType)throw new Error('Invalid \"target\" value, use a valid Element');if(\"copy\"===this.action&&t.hasAttribute(\"disabled\"))throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');if(\"cut\"===this.action&&(t.hasAttribute(\"readonly\")||t.hasAttribute(\"disabled\")))throw new Error('Invalid \"target\" attribute. You cant cut text from elements with \"readonly\" or \"disabled\" attributes');this._target=t}},get:function e(){return this._target}}]),e}();e.exports=c})},{select:5}],8:[function(t,n,o){!function(i,r){if(\"function\"==typeof e&&e.amd)e([\"module\",\"./clipboard-action\",\"tiny-emitter\",\"good-listener\"],r);else if(\"undefined\"!=typeof o)r(n,t(\"./clipboard-action\"),t(\"tiny-emitter\"),t(\"good-listener\"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(e,t,n,o){\"use strict\";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function a(e,t){if(!e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return!t||\"object\"!=typeof t&&\"function\"!=typeof t?e:t}function c(e,t){if(\"function\"!=typeof t&&null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function l(e,t){var n=\"data-clipboard-\"+e;if(t.hasAttribute(n))return t.getAttribute(n)}var u=i(t),s=i(n),f=i(o),d=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=\"function\"==typeof t.action?t.action:this.defaultAction,this.target=\"function\"==typeof t.target?t.target:this.defaultTarget,this.text=\"function\"==typeof t.text?t.text:this.defaultText}},{key:\"listenClick\",value:function e(t){var n=this;this.listener=(0,f.default)(t,\"click\",function(e){return n.onClick(e)})}},{key:\"onClick\",value:function e(t){var n=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new u.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})}},{key:\"defaultAction\",value:function e(t){return l(\"action\",t)}},{key:\"defaultTarget\",value:function e(t){var n=l(\"target\",t);if(n)return document.querySelector(n)}},{key:\"defaultText\",value:function e(t){return l(\"text\",t)}},{key:\"destroy\",value:function e(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:\"isSupported\",value:function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[\"copy\",\"cut\"],n=\"string\"==typeof t?[t]:t,o=!!document.queryCommandSupported;return n.forEach(function(e){o=o&&!!document.queryCommandSupported(e)}),o}}]),t}(s.default);e.exports=h})},{\"./clipboard-action\":7,\"good-listener\":4,\"tiny-emitter\":6}]},{},[8])(8)});\n"; //write html htmlCode = "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "
\n" + "
\n" + "
\n" + "
\n" + "

Animation Parameter:

\n" + " \n" + " \n" + "

Keyframes:

\n" + " \n" + " \n" + "

Backgroupd Preview Color:

\n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + "
\n" + "
\n" + "
\n" + "

\n" + "\n" + "\n" + "\n" + "\n" + ""; //close the renderQueue panel app.project.renderQueue.showWindow(false); //show the correct charactar in the path //theLocation = decodeURIComponent(theLocation); //backup the render queue status, then uncheck the queued items var RQbackup = storeRenderQueue(); if(RQbackup[RQbackup.length-1] == "rendering"){ alert(RQerr); }else{ //call command "save frame as" to add current frame to render queue app.executeCommand(2104); app.project.renderQueue.item(app.project.renderQueue.numItems).render = true; var templateTemp = app.project.renderQueue.item(app.project.renderQueue.numItems).outputModule(1).templates; //call hidden template '_HIDDEN X-Factor 16 Premul', which exports png with alpha var setPNG = app.project.renderQueue.item(app.project.renderQueue.numItems).outputModule(1).templates[templateTemp.length-1]; app.project.renderQueue.item(app.project.renderQueue.numItems).outputModule(1).applyTemplate(setPNG); app.project.renderQueue.item(app.project.renderQueue.numItems).outputModule(1).file = new File(theLocation); //var finalpath = app.project.renderQueue.item(app.project.renderQueue.numItems).outputModule(1).file.fsName; app.project.renderQueue.render(); //remove the rendered item and restored the render queue items app.project.renderQueue.item(app.project.renderQueue.numItems).remove(); if(RQbackup != null){ restoreRenderQueue(RQbackup); } oriComp.openInViewer(); tempComp.remove(); app.activeViewer.setActive(); app.project.activeItem.resolutionFactor = res; //show alert and open the folder var finalpath = decodeURIComponent(aniFolder.fsName); alert(endmsg + "\n" + finalpath); //finalpath = finalpath.substring(0,finalpath.lastIndexOf('/')+1); var openFolder = new Folder(finalpath); openFolder.execute(); var runHtml = new File(aniFolder.fsName + osSlash + htmlName); runHtml.open("w"); runHtml.encoding = "UTF-8"; runHtml.write(htmlCode); runHtml.close(); //runHtml.execute(); } } //store the renderQ,return the index of active render items function storeRenderQueue(){ var checkeds = []; for(var p = 1;p <= app.project.renderQueue.numItems; p++){ if (app.project.renderQueue.item(p).status == RQItemStatus.RENDERING){ checkeds.push("rendering"); break; }else if(app.project.renderQueue.item(p).status == RQItemStatus.QUEUED){ checkeds.push(p); app.project.renderQueue.item(p).render = false; } } return checkeds; } //restore the renderQ function restoreRenderQueue(checkedItems){ for(var q = 0;q < checkedItems.length; q++){ app.project.renderQueue.item(checkedItems[q]).render = true; } } } //check input values var checkInput = function(input){ var isInt = new RegExp("^[0-9]*[1-9][0-9]*$"); var isHefazifu = new RegExp("^[_a-zA-Z][_a-zA-Z0-9]*$"); return [isInt.test(input),isHefazifu(input)]; } return win; } })(this);