Created
April 17, 2012 21:44
-
-
Save andershaig/2409272 to your computer and use it in GitHub Desktop.
Create CSS3 code from Photoshop layers
This file contains hidden or 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
/* Copyright 2012 - Minim Group - http://minim.co/ */ | |
// Enable double-clicking from Finder/Explorer | |
#target photoshop | |
app.bringToFront(); | |
// ### Document Variables | |
var doc_layers = app.activeDocument.layers; | |
var num_layers = doc_layers.length; | |
// ### Effect Variables | |
var dropShadow = {}; | |
var stroke = {}; | |
var gradient = {}; | |
// ### Output Variables | |
var output = ''; // TEMP | |
var css; | |
var html; | |
cTID = function(s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); }; | |
sTID = function(s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); }; | |
xTID = function(s) { | |
if (s.constructor == Number) { | |
return s; | |
} | |
if (s.constructor == String) { | |
if (s.length != 4) return sTID(s); | |
try { return cTID(s); } catch (e) { return sTID(s); } | |
} | |
throw "Bad typeid: " + s; | |
}; | |
// ### Main Function | |
function main() { | |
//createDialog(); | |
getLayerEffects(); | |
//generateCSS(); | |
outputFile(); | |
} | |
// ### Helper Functions | |
function createDialog() { | |
var ui = "dialog { \ | |
text:'Main Dialog Text', \ | |
alignChildren: 'fill', \ | |
mainPanel: Panel { \ | |
orientation: 'column', \ | |
text:'Select Layers', \ | |
alignChildren: 'fill', \ | |
helpText:StaticText { \ | |
text:'Which layer would you like to convert and export?', \ | |
properties:{scrolling:undefined,multiline:undefined} \ | |
}, \ | |
selectLayers:DropDownList { properties:{name:'layerList'} } \ | |
}, \ | |
gButtons: Group { \ | |
orientation: 'row', \ | |
cancelBtn:Button { text:'Cancel', orientation: 'column', alignment: 'left', properties:{name:'cancel'} }, \ | |
continueBtn:Button { text:'Select Layers', orientation: 'column', alignment: 'right', properties:{name:'select'} } \ | |
} \ | |
}"; | |
var win = new Window (ui); // new window object with UI resource | |
win.center(); // move to center before | |
var ret = win.show(); // dialog display | |
/* | |
if (1 == ret) { // if "Open" button clicked. | |
} | |
*/ | |
} | |
function getLayerEffects() { | |
// Get Effect Helpers | |
function getDropShadow() { | |
var dropShadowDesc = effectDesc.getObjectValue(cTID("DrSh")); | |
dropShadow.enabled = dropShadowDesc .getBoolean( cTID( "enab" )); | |
dropShadow.blendMode = typeIDToStringID(dropShadowDesc .getEnumerationValue(cTID( "Md " ))); | |
var shadowColorDesc = dropShadowDesc .getObjectValue(cTID( "Clr " )); | |
var shadowColorMode = typeIDToCharID(dropShadowDesc .getObjectType(cTID( "Clr " ))); | |
dropShadow.color = new SolidColor(); | |
switch ( shadowColorMode ){ | |
case 'Grsc': | |
dropShadow.color.gray.gray = shadowColorDesc.getDouble(cTID('Gry ')); | |
break; | |
case 'RGBC': | |
dropShadow.color.rgb.red = shadowColorDesc.getDouble(cTID('Rd ')); | |
dropShadow.color.rgb.green = shadowColorDesc.getDouble(cTID('Grn ')); | |
dropShadow.color.rgb.blue = shadowColorDesc.getDouble(cTID('Bl ')); | |
break; | |
case 'CMYC': | |
dropShadow.color.cmyk.cyan = shadowColorDesc.getDouble(cTID('Cyn ')); | |
dropShadow.color.cmyk.magenta = shadowColorDesc.getDouble(cTID('Mgnt')); | |
dropShadow.color.cmyk.yellow = shadowColorDesc.getDouble(cTID('Ylw ')); | |
dropShadow.color.cmyk.black = shadowColorDesc.getDouble(cTID('Blck')); | |
break; | |
case 'LbCl': | |
dropShadow.color.lab.l = shadowColorDesc.getDouble(cTID('Lmnc')); | |
dropShadow.color.lab.a = shadowColorDesc.getDouble(cTID('A ')); | |
dropShadow.color.lab.b = shadowColorDesc.getDouble(cTID('B ')); | |
break; | |
} | |
dropShadow.opacity = dropShadowDesc .getDouble(cTID("Opct")); | |
dropShadow.useGlobalAngle = dropShadowDesc .getBoolean(cTID("uglg")); | |
dropShadow.localLightingAngle = dropShadowDesc .getDouble( cTID("lagl")); | |
dropShadow.distance = dropShadowDesc .getDouble( cTID("Dstn")); | |
dropShadow.spread = dropShadowDesc .getDouble( cTID("Ckmt")); | |
dropShadow.blur = dropShadowDesc .getDouble( cTID("blur")); | |
dropShadow.noise = dropShadowDesc .getDouble( cTID("Nose")); | |
dropShadow.antialias = dropShadowDesc .getBoolean( cTID( "AntA" )); | |
dropShadow.knockout = dropShadowDesc .getBoolean( sTID("layerConceals")); | |
var contourDesc = dropShadowDesc .getObjectValue( cTID("TrnS"), cTID("ShpC") ); | |
if( contourDesc.hasKey(cTID("Nm ")) ) { | |
dropShadow.contourName = localize(contourDesc.getString( cTID("Nm "))); | |
}else{ | |
dropShadow.contourName = 'custom'; | |
} | |
} | |
function getStroke() { | |
var strokeDesc = effectDesc.getObjectValue(cTID("FrFX")); | |
stroke.enabled = strokeDesc .getBoolean( cTID("enab")); | |
stroke.frameStyle = typeIDToStringID(strokeDesc .getEnumerationValue(cTID("Styl"))); | |
stroke.frameFill = typeIDToStringID(strokeDesc .getEnumerationValue(cTID("PntT"))); | |
stroke.blendMode = typeIDToStringID(strokeDesc .getEnumerationValue(cTID("Md "))); | |
var strokeColorDesc = strokeDesc .getObjectValue(cTID("Clr ")); | |
var strokeColorMode = typeIDToCharID(strokeDesc .getObjectType(cTID("Clr "))); | |
stroke.color = new SolidColor(); | |
switch ( strokeColorMode ){ | |
case 'Grsc': | |
stroke.color.gray.gray = strokeColorDesc.getDouble(cTID('Gry ')); | |
break; | |
case 'RGBC': | |
stroke.color.rgb.red = strokeColorDesc.getDouble(cTID('Rd ')); | |
stroke.color.rgb.green = strokeColorDesc.getDouble(cTID('Grn ')); | |
stroke.color.rgb.blue = strokeColorDesc.getDouble(cTID('Bl ')); | |
break; | |
case 'CMYC': | |
stroke.color.cmyk.cyan = strokeColorDesc.getDouble(cTID('Cyn ')); | |
stroke.color.cmyk.magenta = strokeColorDesc.getDouble(cTID('Mgnt')); | |
stroke.color.cmyk.yellow = strokeColorDesc.getDouble(cTID('Ylw ')); | |
stroke.color.cmyk.black = strokeColorDesc.getDouble(cTID('Blck')); | |
break; | |
case 'LbCl': | |
stroke.color.lab.l = strokeColorDesc.getDouble(cTID('Lmnc')); | |
stroke.color.lab.a = strokeColorDesc.getDouble(cTID('A ')); | |
stroke.color.lab.b = strokeColorDesc.getDouble(cTID('B ')); | |
break; | |
} | |
stroke.opacity = strokeDesc .getDouble(cTID("Opct")); | |
stroke.size = strokeDesc .getDouble(cTID("Sz ")); | |
} | |
// Generate CSS Helpers | |
function setDropShadowCSS() { | |
// Simple Vars | |
var ds; | |
var dsVal; | |
var dsClr; | |
var blur = dropShadow.blur + 'px '; | |
var spread = dropShadow.spread + 'px '; | |
var red = Math.round(dropShadow.color.rgb.red); | |
var green = Math.round(dropShadow.color.rgb.green); | |
var blue = Math.round(dropShadow.color.rgb.blue); | |
var o = dropShadow.opacity / 100; | |
// Round to nearest 45 degrees (in future do more to calculate) | |
var a = dropShadow.localLightingAngle; | |
var d = dropShadow.distance; | |
var ra = Math.round (a / 45) * 45; | |
var distance; | |
if (ra === 0) { | |
distance = (-d) + 'px 0 '; | |
} else if (ra === 45) { | |
distance = (-d) + 'px ' + d + 'px '; | |
} else if (ra === 90) { | |
distance = '0 ' + d + 'px '; | |
} else if (ra === 135) { | |
distance = d + 'px ' + d + 'px '; | |
} else if (ra === 180 || ra === -180) { | |
distance = d + 'px 0 '; | |
} else if (ra === -135) { | |
distance = d + 'px ' + (-d) + 'px '; | |
} else if (ra === -90) { | |
distance = '0 ' + (-d) + 'px '; | |
} else if (ra === -45) { | |
distance = (-d) + 'px ' + (-d) + 'px '; | |
} else { | |
// Couldn't figure out angle | |
} | |
dsVal = distance + blur + spread; | |
dsClr = 'rgba(' + red + ',' + green + ',' + blue + ',' + o + ')'; | |
ds = 'box-shadow: ' + dsVal + dsClr + ';\n'; | |
output += ds; | |
} | |
function setStrokeCSS() { | |
// Simple Vars | |
var s; | |
var sClr; | |
var size = stroke.size + 'px '; | |
var red = Math.round(stroke.color.rgb.red); | |
var green = Math.round(stroke.color.rgb.green); | |
var blue = Math.round(stroke.color.rgb.blue); | |
var o = stroke.opacity / 100; | |
sClr = 'rgba(' + red + ',' + green + ',' + blue + ',' + o + ')'; | |
s = 'border: ' + size + 'solid ' + sClr + ';\n'; | |
//if (stroke.frameStyle === 'insetFrame') { | |
//} | |
output += s; | |
} | |
// Effect Names To Array | |
var ref = new ActionReference(); | |
ref.putEnumerated( cTID("Lyr "), cTID("Ordn"), cTID("Trgt") ); | |
var desc = executeActionGet(ref); | |
if (desc.hasKey(sTID('layerEffects'))) { | |
var effects = []; | |
var effectDesc = desc.getObjectValue( sTID('layerEffects')); | |
// first key is scale so skip and start with 1 | |
for (var effect = 1; effect < effectDesc.count; effect++) { | |
var effect_name = typeIDToStringID(effectDesc.getKey(effect)); | |
if (effect_name === 'dropShadow') { | |
// Drop Shadow / Box Shadow | |
getDropShadow(); | |
setDropShadowCSS(); | |
//output += 'Effect name is ' + effect_name + '\n'; | |
} else if (effect_name === 'gradientFill') { | |
// Gradient | |
//gradient_obj = getGradientSettings(); | |
//output += 'Effect name is ' + effect_name + '\n'; | |
} else if (effect_name === 'frameFX') { | |
// Stroke / Border | |
getStroke(); | |
setStrokeCSS(); | |
//output += 'Effect name is ' + effect_name + '\n'; | |
} else { | |
// do nothing | |
} | |
} | |
} | |
} | |
function generateCSS() { | |
// TODO - Templating? | |
} | |
// ### Output Function | |
function outputFile(){ | |
var mySavefile = File.saveDialog("Filename...","*.html"); | |
if (!mySavefile) {return}; | |
if (mySavefile.exists) { | |
if(! confirm("There is already a file with that name.\nDo you want to overwrite?")){return false;}; | |
} | |
var fileRef = new File(mySavefile); | |
flag = fileRef.open ("w","",""); | |
if (flag) | |
{ | |
fileRef.writeln('<!DOCTYPE html>'); | |
fileRef.writeln('<html lang="en">'); | |
fileRef.writeln('<head>'); | |
fileRef.writeln('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'); | |
fileRef.writeln('<meta http-equiv="Content-Script-Type" content="text/javascript" />'); | |
fileRef.writeln('<title>Template</title>'); | |
fileRef.writeln('</head>'); | |
fileRef.writeln('<style><!--'); | |
fileRef.writeln(output); | |
fileRef.writeln('--></style>'); | |
fileRef.writeln('<body>'); | |
fileRef.writeln('HTML will go here.'); | |
fileRef.writeln('</body>'); | |
fileRef.writeln('</html>'); | |
} | |
fileRef.close(); | |
} | |
// ### Make That Magic Happen | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment