-
-
Save nisrulz/ac0e31677abf30a355d6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MultiExporter.jsx | |
// Version 0.1 | |
// Version 0.2 Adds PNG and EPS exports | |
// Version 0.3 Adds support for exporting at different resolutions | |
// Version 0.4 Adds support for SVG, changed EPS behaviour to minimise output filesize | |
// Version 0.5 Fixed cropping issues | |
// Version 0.6 Added inner padding mode to prevent circular bounds clipping | |
// | |
// Copyright 2013 Tom Byrne | |
// Comments or suggestions to [email protected] | |
// | |
// Copyright 2011 Matthew Ericson | |
var docRef = app.activeDocument; | |
// Format specific functionality | |
getPng8Options = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
var options = new ExportOptionsPNG8(); | |
options.antiAliasing = true; | |
options.transparency = transparency; | |
options.artBoardClipping = true; | |
options.horizontalScale = scaling; | |
options.verticalScale = scaling; | |
return options; | |
} | |
getPng24Options = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
var options = new ExportOptionsPNG24(); | |
options.antiAliasing = true; | |
options.transparency = transparency; | |
options.artBoardClipping = true; | |
options.horizontalScale = scaling; | |
options.verticalScale = scaling; | |
return options; | |
} | |
getPdfOptions = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
var options = new PDFSaveOptions(); | |
options.compatibility = PDFCompatibility.ACROBAT5; | |
options.generateThumbnails = true; | |
options.preserveEditability = false; | |
return options; | |
} | |
getJpgOptions = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
var options = new ExportOptionsJPEG(); | |
options.antiAliasing = true; | |
options.artBoardClipping = true; | |
options.horizontalScale = scaling; | |
options.verticalScale = scaling; | |
return options; | |
} | |
getEpsOptions = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
var options = new EPSSaveOptions(); | |
options.embedLinkedFiles = embedImage; | |
options.embedAllFonts = embedFont; | |
options.includeDocumentThumbnails = true; | |
options.saveMultipleArtboards = false; | |
return options; | |
} | |
getSvgOptions = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
options = new ExportOptionsSVG(); | |
options.embedRasterImages = embedImage; | |
return options; | |
} | |
getFxg1Options = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
options = new FXGSaveOptions(); | |
options.version = FXGVersion.VERSION1PT0; | |
return options; | |
} | |
getFxg2Options = function ( transparency, scaling, embedImage, embedFont, trimEdges ) { | |
options = new FXGSaveOptions(); | |
options.version = FXGVersion.VERSION2PT0; | |
return options; | |
} | |
// Format specific save functions | |
savePng8 = function ( doc, filePath, options, artboardIndex, artboardName ) { | |
var destFile = new File( filePath + '.png' ); | |
doc.exportFile(destFile, ExportType.PNG8 , options); | |
} | |
savePng24 = function ( doc, filePath, options, artboardIndex, artboardName ) { | |
var destFile = new File( filePath + '.png' ); | |
doc.exportFile(destFile, ExportType.PNG24 , options); | |
} | |
savePdf = function ( doc, filePath, options, artboardIndex, artboardName ) { | |
var destFile = new File( filePath + '.pdf' ); | |
options.artboardRange = (artboardIndex+1).toString(); | |
doc.saveAs( destFile, options, artboardIndex, artboardName ) | |
} | |
saveJpg = function ( doc, filePath, options, artboardIndex, artboardName ) { | |
var destFile = new File( filePath + '.jpg' ); | |
doc.exportFile(destFile, ExportType.JPEG , options); | |
} | |
saveEps = function ( doc, filePath, options, artboardIndex, artboardName ) { | |
var destFile = new File( filePath + '.eps' ); | |
options.artboardRange = (artboardIndex+1).toString(); | |
doc.saveAs( destFile, options, artboardIndex, artboardName ) | |
} | |
saveSvg = function ( doc, filePath, options, artboardIndex, artboardName ) { | |
var destFile = new File( filePath + '.svg' ); | |
doc.exportFile(destFile, ExportType.SVG , options); | |
} | |
saveFxg = function ( doc, filePath, options, artboardIndex, artboardName ) { | |
var destFile = new File( filePath + '.fxg' ); | |
options.artboardRange = (artboardIndex+1).toString(); | |
doc.saveAs( destFile, options, artboardIndex, artboardName ) | |
} | |
var multi_exporter = { | |
PREFS_LAYER_NAME: "nyt_exporter_info", | |
multiExporterPrefs: null, | |
prefix: '', | |
suffix: '', | |
base_path: '~/Desktop', | |
transparency: false, | |
embedImage: true, | |
embedFont: true, | |
trimEdges: true, | |
innerPadding: false, | |
ignoreWarnings: false, | |
format: "PNG 24", | |
artboards: null, | |
layers: null, | |
dlg: null, | |
prefs_xml: null, | |
currentFormatInfo: null, | |
num_to_export: 0, | |
failed_artboards: null, | |
failed_layers: null, | |
export_artboards: null, | |
export_layers: null, | |
whole_artboard_mode: false, | |
formatList:null, | |
artboardList:null, | |
progLabel:null, | |
// these are controls that are format dependant | |
controlNames:["scalingInput","transCheckBox","embedImageCheckBox","embedFontCheckBox","trimEdgesCheckBox","innerPaddingCheckBox"], | |
scalingInput:null, | |
transCheckBox:null, | |
embedImageCheckBox:null, | |
embedFontCheckBox:null, | |
trimEdgesCheckBox:null, | |
ignoreCheckBox:null, | |
exportArtboardsCheckBox:null, | |
// copyBehaviour - for vector outputs the output must be done from a copy of the document (to avoid hidden layers being included in output) | |
formatInfo: [ {name:"PNG 8", copyBehaviour:false, pixelDocSize:true, getOptions:getPng8Options, saveFile:savePng8, activeControls:["scalingInput","transCheckBox","trimEdgesCheckBox","innerPaddingCheckBox"]}, | |
{name:"PNG 24", copyBehaviour:false, pixelDocSize:true, getOptions:getPng24Options, saveFile:savePng24, activeControls:["scalingInput","transCheckBox","trimEdgesCheckBox","innerPaddingCheckBox"]}, | |
{name:"PDF", copyBehaviour:false, pixelDocSize:false, getOptions:getPdfOptions, saveFile:savePdf, activeControls:["trimEdgesCheckBox"]}, | |
{name:"JPG", copyBehaviour:false, pixelDocSize:true, getOptions:getJpgOptions, saveFile:saveJpg, activeControls:["scalingInput","trimEdgesCheckBox","innerPaddingCheckBox"]}, | |
{name:"EPS", copyBehaviour:true, pixelDocSize:false, getOptions:getEpsOptions, saveFile:saveEps, activeControls:["embedImageCheckBox","embedFontCheckBox","trimEdgesCheckBox"]}, | |
{name:"SVG", copyBehaviour:true, pixelDocSize:false, getOptions:getSvgOptions, saveFile:saveSvg, activeControls:["embedImageCheckBox","trimEdgesCheckBox"]}, | |
{name:"FXG 1.0", copyBehaviour:true, pixelDocSize:false, getOptions:getFxg1Options, saveFile:saveFxg, activeControls:["trimEdgesCheckBox"]}, | |
{name:"FXG 2.0", copyBehaviour:true, pixelDocSize:false, getOptions:getFxg2Options, saveFile:saveFxg, activeControls:["trimEdgesCheckBox"]}], | |
artboardSelect: [ {code:"all", name:'All Artboards (except those beginning with - )'}, | |
{code:"current", name:'Current Artboard'}, | |
{name:'---'} ], | |
layerSelect: [ {code:"all", name:'All Layers (except those beginning with - )'}, | |
{code:"none", name:'None (for use with \'Export Artboard Images\')'}, | |
{code:"selected", name:'Selected Items\' Layers'}, | |
{name:'---'} ], | |
init: function() { | |
var parse_success = this.load_prefs(); | |
if (parse_success) { | |
this.show_dialog(); | |
} | |
}, | |
findExportTypeByCode: function(code){ | |
for(var i=0; i<this.exportTypes.length; ++i){ | |
var type = this.exportTypes[i]; | |
if(type.code==code)return type; | |
} | |
}, | |
load_prefs: function() { | |
var parse_success = false; | |
// find existing layers or add new one | |
try { | |
this.multiExporterPrefs = docRef.layers.getByName( this.PREFS_LAYER_NAME ); | |
} catch ( e ) { | |
this.multiExporterPrefs = docRef.layers.add(); | |
this.multiExporterPrefs.name = this.PREFS_LAYER_NAME; | |
var nyt_exporter_info_xml = this.multiExporterPrefs.textFrames.add(); | |
var saved_data = new XML( '<nyt_prefs></nyt_prefs>' ); | |
saved_data.appendChild( new XML('<nyt_prefix></nyt_prefix>') ); | |
saved_data.appendChild( new XML('<nyt_suffix></nyt_suffix>') ); | |
saved_data.appendChild( new XML('<nyt_base_path>~/Desktop</nyt_base_path>') ); | |
saved_data.appendChild( new XML('<nyt_scaling>100%</nyt_scaling>') ); | |
saved_data.appendChild( new XML('<nyt_transparency>true</nyt_transparency>') ); | |
saved_data.appendChild( new XML('<nyt_embedImage>true</nyt_embedImage>') ); | |
saved_data.appendChild( new XML('<nyt_embedFont>true</nyt_embedFont>') ); | |
saved_data.appendChild( new XML('<nyt_trimEdges>true</nyt_trimEdges>') ); | |
saved_data.appendChild( new XML('<nyt_innerPadding>false</nyt_innerPadding>') ); | |
saved_data.appendChild( new XML('<nyt_format>PNG 24</nyt_format>') ); | |
saved_data.appendChild( new XML('<nyt_artboards>all</nyt_artboards>') ); | |
saved_data.appendChild( new XML('<nyt_layers>all</nyt_layers>') ); | |
saved_data.appendChild( new XML('<nyt_exportArtboards>false</nyt_exportArtboards>') ); | |
saved_data.appendChild( new XML('<nyt_ignoreWarnings>false</nyt_ignoreWarnings>') ); | |
nyt_exporter_info_xml.contents = saved_data.toXMLString(); | |
this.multiExporterPrefs.printable = false; | |
this.multiExporterPrefs.visible = false; | |
} | |
// get xml out of the 1 text item on that layer and parse it | |
if ( this.multiExporterPrefs.textFrames.length != 1 ) { | |
Window.alert( 'Please delete the '+this.PREFS_LAYER_NAME+' layer and try again.' ); | |
} else { | |
try { | |
this.prefs_xml = new XML( this.multiExporterPrefs.textFrames[0].contents ); | |
this.prefix = this.prefs_xml.nyt_prefix; | |
this.suffix = this.prefs_xml.nyt_suffix; | |
this.base_path = this.prefs_xml.nyt_base_path; | |
this.scaling = this.prefs_xml.nyt_scaling; | |
this.transparency = this.prefs_xml.nyt_transparency == "true" ? true : false; | |
this.embedImage = this.prefs_xml.nyt_embedImage == "true" ? true : false; | |
this.ignoreWarnings = this.prefs_xml.nyt_ignoreWarnings == "true" ? true : false; | |
this.embedFont = this.prefs_xml.nyt_embedFont == "true" ? true : false; | |
this.trimEdges = this.prefs_xml.nyt_trimEdges == "true" ? true : false; | |
this.innerPadding = this.prefs_xml.nyt_innerPadding == "true" ? true : false; | |
this.format = this.prefs_xml.nyt_format; | |
this.artboards = this.prefs_xml.nyt_artboards.toString(); | |
this.layers = this.prefs_xml.nyt_layers.toString(); | |
this.whole_artboard_mode = this.prefs_xml.nyt_exportArtboards == "true" ? true : false; | |
if(!this.artboards){ | |
this.artboards = this.artboardSelect[0].code; | |
}else if(parseInt(this.artboards).toString()==this.artboards){ | |
this.artboards = parseInt(this.artboards); | |
} | |
if(!this.layers){ | |
this.layers = this.layerSelect[0].code; | |
}else if(parseInt(this.layers).toString()==this.layers){ | |
this.layers = parseInt(this.layers); | |
} | |
if ( ! this.prefs_xml.nyt_scaling || this.prefs_xml.nyt_scaling == '' ) { | |
this.scaling = '100%'; | |
} | |
parse_success = true; | |
} catch ( e ) { | |
Window.alert( 'Please delete the this.multiExporterPrefs layer and try again.' ); | |
} | |
} | |
return parse_success; | |
}, | |
// dialog display | |
show_dialog: function() { | |
// Export dialog | |
this.dlg = new Window('dialog', 'Multi Exporter'); | |
var row; | |
// ARTBOARD TYPE ROW | |
row = this.dlg.add('group', undefined, '') | |
row.oreintation = 'row'; | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
var typeSt = row.add('statictext', undefined, 'Export artboards:'); | |
typeSt.size = [ 100,20 ]; | |
var artboardNames = []; | |
for(var i=0; i<this.artboardSelect.length; ++i){ | |
artboardNames.push(this.artboardSelect[i].name) | |
} | |
for(var i=0; i<docRef.artboards.length; i++){ | |
var artboard = docRef.artboards[i]; | |
artboardNames.push((i+1)+": "+artboard.name); | |
} | |
this.artboardList = row.add('dropdownlist', undefined, artboardNames); | |
this.artboardList.selection = this.findDataIndex(this.artboards, this.artboardSelect); | |
this.exportArtboardsCheckBox = row.add('checkbox', undefined, 'Export Artboard Images'); | |
this.exportArtboardsCheckBox.value = this.whole_artboard_mode; | |
// LAYER TYPE ROW | |
row = this.dlg.add('group', undefined, '') | |
row.oreintation = 'row'; | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
var typeSt = row.add('statictext', undefined, 'Export layers:'); | |
typeSt.size = [ 100,20 ]; | |
var layerNames = []; | |
for(var i=0; i<this.layerSelect.length; ++i){ | |
layerNames.push(this.layerSelect[i].name) | |
} | |
for(var i=0; i<docRef.layers.length; i++){ | |
var layer = docRef.layers[i]; | |
layerNames.push((i+1)+": "+layer.name); | |
} | |
this.layerList = row.add('dropdownlist', undefined, layerNames); | |
this.layerList.selection = this.findDataIndex(this.layers, this.layerSelect); | |
// PREFIX GRP | |
row = this.dlg.add('group', undefined, '') | |
row.oreintation = 'row'; | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
var prefixSt = row.add('statictext', undefined, 'File prefix:'); | |
prefixSt.size = [100,20] | |
this.prefixEt = row.add('edittext', undefined, this.prefix); | |
this.prefixEt.size = [ 300,20 ]; | |
// suffix row | |
row = this.dlg.add('group', undefined, '') | |
row.oreintation = 'row'; | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
row = this.dlg.add('group', undefined, '') | |
row.oreintation = 'row'; | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
var suffixSt = row.add('statictext', undefined, 'File suffix:'); | |
suffixSt.size = [100,20] | |
this.suffixEt = row.add('edittext', undefined, this.suffix); | |
this.suffixEt.size = [ 300,20 ]; | |
// scaling row | |
row = this.dlg.add('group', undefined, '') | |
row.oreintation = 'row'; | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
var scalingLabel = row.add('statictext', undefined, 'Scaling:'); | |
scalingLabel.size = [100,20] | |
this.scalingInput = row.add('edittext', undefined, this.scaling); | |
this.scalingInput.size = [ 100,20 ]; | |
var scalingTip = row.add('statictext', undefined, '(Normally 100%; Use 200% for Retina display exports)'); | |
scalingTip.size = [300,20] | |
// DIR GROUP | |
row = this.dlg.add( 'group', undefined, '') | |
row.orientation = 'row' | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
var dirSt = row.add('statictext', undefined, 'Output directory:'); | |
dirSt.size = [ 100,20 ]; | |
this.dirEt = row.add('edittext', undefined, this.base_path); | |
this.dirEt.size = [ 300,20 ]; | |
var chooseBtn = row.add('button', undefined, 'Choose ...' ); | |
chooseBtn.onClick = function() { multi_exporter.dirEt.text = Folder.selectDialog(); } | |
// FORMAT ROW | |
row = this.dlg.add('group', undefined, ''); | |
row.orientation = 'row' | |
row.alignment = [ScriptUI.Alignment.LEFT, ScriptUI.Alignment.TOP] | |
var formatSt = row.add('statictext', undefined, 'Export format:'); | |
formatSt.size = [ 100,20 ]; | |
var formatNames = []; | |
for(var i=0; i<this.formatInfo.length; ++i){ | |
formatNames.push(this.formatInfo[i].name) | |
} | |
this.formatList = row.add('dropdownlist', undefined, formatNames); | |
this.formatList.selection = 1; | |
for ( var i=0; i < this.formatList.items.length; i++ ) { | |
if ( multi_exporter.format == this.formatList.items[i].text ) { | |
this.formatList.selection = i; | |
} | |
} | |
this.embedImageCheckBox = row.add('checkbox', undefined, 'Embed Imagery'); | |
this.embedImageCheckBox.value = this.embedImage; | |
this.embedFontCheckBox = row.add('checkbox', undefined, 'Embed Fonts'); | |
this.embedFontCheckBox.value = this.embedFont; | |
// TRANSPARENCY AND TRIM ROW | |
row = this.dlg.add('group', undefined, ''); | |
row.orientation = 'row' | |
row.alignment = [ScriptUI.Alignment.CENTER, ScriptUI.Alignment.TOP] | |
this.transCheckBox = row.add('checkbox', undefined, 'Transparency'); | |
this.transCheckBox.value = this.transparency; | |
this.trimEdgesCheckBox = row.add('checkbox', undefined, 'Trim Edges'); | |
this.trimEdgesCheckBox.value = this.trimEdges; | |
this.innerPaddingCheckBox = row.add('checkbox', undefined, 'Inner Padding (to prevent curved edge clipping)'); | |
this.innerPaddingCheckBox.value = this.innerPadding; | |
// progress bar | |
var progBar = this.dlg.add( 'progressbar', undefined, 0, 100 ); | |
progBar.size = [400,10] | |
this.progLabel = this.dlg.add('statictext', undefined, '...' ); | |
this.progLabel.size = [ 400,20 ]; | |
// buttons row | |
row = this.dlg.add('group', undefined, ''); | |
row.orientation = 'row' | |
var cancelBtn = row.add('button', undefined, 'Cancel', {name:'cancel'}); | |
cancelBtn.onClick = function() { multi_exporter.dlg.close() }; | |
var saveBtn = row.add('button', undefined, 'Save and Close', {name:'saveClose'}); | |
saveBtn.onClick = function() { | |
multi_exporter.saveOptions(); | |
multi_exporter.dlg.close() | |
}; | |
// OK button | |
var okBtn = row.add('button', undefined, 'Export', {name:'ok'}); | |
okBtn.onClick = function() { | |
multi_exporter.saveOptions(); // save options before export in case of errors | |
try{ | |
multi_exporter.run_export(); | |
}catch(e){ | |
alert(e); | |
} | |
}; | |
this.ignoreCheckBox = row.add('checkbox', undefined, 'Ignore Warnings'); | |
this.ignoreCheckBox.value = this.ignoreWarnings; | |
// Export type handler | |
this.artboardList.onChange = function() { | |
multi_exporter.artboards = multi_exporter.getListData(multi_exporter.artboardList.selection.index, multi_exporter.artboardSelect); | |
multi_exporter.update_export_desc( ); | |
}; | |
this.layerList.onChange = function() { | |
multi_exporter.layers = multi_exporter.getListData(multi_exporter.layerList.selection.index, multi_exporter.layerSelect); | |
multi_exporter.update_export_desc( ); | |
}; | |
this.exportArtboardsCheckBox.onClick = function() { | |
multi_exporter.whole_artboard_mode = multi_exporter.exportArtboardsCheckBox.value; | |
multi_exporter.update_export_desc( ); | |
}; | |
// Format change handler | |
this.formatList.onChange = function() { | |
multi_exporter.checkFormat(); | |
}; | |
multi_exporter.update_export_desc( ); | |
this.dlg.progBar = progBar; | |
this.checkFormat(); | |
this.dlg.show(); | |
}, | |
findDataIndex: function(data, selectList){ | |
if(typeof(data)=="string" && parseInt(data).toString()==data){ | |
data = parseInt(data); | |
} | |
if(typeof(data)=="number"){ | |
return selectList.length+data; | |
}else{ | |
for(var i=0; i<selectList.length; ++i){ | |
if(selectList[i].code==data){ | |
return i; | |
} | |
} | |
} | |
alert("no find: "+data); | |
}, | |
getListData: function(index, selectList){ | |
if(index>=selectList.length){ | |
return index-selectList.length; | |
}else{ | |
return selectList[index].code; | |
} | |
}, | |
checkFormat: function ( progLabel ) { | |
var formatInfo = this.formatInfo[this.formatList.selection.index]; | |
this.currentFormatInfo = formatInfo; | |
for(var i=0; i<this.controlNames.length; i++){ | |
var controlName = this.controlNames[i]; | |
this[controlName].enabled = (this.indexOf(formatInfo.activeControls, controlName)!=-1); | |
} | |
}, | |
indexOf: function ( array, element ) { | |
for(var i=0; i<array.length; i++){ | |
if(array[i]==element)return i; | |
} | |
return -1; | |
}, | |
update_export_desc: function () { | |
this.export_artboards = []; | |
this.export_layers = []; | |
if(this.artboards=="all"){ | |
for(var i=0; i<docRef.artboards.length; ++i){ | |
var artboard = docRef.artboards[i]; | |
if(!artboard.name.match( /^\-/ )){ | |
this.export_artboards.push(i); | |
} | |
} | |
}else if(this.artboards=="current"){ | |
this.export_artboards.push(docRef.artboards.getActiveArtboardIndex()); | |
}else if(typeof(this.artboards)=="number"){ | |
this.export_artboards.push(this.artboards); | |
} | |
if(this.layers=="all"){ | |
for(var i=0; i<docRef.layers.length; ++i){ | |
var layer = docRef.layers[i]; | |
if(!this.isAdditionalLayer(layer) && this.isIncludeLayer(layer)){ | |
this.export_layers.push(i); | |
} | |
} | |
}else if(this.layers=="selected"){ | |
for(var i=0; i<docRef.layers.length; ++i){ | |
var layer = docRef.layers[i]; | |
if(!this.isAdditionalLayer(layer) && this.isIncludeLayer(layer) && layer.hasSelectedArtwork){ | |
this.export_layers.push(i); | |
} | |
} | |
this.export_layers.push(docRef.artboards.getActiveArtboardIndex()); | |
}else if(typeof(this.layers)=="number"){ | |
this.export_layers.push(this.layers); | |
} | |
this.updateExportCounts(); | |
}, | |
updateExportCounts: function(){ | |
this.num_to_export = this.export_artboards.length*this.export_layers.length; | |
var artboardExportTxt; | |
if(this.whole_artboard_mode){ | |
this.num_to_export += this.export_artboards.length; | |
if(this.export_layers.length){ | |
artboardExportTxt = " (and "+this.export_artboards.length+" artboard images)"; | |
}else{ | |
this.progLabel.text = 'Will export ' + this.export_artboards.length + ' of ' + docRef.artboards.length + ' artboards'; | |
return; | |
} | |
}else{ | |
artboardExportTxt = ""; | |
} | |
if(this.export_artboards.length>1 && this.export_layers.length>1){ | |
this.progLabel.text = 'Will export ' + this.num_to_export + ' files (' + this.export_layers.length + ' layers * ' + this.export_artboards.length + ' artboards)'+artboardExportTxt; | |
}else if(this.export_layers.length>0 && this.export_artboards.length==1){ | |
var artboard = docRef.artboards[this.export_artboards[0]]; | |
this.progLabel.text = 'Will export ' + this.export_layers.length + ' of ' + docRef.layers.length+ ' layers on artboard "' + artboard.name +'"' +artboardExportTxt; | |
}else if(this.export_layers.length>0 && this.export_artboards.length>0){ | |
var artboard = docRef.artboards[this.export_artboards[0]]; | |
this.progLabel.text = 'Will export ' + this.export_layers.length+' layers on "' + this.export_artboards.length +'" artboards' +artboardExportTxt; | |
}else{ | |
this.progLabel.text = 'Please select valid artboards / layers' ; | |
} | |
}, | |
saveOptions:function(){ | |
this.prefix = this.prefixEt.text; | |
this.suffix = this.suffixEt.text; | |
this.base_path = this.dirEt.text; | |
this.transparency = this.transCheckBox.value; | |
this.embedImage = this.embedImageCheckBox.value; | |
this.embedFont = this.embedFontCheckBox.value; | |
this.trimEdges = this.trimEdgesCheckBox.value; | |
this.innerPadding = this.innerPaddingCheckBox.value; | |
this.ignoreWarnings = this.ignoreCheckBox.value; | |
this.format = this.formatList.selection.text; | |
this.scaling = parseFloat( this.scalingInput.text.replace( /\% /, '' )); | |
this.prefs_xml.nyt_base_path = this.base_path; | |
this.prefs_xml.nyt_scaling = this.scaling; | |
this.prefs_xml.nyt_prefix = this.prefix; | |
this.prefs_xml.nyt_suffix = this.suffix; | |
this.prefs_xml.nyt_transparency = this.transparency; | |
this.prefs_xml.nyt_embedImage = this.embedImage; | |
this.prefs_xml.nyt_ignoreWarnings = this.ignoreWarnings; | |
this.prefs_xml.nyt_embedFont = this.embedFont; | |
this.prefs_xml.nyt_trimEdges = this.trimEdges; | |
this.prefs_xml.nyt_innerPadding = this.innerPadding; | |
this.prefs_xml.nyt_format = this.format; | |
this.prefs_xml.nyt_artboards = this.artboards; | |
this.prefs_xml.nyt_layers = this.layers; | |
this.prefs_xml.nyt_exportArtboards = this.whole_artboard_mode; | |
this.multiExporterPrefs.textFrames[0].contents = this.prefs_xml.toXMLString(); | |
}, | |
// run_export function. does the dirty work | |
run_export: function() { | |
this.failed_artboards = []; | |
this.failed_layers = []; | |
var formatInfo = this.currentFormatInfo; | |
var copyBehaviour = formatInfo.copyBehaviour || this.trimEdges; | |
var num_exported = 0; | |
var options = formatInfo.getOptions(this.transparency, this.scaling, this.embedImage, this.embedFont, this.trimEdges); | |
if(!copyBehaviour){ | |
var were_shown = this.get_shown_layers(); | |
} | |
if(!this.export_artboards.length || (!this.export_layers.length && !this.whole_artboard_mode)){ | |
alert('Please select valid artboards / layers'); | |
return; | |
} | |
if(!this.base_path){ | |
alert('Please select select a destination'); | |
return; | |
} | |
// offsetting must be in relation to the center of the first artboard | |
var firstRect = docRef.artboards[0].artboardRect; | |
var firstCentX = (firstRect[2]-firstRect[0])/2; | |
var firstCentY = (firstRect[1]-firstRect[3])/2; | |
for (var i = 0; i < this.export_artboards.length; i++ ) { | |
var artboard = docRef.artboards[this.export_artboards[i]]; | |
var artboardName = artboard.name; | |
starting_artboard = docRef.artboards.setActiveArtboardIndex(i); | |
var rect = artboard.artboardRect; | |
var offsetX = firstRect[0]-rect[0]; | |
var offsetY = firstRect[1]-rect[1]; | |
var artW = rect[2]-rect[0]; | |
var artH = rect[1]-rect[3]; | |
var copyDoc; | |
// if exporting artboard by artboard, export layers as is | |
if ( this.whole_artboard_mode) { | |
try{ | |
var base_filename = this.base_path + "/" + this.prefix + artboardName + this.suffix; | |
if(copyBehaviour){ | |
var offset = {x:offsetX, y:offsetY}; | |
copyDoc = this.copyDocument(docRef, formatInfo.pixelDocSize, artboard, rect, artW, artH, offset, function(layer){return (layer.name!=multi_exporter.PREFS_LAYER_NAME && layer.visible)}); | |
formatInfo.saveFile(copyDoc, base_filename, options, i, artboardName); | |
copyDoc.close(SaveOptions.DONOTSAVECHANGES); | |
copyDoc = null; | |
}else{ | |
formatInfo.saveFile(docRef, base_filename, options, i, artboardName); | |
} | |
}catch(e){ | |
this.failed_artboards.push(i); | |
} | |
this.updateProgress(++num_exported); | |
} | |
if(this.export_layers.length){ | |
if(copyBehaviour){ | |
if(!this.trimEdges){ | |
var layerDepths = []; | |
var offset = {x:offsetX, y:offsetY}; | |
copyDoc = this.copyDocument(docRef, formatInfo.pixelDocSize, artboard, rect, docRef.width, docRef.height, offset, this.isAdditionalLayer, layerDepths); | |
var hasAdditLayers = copyDoc.layers.length>0; | |
} | |
}else{ | |
this.hide_all_layers(); | |
} | |
for ( var j=0; j < this.export_layers.length; j++ ) { | |
var layer = docRef.layers[this.export_layers[j]]; | |
var lyr_name = layer.name; | |
try{ | |
var layerRect | |
// only process layer if it has bounds (i.e. not guide layer) and falls within current artboard bounds | |
layerRect = this.get_layer_bounds(layer) | |
if(layerRect==null)continue; | |
if (layerRect[0]<layerRect[2] && layerRect[1]>layerRect[3]) { | |
var isVis = this.intersects(rect, layerRect); | |
if(!hasAdditLayers && !isVis && !this.trimEdges){ | |
// skip layers where nothing is visible | |
continue; | |
} | |
var base_filename; | |
if ( this.export_artboards.length==1 ) { | |
base_filename = this.base_path + "/" + this.prefix + lyr_name + this.suffix; | |
} else{ | |
base_filename = this.base_path + "/" + this.prefix + artboardName + '-' + lyr_name + this.suffix; | |
} | |
if(copyBehaviour){ | |
if(this.trimEdges){ | |
if(copyDoc){ | |
copyDoc.close(SaveOptions.DONOTSAVECHANGES); | |
copyDoc = null; | |
} | |
// crop to artboard | |
if(layerRect[0]<rect[0]){ | |
layerRect[0] = rect[0]; | |
}else{ | |
intendedX = 0; | |
} | |
if(layerRect[1]>rect[1]){ | |
layerRect[1] = rect[1]; | |
} | |
if(layerRect[2]>rect[2]){ | |
layerRect[2] = rect[2]; | |
} | |
if(layerRect[3]<rect[3]){ | |
layerRect[3] = rect[3]; | |
}else{ | |
intendedY = 0; | |
} | |
layerOffsetY = rect[3] - layerRect[3]; | |
layerOffsetX = rect[0] - layerRect[0]; | |
docW = layerRect[2]-layerRect[0]; | |
docH = layerRect[1]-layerRect[3]; | |
offset = {x:offsetX+layerOffsetX, y:offsetY+layerOffsetY}; | |
var layerDepths = []; | |
var copyDoc = this.copyDocument(docRef, formatInfo.pixelDocSize, artboard, rect, docW, docH, offset, this.isAdditionalLayer, layerDepths); | |
var hasAdditLayers = copyDoc.layers.length>1; // there will be one empty layer in the new file (which can be ignored) | |
if(!hasAdditLayers && !isVis){ | |
// skip layers where nothing is visible | |
continue; | |
} | |
} | |
if(isVis){ | |
// only copy layer if it is visible (if not only visible '+' layers will be output) | |
var new_layer = this.copy_layer(layer, copyDoc.layers.add(), offset, copyDoc.width, copyDoc.height, this.innerPadding); | |
new_layer.visible = true; | |
var depth = layerDepths[this.export_layers[j]]; | |
while(new_layer.zOrderPosition<depth){ | |
new_layer.zOrder(ZOrderMethod.BRINGFORWARD); | |
} | |
while(new_layer.zOrderPosition>depth){ | |
new_layer.zOrder(ZOrderMethod.SENDBACKWARD); | |
} | |
} | |
formatInfo.saveFile(copyDoc, base_filename, options, i, artboardName); | |
if(new_layer && !this.trimEdges){ | |
new_layer.remove(); | |
new_layer = null; | |
} | |
}else{ | |
layer.visible = true; | |
formatInfo.saveFile(docRef, base_filename, options, i, artboardName); | |
layer.visible = false; | |
} | |
} | |
}catch(e){ | |
this.failed_artboards.push(i); | |
this.failed_layers.push(j); | |
if(new_layer && !this.trimEdges){ | |
new_layer.remove(); | |
new_layer = null; | |
} | |
} | |
this.updateProgress(++num_exported); | |
} | |
if(copyDoc){ | |
copyDoc.close(SaveOptions.DONOTSAVECHANGES); | |
copyDoc = null; | |
} | |
} | |
} | |
if(!copyBehaviour){ | |
this.show_layers(were_shown); | |
} | |
if((!this.failed_layers.length && !this.failed_artboards.length) || !this.redoFailed(this.failed_layers, this.failed_artboards)){ | |
this.dlg.close(); | |
} | |
}, | |
redoFailed: function(failed_layers, failed_artboards) { | |
var newLayers = []; | |
for(var i=0; i<failed_layers.length; ++i){ | |
var index = this.export_layers[failed_layers[i]]; | |
if(this.indexOf(newLayers, index)==-1)newLayers.push(index); | |
} | |
var newArtboards = []; | |
for(var i=0; i<failed_artboards.length; ++i){ | |
var index = this.export_artboards[failed_artboards[i]]; | |
if(this.indexOf(newArtboards, index)==-1)newArtboards.push(index); | |
} | |
if(newLayers.length){ | |
var layerNames = ""; | |
for(var i=0; i<newLayers.length; ++i){ | |
var index = newLayers[i]; | |
layerNames += "\n - "+docRef.layers[index].name; | |
} | |
var msg = newLayers.length+" layers failed across "+newArtboards.length+" artboards:"+layerNames+"\n Retry?"; | |
}else{ | |
var artboardNames = ""; | |
for(var i=0; i<newArtboards.length; ++i){ | |
var index = newArtboards[i]; | |
artboardNames += "\n - "+docRef.artboards[index].name; | |
} | |
var msg = newArtboards.length+" artboards failed:"+artboardNames+"\nRetry?"; | |
} | |
if(confirm(msg)){ | |
this.export_artboards = newArtboards; | |
this.export_layers = newLayers; | |
this.updateExportCounts(); | |
this.run_export(); | |
return true; | |
} | |
return false; | |
}, | |
traceRect: function(rect) { | |
if(!rect)return "no rect"; | |
return "l: "+Math.round(rect[0])+" t: "+Math.round(rect[1])+" r: "+Math.round(rect[2])+" b: "+Math.round(rect[3])+" w: "+(rect[2]-rect[0])+" h: "+(rect[1]-rect[3]); | |
}, | |
isAdditionalLayer: function(layer) { | |
return ( layer.name.match( /^\+/ ) && layer.visible); | |
}, | |
isIncludeLayer: function(layer) { | |
return ( !layer.name.match( /^\+/ ) && layer.name!=this.PREFS_LAYER_NAME && !layer.name.match( /^\-/) ) | |
}, | |
copyDocument: function(docRef, pixelDocSize, artboard, rect, w, h, offset, layerCheck, layerDepths) { | |
var docW; | |
var docH; | |
if(pixelDocSize){ | |
w = Math.round(w *1000) / 1000; | |
h = Math.round(h *1000) / 1000; | |
w = Math.ceil(w); | |
h = Math.ceil(h); | |
} | |
var preset = new DocumentPreset(); | |
preset.width = w; | |
preset.height = h; | |
preset.colorMode = docRef.documentColorSpace; | |
preset.units = docRef.rulerUnits; | |
var copyDoc = app.documents.addDocument(docRef.documentColorSpace, preset); | |
copyDoc.pageOrigin = docRef.pageOrigin; | |
copyDoc.rulerOrigin = docRef.rulerOrigin; | |
var count = 1; // indices are 1 based! | |
var n = docRef.layers.length; | |
for ( var j=docRef.layers.length-1; j >=0; j-- ) { | |
layer = docRef.layers[j]; | |
if (layerCheck(layer)) { | |
var layerBounds = this.get_layer_bounds(layer); | |
if(layerBounds && this.intersects(rect, layerBounds)){ | |
this.copy_layer(layer, copyDoc.layers.add(), offset, w, h, false); | |
++count; | |
} | |
}else if(layerDepths){ | |
layerDepths[j] = count; | |
} | |
} | |
return copyDoc; | |
}, | |
updateProgress: function(num_exported) { | |
this.progLabel.text = 'Exported ' + num_exported + ' of ' + this.num_to_export; | |
this.dlg.progBar.value = num_exported / this.num_to_export * 100; | |
this.dlg.update(); | |
}, | |
copy_layer: function(from_layer, to_layer, offset, docW, docH, doInnerPadding) { | |
to_layer.artworkKnockout = from_layer.artworkKnockout; | |
to_layer.blendingMode = from_layer.blendingMode; | |
to_layer.color = from_layer.color; | |
to_layer.dimPlacedImages = from_layer.dimPlacedImages; | |
to_layer.isIsolated = from_layer.isIsolated; | |
to_layer.name = from_layer.name; | |
to_layer.opacity = from_layer.opacity; | |
to_layer.preview = from_layer.preview; | |
to_layer.printable = from_layer.printable; | |
to_layer.sliced = from_layer.sliced; | |
to_layer.typename = from_layer.typename; | |
if(!offset.norm){ | |
var oldBounds = this.get_layer_bounds(from_layer); | |
//for mystery reasons, this only works if done before copying items across | |
} | |
var items = from_layer.pageItems; | |
try{ | |
this.copy_items(items, to_layer); | |
}catch(e){ | |
alert("copy items failed"); | |
} | |
// copy backwards for correct z-ordering | |
for(var i=from_layer.layers.length-1; i>=0; --i){ | |
var child = from_layer.layers[i]; | |
if(child.visible)this.copy_layer(child, to_layer.layers.add(), offset, docW, docH, false) | |
} | |
if(!offset.norm){ | |
var newBounds = this.get_layer_bounds(to_layer); | |
if(this.rect_equal(oldBounds, newBounds)){ | |
//$.sleep(5000); // sleeping doesn't help!! | |
if(!this.ignoreWarnings)alert("Illustrator visibleBounds issue workaround.\nTry removing groups on layer '"+from_layer.name+"' to avoid this in future.\nPlease press OK"); | |
newBounds = this.get_layer_bounds(to_layer); | |
// sometimes it takes a moment for bounds to be updated | |
} | |
if(oldBounds && newBounds){ | |
offset.x += oldBounds[0]-newBounds[0]; | |
offset.y += oldBounds[3]-newBounds[3]; | |
offset.norm = true; | |
} | |
} | |
if(to_layer.parent.artboards!=null){ // only if top level layer | |
try{ | |
this.shift_layer(to_layer, offset.x, offset.y); | |
}catch(e){ | |
alert("shift layer failed"); | |
} | |
} | |
if(doInnerPadding)this.innerPadLayer(to_layer, docW, docH); | |
return to_layer; | |
}, | |
innerPadLayer: function(layer, docW, docH){ | |
docW = Math.round(docW * 100) / 100; | |
docH = Math.round(docH * 100) / 100; | |
for(var i=0; i<layer.pageItems.length; ++i){ | |
var item = layer.pageItems[i]; | |
var bounds = item.visibleBounds; | |
// round to two decimal points | |
var l = Math.round(bounds[0] * 100) / 100; | |
var b = Math.round(bounds[1] * 100) / 100; | |
var r = Math.round(bounds[2] * 100) / 100; | |
var t = Math.round(bounds[3] * 100) / 100; | |
var w = (r - l); | |
var h = (b - t); | |
if(w>docW-1 && h>docH-1){ | |
var scaleX = (w-1) / w * 100; // resize takes percentage values | |
var scaleY = (h-1) / h * 100; | |
item.resize(scaleX, scaleY, null, null, null, null, null, Transformation.CENTER); | |
} | |
} | |
for(var i=0; i<layer.layers.length; ++i){ | |
innerPadLayer(layer.layers[i], docW, docH); | |
} | |
}, | |
rect_equal: function(rect1, rect2) { | |
return rect1[0]==rect2[0] && rect1[1]==rect2[1] && rect1[2]==rect2[2] && rect1[3]==rect2[3] ; | |
}, | |
copy_items: function(from_list, to_layer) { | |
var visWas = to_layer.visible; | |
to_layer.visible = true; | |
for(var i=0; i<from_list.length; ++i){ | |
var item = from_list[i].duplicate(to_layer, ElementPlacement.PLACEATEND); | |
/*if(shiftX!=0 || shiftY!=0){ | |
item.translate(shiftX, shiftY) | |
}*/ | |
} | |
to_layer.visible = visWas; | |
}, | |
shift_layer: function(layer, shiftX, shiftY) { | |
this.shift_items(layer.pageItems, shiftX, shiftY); | |
// copy backwards for correct z-ordering | |
for(var i=layer.layers.length-1; i>=0; --i){ | |
this.shift_layer(layer.layers[i], shiftX, shiftY) | |
} | |
}, | |
shift_items: function(items, shiftX, shiftY) { | |
if(shiftX==undefined)shiftX = 0; | |
if(shiftY==undefined)shiftY = 0; | |
for(var i=0; i<items.length; ++i){ | |
items[i].translate(shiftX, shiftY) | |
} | |
}, | |
hide_all_layers: function() { | |
var n = docRef.layers.length; | |
for(var i=0; i<n; ++i) { | |
layer = docRef.layers[i]; | |
lyr_name = layer.name; | |
// any layers that start with + are always turned on | |
if (this.isAdditionalLayer(layer)) { | |
layer.visible = true; | |
} else { | |
layer.visible = false; | |
} | |
} | |
}, | |
get_shown_layers: function() { | |
var shown = [] | |
var n = docRef.layers.length; | |
for(var i=0; i<n; ++i) { | |
layer = docRef.layers[i]; | |
if(layer.visible){ | |
shown.push(i); | |
} | |
} | |
return shown; | |
}, | |
get_layer_bounds: function(layer) { | |
var rect; | |
var items = layer.pageItems; | |
for(var i=0; i<items.length; ++i){ | |
var item = items[i]; | |
if(item.guides){ | |
continue; | |
} | |
var visBounds = item.visibleBounds; | |
if(visBounds==null)continue; | |
if(rect==null){ | |
rect = visBounds; | |
}else{ | |
if(rect[0]>visBounds[0]){ | |
rect[0] = visBounds[0]; | |
} | |
if(rect[1]<visBounds[1]){ | |
rect[1] = visBounds[1]; | |
} | |
if(rect[2]<visBounds[2]){ | |
rect[2] = visBounds[2]; | |
} | |
if(rect[3]>visBounds[3]){ | |
rect[3] = visBounds[3]; | |
} | |
} | |
} | |
for(var i=0; i<layer.layers.length; ++i){ | |
var childRect = this.get_layer_bounds(layer.layers[i]); | |
if(childRect==null)continue; | |
if(rect==null){ | |
rect = childRect; | |
}else{ | |
if(rect[0]>childRect[0]){ | |
rect[0] = childRect[0]; | |
} | |
if(rect[1]<childRect[1]){ | |
rect[1] = childRect[1]; | |
} | |
if(rect[2]<childRect[2]){ | |
rect[2] = childRect[2]; | |
} | |
if(rect[3]>childRect[3]){ | |
rect[3] = childRect[3]; | |
} | |
} | |
} | |
return rect; | |
}, | |
intersects: function(rect1, rect2) { | |
return !( rect2[0] > rect1[2] || | |
rect2[1] < rect1[3] || | |
rect2[2] < rect1[0] || | |
rect2[3] > rect1[1]); | |
}, | |
show_layers: function(layerIndices) { | |
var n = layerIndices.length; | |
for(var i=0; i<n; ++i) { | |
layer = docRef.layers[layerIndices[i]]; | |
layer.visible = true; | |
} | |
} | |
}; | |
multi_exporter.init(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment