Copy link to clipboard
Copied
Have you ever drawn a bunch of arrows or lines then needed to change their properties? Normally, you would have to redraw them all with new parameters in the line/arrow tool. Here is a script that allows you to edit an existing line or arrow, drawn with the shape tool.
#target photoshop
//copyright 2017 Chuck Uebele, all rights reserved
//Use at your own risk.
var xmlFile = new File(Folder.desktop+'/ArrowPrefs.xml');
var xmlPref
if(xmlFile.exists){
xmlPref = readXMLFile (xmlFile)
//alert(xmlPref.prefs.lines.children().length())
//alert(xmlPref.prefs.lines.children()[0].@preset)
}
else{xmlPref = new XML('<root><prefs><lines/><arrows/></prefs>')};
//varables for lines and points
var run = true;
var lineType;
var origLineWidth;
var lineAngTan1;//from first point to oppsite side of line
var lineAngTan2;//From oppsite side of line to first point
var lineLengthAng;
var lineLength;
var lineMid1;//mid width on line from first point
var lineMid2;//mid width on line from oppsite end of line
var newWidth = 20
var ptTemp1
var ptTemp2
var ptTemp3
var ptTemp4
var dropLst = new Array()
var prefsDrop
var headIntersect1;
var headIntersect2;
//-----------
var arrowLength;
var arrowWidth;
var arrowEndsMid;
var arrowConcave;
var arrowConcaveFactor;
var arrowLengthFactor;
var arrowWidthFactor;
/////////////////
app.preferences.rulerUnits = Units.PIXELS;
try{
var doc = activeDocument
var sLay = doc.activeLayer
var sLayName = sLay.name + ' Shape Path'
var cPath = doc.pathItems.getByName(sLayName)
var ptArray = new Array();
var ptNewArray = new Array();
var idPath;
//var numAnchors = cPath.subPathItems[0].pathPoints.length;
recordAnchors (cPath);
var numAnchors = ptArray.length;
}
catch(e){
run = false;
var numAnchors=0
}
switch(numAnchors){
case 4:
lineType = 'Normal Line'
origLineWidth = lineL (ptArray[0][0], ptArray[0][1], ptArray[1][0], ptArray[1][1]);
lineAngTan1 = getAng (ptArray[0][0], ptArray[0][1], ptArray[1][0], ptArray[1][1]);
lineAngTan2 = getAng (ptArray[1][0], ptArray[1][1], ptArray[0][0], ptArray[0][1]);
lineMid1 = [(ptArray[0][0] + ptArray[1][0])/2,(ptArray[0][1] + ptArray[1][1])/2 ];
lineMid2 = [(ptArray[2][0] + ptArray[3][0])/2,(ptArray[2][1] + ptArray[3][1])/2 ];
ui ();
ptNewArray[0] = newPt (lineMid1[0],lineMid1[1], newWidth/2, lineAngTan1);
ptNewArray[3] = newPt (lineMid2[0],lineMid2[1], newWidth/2, lineAngTan1);
ptNewArray[1] = newPt (lineMid1[0],lineMid1[1], newWidth/2, lineAngTan2);
ptNewArray[2] = newPt (lineMid2[0],lineMid2[1], newWidth/2, lineAngTan2);
break;
case 7:
if(Math.round (getAng (ptArray[0][0], ptArray[0][1], ptArray[6][0], ptArray[6][1]))==Math.round (getAng (ptArray[1][0], ptArray[1][1], ptArray[2][0], ptArray[2][1]))){
//alert('end')
lineType = 'Single Arrow End';
origLineWidth = lineL (ptArray[0][0], ptArray[0][1], ptArray[1][0], ptArray[1][1]);
lineAngTan1 = getAng (ptArray[0][0], ptArray[0][1], ptArray[1][0], ptArray[1][1]);
lineAngTan2 = getAng (ptArray[1][0], ptArray[1][1], ptArray[0][0], ptArray[0][1]);
lineMid1 = [(ptArray[1][0] + ptArray[0][0])/2,(ptArray[1][1] + ptArray[0][1])/2 ];
lineMid2 = [(ptArray[2][0] + ptArray[6][0])/2,(ptArray[2][1] + ptArray[6][1])/2 ];
arrowEndsMid = [(ptArray[3][0] + ptArray[5][0])/2,(ptArray[3][1] + ptArray[5][1])/2 ];
arrowLength = lineL (ptArray[4][0], ptArray[4][1], arrowEndsMid[0], arrowEndsMid[1]);
arrowWidth = lineL (ptArray[5][0], ptArray[5][1], ptArray[3][0], ptArray[3][1]);
arrowConcaveFactor = getConcaveFactor (ptArray[6][0], ptArray[6][1], ptArray[0][0], ptArray[0][1], ptArray[4][0], ptArray[4][1], ptArray[5][0], ptArray[5][1], ptArray[3][0], ptArray[3][1]);
arrowLengthFactor = Math.round((arrowLength/origLineWidth)*100);
arrowWidthFactor = Math.round((arrowWidth/origLineWidth)*100);
lineLengthAng = getAng (arrowEndsMid[0], arrowEndsMid[1],ptArray[4][0], ptArray[4][1]);
//////////////////////////////////////
ui ()
//New points
arrowEndsMid = newPt (ptArray[4][0], ptArray[4][1], newWidth*arrowLengthFactor*.01, lineLengthAng);
ptNewArray[5] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan1);
ptNewArray[3] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan2);
ptNewArray[1] = newPt (lineMid1[0], lineMid1[1], newWidth/2, lineAngTan2);
ptNewArray[0] = newPt (lineMid1[0], lineMid1[1], newWidth/2, lineAngTan1);
ptTemp1 = newPt (lineMid2[0], lineMid2[1], newWidth/2, lineAngTan1);
ptTemp2 = newPt (lineMid2[0], lineMid2[1], newWidth/2, lineAngTan2);
headIntersect1= getIntersect (ptTemp1[0], ptTemp1[1], ptNewArray[0][0], ptNewArray[0][1], ptArray[4][0], ptArray[4][1], ptNewArray[5][0], ptNewArray[5][1]);
headIntersect2= getIntersect (ptTemp2[0], ptTemp2[1], ptNewArray[1][0], ptNewArray[1][1], ptArray[4][0], ptArray[4][1], ptNewArray[3][0], ptNewArray[3][1]);
ptTemp3 = getIntersect (ptTemp1[0], ptTemp1[1], ptNewArray[0][0], ptNewArray[0][1], ptNewArray[5][0], ptNewArray[5][1], ptNewArray[3][0], ptNewArray[3][1]);
ptTemp4 = getIntersect (ptTemp2[0], ptTemp2[1], ptNewArray[1][0], ptNewArray[1][1], ptNewArray[5][0], ptNewArray[5][1], ptNewArray[3][0], ptNewArray[3][1]);
arrowConcave = lineL (headIntersect1[0], headIntersect1[1], ptTemp3[0], ptTemp3[1])*arrowConcaveFactor*.01;
ptNewArray[6] = newPt (ptTemp3[0], ptTemp3[1], -arrowConcave, lineLengthAng);
ptNewArray[2] = newPt (ptTemp4[0], ptTemp4[1], -arrowConcave, lineLengthAng);
}
else{
//alert('beginning')
lineType = 'Single Arrow Start';
origLineWidth = lineL (ptArray[0][0], ptArray[0][1], ptArray[4][0], ptArray[4][1]);
lineAngTan1 = getAng (ptArray[0][0], ptArray[0][1], ptArray[4][0], ptArray[4][1]);
lineAngTan2 = getAng (ptArray[4][0], ptArray[4][1], ptArray[0][0], ptArray[0][1]);
lineMid1 = [(ptArray[4][0] + ptArray[0][0])/2,(ptArray[4][1] + ptArray[0][1])/2 ];
lineMid2 = [(ptArray[5][0] + ptArray[6][0])/2,(ptArray[5][1] + ptArray[6][1])/2 ];
arrowEndsMid = [(ptArray[1][0] + ptArray[3][0])/2,(ptArray[1][1] + ptArray[3][1])/2 ]
arrowLength = lineL (ptArray[2][0], ptArray[2][1], arrowEndsMid[0], arrowEndsMid[1]);
arrowWidth = lineL (ptArray[1][0], ptArray[1][1], ptArray[3][0], ptArray[3][1]);
arrowConcaveFactor = getConcaveFactor (ptArray[0][0], ptArray[0][1], ptArray[6][0], ptArray[6][1], ptArray[2][0], ptArray[2][1], ptArray[1][0], ptArray[1][1], ptArray[3][0], ptArray[3][1])
arrowLengthFactor = Math.round((arrowLength/origLineWidth)*100);
arrowWidthFactor = Math.round((arrowWidth/origLineWidth)*100);
lineLengthAng = getAng (arrowEndsMid[0], arrowEndsMid[1],ptArray[2][0], ptArray[2][1]);
//////////////////////////////////////
ui ()
//New points
arrowEndsMid = newPt (ptArray[2][0], ptArray[2][1], newWidth*arrowLengthFactor*.01, lineLengthAng);
ptNewArray[1] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan1);
ptNewArray[3] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan2);
ptNewArray[5] = newPt (lineMid2[0], lineMid2[1], newWidth/2, lineAngTan2);
ptNewArray[6] = newPt (lineMid2[0], lineMid2[1], newWidth/2, lineAngTan1);
ptTemp1 = newPt (lineMid1[0], lineMid1[1], newWidth/2, lineAngTan1);
ptTemp2 = newPt (lineMid1[0], lineMid1[1], newWidth/2, lineAngTan2);
headIntersect1= getIntersect (ptTemp1[0], ptTemp1[1], ptNewArray[6][0], ptNewArray[6][1], ptArray[2][0], ptArray[2][1], ptNewArray[1][0], ptNewArray[1][1])
headIntersect2= getIntersect (ptTemp2[0], ptTemp2[1], ptNewArray[5][0], ptNewArray[5][1], ptArray[2][0], ptArray[2][1], ptNewArray[3][0], ptNewArray[3][1])
ptTemp3 = getIntersect (ptTemp1[0], ptTemp1[1], ptNewArray[6][0], ptNewArray[6][1], ptNewArray[1][0], ptNewArray[1][1], ptNewArray[3][0], ptNewArray[3][1])
ptTemp4 = getIntersect (ptTemp2[0], ptTemp2[1], ptNewArray[5][0], ptNewArray[5][1], ptNewArray[1][0], ptNewArray[1][1], ptNewArray[3][0], ptNewArray[3][1])
arrowConcave = lineL (headIntersect1[0], headIntersect1[1], ptTemp3[0], ptTemp3[1])*arrowConcaveFactor*.01;
ptNewArray[0] = newPt (ptTemp3[0], ptTemp3[1], -arrowConcave, lineLengthAng);
ptNewArray[4] = newPt (ptTemp4[0], ptTemp4[1], -arrowConcave, lineLengthAng);
}
break;
case 10:
lineType = 'Double Arrow';
origLineWidth = lineL (ptArray[0][0], ptArray[0][1], ptArray[4][0], ptArray[4][1]);
lineAngTan1 = getAng (ptArray[0][0], ptArray[0][1], ptArray[4][0], ptArray[4][1]);
lineAngTan2 = getAng (ptArray[4][0], ptArray[4][1], ptArray[0][0], ptArray[0][1]);
arrowEndsMid = [(ptArray[1][0] + ptArray[3][0])/2,(ptArray[1][1] + ptArray[3][1])/2 ];
arrowLength = lineL (ptArray[2][0], ptArray[2][1], arrowEndsMid[0], arrowEndsMid[1]);
arrowWidth = lineL (ptArray[1][0], ptArray[1][1], ptArray[3][0], ptArray[3][1]);
arrowConcaveFactor = getConcaveFactor (ptArray[0][0], ptArray[0][1], ptArray[9][0], ptArray[9][1], ptArray[2][0], ptArray[2][1], ptArray[1][0], ptArray[1][1], ptArray[3][0], ptArray[3][1]);
arrowLengthFactor = Math.round((arrowLength/origLineWidth)*100);
arrowWidthFactor = Math.round((arrowWidth/origLineWidth)*100);
lineLengthAng = getAng (ptArray[7][0], ptArray[7][1],ptArray[2][0], ptArray[2][1]);
/////////////////////////////////////////////
ui ()
//new points
arrowEndsMid = newPt (ptArray[2][0], ptArray[2][1], newWidth*arrowLengthFactor*.01, lineLengthAng);
ptNewArray[1] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan1);
ptNewArray[3] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan2);
arrowEndsMid = newPt (ptArray[7][0], ptArray[7][1], -newWidth*arrowLengthFactor*.01, lineLengthAng);
ptNewArray[8] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan1);
ptNewArray[6] = newPt (arrowEndsMid[0], arrowEndsMid[1], (newWidth*arrowWidthFactor *.01)/2, lineAngTan2);
ptTemp1 = newPt (ptArray[2][0], ptArray[2][1], newWidth/2, lineAngTan1);
var ptTemp1a = newPt (ptArray[7][0], ptArray[7][1], newWidth/2, lineAngTan1);
ptTemp2 = newPt (ptArray[2][0], ptArray[2][1], newWidth/2, lineAngTan2);
var ptTemp2a = newPt (ptArray[7][0], ptArray[7][1], newWidth/2, lineAngTan2);
headIntersect1= getIntersect (ptTemp1[0], ptTemp1[1], ptTemp1a[0], ptTemp1a[1], ptArray[2][0], ptArray[2][1], ptNewArray[1][0], ptNewArray[1][1]);
headIntersect2= getIntersect (ptTemp2[0], ptTemp2[1], ptTemp2a[0], ptTemp2a[1], ptArray[2][0], ptArray[2][1], ptNewArray[3][0], ptNewArray[3][1]);
var headIntersect3= getIntersect (ptTemp1[0], ptTemp1[1], ptTemp1a[0], ptTemp1a[1], ptArray[7][0], ptArray[7][1], ptNewArray[8][0], ptNewArray[8][1]);
var headIntersect4= getIntersect (ptTemp2[0], ptTemp2[1], ptTemp2a[0], ptTemp2a[1], ptArray[7][0], ptArray[7][1], ptNewArray[6][0], ptNewArray[6][1]);
ptTemp3 = getIntersect (ptTemp1[0], ptTemp1[1], ptTemp1a[0], ptTemp1a[1], ptNewArray[1][0], ptNewArray[1][1], ptNewArray[3][0], ptNewArray[3][1]);
var ptTemp3a = getIntersect (ptTemp2[0], ptTemp2[1], ptTemp2a[0], ptTemp2a[1], ptNewArray[1][0], ptNewArray[1][1], ptNewArray[3][0], ptNewArray[3][1]);
ptTemp4 = getIntersect (ptTemp1[0], ptTemp1[1], ptTemp1a[0], ptTemp1a[1], ptNewArray[6][0], ptNewArray[6][1], ptNewArray[8][0], ptNewArray[8][1]);
var ptTemp4a = getIntersect (ptTemp2[0], ptTemp2[1], ptTemp2a[0], ptTemp2a[1], ptNewArray[6][0], ptNewArray[6][1], ptNewArray[8][0], ptNewArray[8][1]);
arrowConcave = lineL (headIntersect1[0], headIntersect1[1], ptTemp3[0], ptTemp3[1])*arrowConcaveFactor*.01;
ptNewArray[0] = newPt (ptTemp3[0], ptTemp3[1], -arrowConcave, lineLengthAng);
ptNewArray[4] = newPt (ptTemp3a[0], ptTemp3a[1], -arrowConcave, lineLengthAng);
ptNewArray[9] = newPt (ptTemp4[0], ptTemp4[1], arrowConcave, lineLengthAng);
ptNewArray[5] = newPt (ptTemp4a[0], ptTemp4a[1], arrowConcave, lineLengthAng);
break;
default:
run = false;
alert("The layer selected didn't match the criteria for a line or arrow")
}//end switch
if(run){
var myPathInfo = mkNewPathInfo ();
deltPath ();
var tempPath = app.activeDocument.pathItems.add( 'temp', myPathInfo);
selPath ();
doc.activeLayer = sLay;
mkPath ()
tempPath.remove();
}
////////////////////////////////////
function ui(){
var dlg = new Window('dialog','Edit Line Tool Line');
dlg.alignChildren = ['left','top'];
dlg.lType = dlg.add('statictext',undefined,lineType);
dlg.wGp = dlg.add('group');
dlg.wGp.alignChildren = ['left','top'];
dlg.wGp.sTxts = dlg.wGp.add('statictext',undefined,'Line Width');
dlg.wGp.eTxt = dlg.wGp.add('edittext',undefined,Math.round(origLineWidth));
dlg.wGp.eTxt.size = [50,12];
dlg.wGp.sTxte = dlg.wGp.add('statictext',undefined,'px');
if(lineType!='Normal Line'){
for(var i=0;i<xmlPref.prefs.arrows.children().length();i++){
dropLst[i]= xmlPref.prefs.arrows.children()[i].@preset
}
}
else{
for(var i=0;i<xmlPref.prefs.lines.children().length();i++){
dropLst[i]= xmlPref.prefs.lines.children()[i].@preset
}
}
if(lineType!='Normal Line'){
dlg.aLgp = dlg.add('group');
dlg.aLgp.alignChildren = ['left','top'];
dlg.aLgp.sTxts = dlg.aLgp.add('statictext',undefined,'Arrow Length');
dlg.aLgp.ALen = dlg.aLgp.add('edittext',undefined,arrowLengthFactor);
dlg.aLgp.ALen.size = [50,12];
dlg.aLgp.sTxte = dlg.aLgp.add('statictext',undefined,'%');
dlg.aWgp = dlg.add('group');
dlg.aWgp.alignChildren = ['left','top'];
dlg.aWgp.sTxts = dlg.aWgp.add('statictext',undefined,'Arrow Width');
dlg.aWgp.AWid = dlg.aWgp.add('edittext',undefined,arrowWidthFactor);
dlg.aWgp.AWid.size = [50,12];
dlg.aWgp.sTxte = dlg.aWgp.add('statictext',undefined,'%');
dlg.aConGp = dlg.add('group');
dlg.aConGp.alignChildren = ['left','top'];
dlg.aConGp.sTxts = dlg.aConGp.add('statictext',undefined,'Arrow Concave');
dlg.aConGp.ACon = dlg.aConGp.add('edittext',undefined,arrowConcaveFactor);
dlg.aConGp.ACon.size = [50,12];
dlg.aConGp.sTxte = dlg.aConGp.add('statictext',undefined,'%');
}
dlg.btnGp = dlg.add('group');
dlg.btnGp.okay = dlg.btnGp.add('button',undefined,'Okay');
dlg.btnGp.cancel = dlg.btnGp.add('button',undefined,'Cancel');
dlg.prefsPn = dlg.add('panel',undefined,'Preferences');
dlg.prefsPn.alignChildren = ['left','top'];
dlg.prefsPn.save = dlg.prefsPn.add('button',undefined,'Save Preference');
dlg.prefsPn.del = dlg.prefsPn.add('button',undefined,'Delete Preference');
prefsDrop = dlg.prefsPn.add('dropdownlist',undefined,dropLst);
prefsDrop.title = 'Load Preferences';
prefsDrop.size = [300,25];
prefsDrop.onChange = function(){
if(lineType!='Normal Line'){
dlg.wGp.eTxt.text = xmlPref.prefs.arrows.children()[parseInt(prefsDrop.selection)].width
dlg.aLgp.ALen.text = xmlPref.prefs.arrows.children()[parseInt(prefsDrop.selection)].leng
dlg.aWgp.AWid.text = xmlPref.prefs.arrows.children()[parseInt(prefsDrop.selection)].aWidth
dlg.aConGp.ACon.text = xmlPref.prefs.arrows.children()[parseInt(prefsDrop.selection)].concave
}
else{
dlg.wGp.eTxt.text = xmlPref.prefs.lines.children()[parseInt(prefsDrop.selection)].width
}
};
dlg.wGp.eTxt.onChange = function(){
textToNum (1, 1000, dlg.wGp.eTxt, origLineWidth);
}
if(lineType!='Normal Line'){
dlg.aLgp.ALen.onChange = function(){
textToNum (1, 10000, dlg.aLgp.ALen, arrowLengthFactor);
}
dlg.aWgp.AWid.onChange = function(){
textToNum (1, 10000, dlg.aWgp.AWid, arrowWidthFactor);
}
dlg.aWgp.AWid.onChange = function(){
textToNum (-50, 50, dlg.aConGp.ACon, arrowConcaveFactor);
}
}//end if
dlg.prefsPn.save.onClick = function(){
savePrefs ();
}
dlg.prefsPn.del.onClick = function(){
if(prefsDrop.selection != null){
var selc = parseInt(prefsDrop.selection);
prefsDrop.remove(selc);
if(lineType!='Normal Line'){
delete xmlPref.prefs.arrows.children()[selc];
}
else{
delete xmlPref.prefs.lines.children()[selc];
}
writeXMLFile (xmlFile, xmlPref)
}
}
dlg.btnGp.okay.onClick = function(){
dlg.close();
newWidth = parseInt (dlg.wGp.eTxt.text);
if(lineType!='Normal Line'){
arrowLengthFactor = parseInt (dlg.aLgp.ALen.text);
arrowWidthFactor = parseInt (dlg.aWgp.AWid.text);
arrowConcaveFactor = parseInt (dlg.aConGp.ACon.text);
}
}
dlg.btnGp.cancel.onClick = function(){
run = false;
dlg.close()
}
//==================
function savePrefs(){
var newName = prompt ('Enter New Profile Name', '', 'Save Preferences');
var prefGood = true;
for(var i=0;i<prefsDrop.items.length;i++){
if(prefsDrop.items[i].text == newName){
newName = prompt ('That preset exists\nPlease choose a unique name','', 'Save Preferences' );
i=0
}
}
prefsDrop.add('item',newName)
if(lineType=='Normal Line'){
xmlPref.prefs.lines.appendChild (XML('<line preset="'+ newName+ '"><width>'+dlg.wGp.eTxt.text+'</width></line>'));
}
else{
xmlPref.prefs.arrows.appendChild (XML('<arrow preset="'+ newName+ '"><width>'+dlg.wGp.eTxt.text+'</width><leng>'+dlg.aLgp.ALen.text+'</leng><aWidth>'+dlg.aWgp.AWid.text+'</aWidth><concave>'+dlg.aConGp.ACon.text+'</concave></arrow>'));
}
writeXMLFile (xmlFile, xmlPref)
}
//=====================
dlg.show();
}
function textToNum(sMin,sMax,e,def){
def=Math.round (def)
var sHold = def;
if(isNaN(parseInt(e.text))){
alert('"' + e.text + '" is not a number\nEnter a value between ' + sMin + '-' + sMax );
e.text = def};
else{
sHold = parseInt(e.text)
if(sHold < sMin){
rangeAlert();
sHold = sMin;
};
if(sHold > sMax){
rangeAlert();
sHold = sMax;
};
e.text = sHold;
}
function rangeAlert(){alert('Number range must be between ' + sMin + '-' + sMax)};
};//end function textToNum
function getConcaveFactor(x1,y1,x2,y2, x3, y3, x4, y4, x5, y5){//1 & 2 = shaft pt 1 &2; 3 & 4 = arrow length line; 5 = tail point opp side
var ptAH = getIntersect (x1, y1, x2, y2, x3, y3, x4, y4);//intersection of shaft with sides of arrowhead
//mkDot (ptAH)
var ptTail = getIntersect (x1, y1, x2, y2, x4, y4, x5, y5);//Intersection of arrow tip ends cross shaft
var conTotalLen = lineL (x1, y1, ptAH[0], ptAH[1]);//gets total length to see if the concave goes in toward the arrowhead or out (-)
var conFullLen = lineL (ptTail[0], ptTail[1], ptAH[0], ptAH[1]);//length of arrow from end tips to intersection with shaft
var conF = lineL (x1, y1, ptTail[0], ptTail[1])/conFullLen
if(conTotalLen>conFullLen){conF*=-1}
return Math.round(conF*100)
}
function getIntersect(x1,y1,x2,y2, x3, y3, x4, y4){
var slope1 = (y1-y2)/(x1-x2);
var bIntersect1 = y1-(slope1*x1)
var slope2 = (y3-y4)/(x3-x4);
var bIntersect2 = y3-(slope2*x3)
var xNew ;
var yNew;
if(bIntersect1=='-Infinity'||bIntersect1=='Infinity'){
xNew=x1;
yNew = slope2*xNew + bIntersect2;
}
else if(bIntersect2=='-Infinity'||bIntersect2=='Infinity'){
xNew = x3;
yNew = slope1*xNew + bIntersect1;
}
else{
xNew= (-(bIntersect1-bIntersect2))/(slope1-slope2);
yNew = slope1*xNew + bIntersect1
}
return [xNew,yNew]
}
function recordAnchors(pathObj){
ptArray = new Array();
for(var i=0;i<pathObj.subPathItems[0].pathPoints.length;i++){
ptNewArray [i] = ptArray[i] = pathObj.subPathItems[0].pathPoints[i].anchor;
}//end loop
}//end function
function mkNewPathInfo(){
var pathArray = new Array();
var piArray = new Array();
for(var i=0;i<ptNewArray.length;i++){
piArray[i] = new PathPointInfo;
piArray[i].kind = cPath.subPathItems[0].pathPoints[i].kind;
piArray[i].anchor = ptNewArray[i];
piArray[i].leftDirection = ptNewArray[i];
piArray[i].rightDirection = ptNewArray[i];
}//end loop
pathArray[0] = new SubPathInfo();
pathArray[0].operation = cPath.subPathItems[0].operation;
pathArray[0].closed = cPath.subPathItems[0].closed;
pathArray[0].entireSubPath = piArray;
return pathArray;
};//end function
/////////////////////
function extractSubPathInfo(pathObj,oldPoint,newPoint){
var pathArray = new Array();
var pl = pathObj.subPathItems.length;
for(var s=0;s<pl;s++){
var pArray = new Array();
for(var i=0;i<pathObj.subPathItems[s].pathPoints.length;i++){
pArray[i] = new PathPointInfo;
pArray[i].kind = pathObj.subPathItems[s].pathPoints[i].kind;
if(pathObj.subPathItems[s].pathPoints[i].anchor[0]==oldPoint[0] &&
pathObj.subPathItems[s].pathPoints[i].anchor[1]==oldPoint[1]){
pArray[i].anchor = newPoint;
pArray[i].leftDirection = newPoint;
pArray[i].rightDirection = newPoint;
}else{
pArray[i].anchor = pathObj.subPathItems[s].pathPoints[i].anchor;
pArray[i].leftDirection = pathObj.subPathItems[s].pathPoints[i].leftDirection;
pArray[i].rightDirection = pathObj.subPathItems[s].pathPoints[i].rightDirection;
}
};
pathArray[pathArray.length] = new Array();
pathArray[pathArray.length - 1] = new SubPathInfo();
pathArray[pathArray.length - 1].operation = pathObj.subPathItems[s].operation;
pathArray[pathArray.length - 1].closed = pathObj.subPathItems[s].closed;
pathArray[pathArray.length - 1].entireSubPath = pArray;
};
return pathArray;
};
function deltPath(){
var idDlt = charIDToTypeID( "Dlt " );
var desc2 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
idPath = charIDToTypeID( "Path" );
var idvectorMask = stringIDToTypeID( "vectorMask" );
ref1.putEnumerated( idPath, idPath, idvectorMask );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref1.putEnumerated( idLyr, idOrdn, idTrgt );
desc2.putReference( idnull, ref1 );
executeAction( idDlt, desc2, DialogModes.NO );
}
function selPath(){
var idslct = charIDToTypeID( "slct" );
var desc2 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
ref1.putName( idPath, "temp" );
desc2.putReference( idnull, ref1 );
executeAction( idslct, desc2, DialogModes.NO );
}
function mkPath(){
var idMk = charIDToTypeID( "Mk " );
var desc10 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref3 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
ref3.putClass( idPath );
desc10.putReference( idnull, ref3 );
var idAt = charIDToTypeID( "At " );
var ref4 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
var idPath = charIDToTypeID( "Path" );
var idvectorMask = stringIDToTypeID( "vectorMask" );
ref4.putEnumerated( idPath, idPath, idvectorMask );
desc10.putReference( idAt, ref4 );
var idUsng = charIDToTypeID( "Usng" );
var ref5 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref5.putEnumerated( idPath, idOrdn, idTrgt );
desc10.putReference( idUsng, ref5 );
executeAction( idMk, desc10, DialogModes.NO );
}
function lineL (ax,ay,bx,by){
var x = Math.abs (ax-bx);
var y = Math.abs (ay-by);
var len = Math.sqrt (Math.pow (x, 2) + Math.pow (y, 2));
return len
}
function getAng(ax,ay,bx,by){
var dx = ax-bx;
var dy = ay-by;
var theta = Math.atan2 (dy, dx);
//theta *= 180/Math.PI
return theta;
}
function newPt (x1,y1,rad,ang){
var newEnd = new Array();
newEnd[0] = x1 + rad * Math.cos (ang);
newEnd[1] = y1 + rad * Math.sin (ang);
return newEnd;
}
//===============READ/WRITE functions========================================
//=========================================================================
function readXMLFile(file) {
if (!file.exists) {
alert( "Cannot find file: " + deodeURI(file.absoluteURI));
}
else{
file.encoding = "UTF8";
file.lineFeed = "unix";
file.open("r", "TEXT", "????");
var str = file.read();
file.close();
return new XML(str);
};
};
function writeXMLFile(file, xml) {
if (!(xml instanceof XML)) {
alert( "Bad XML parameter");
};
else{
file.encoding = "UTF8";
file.open("w", "TEXT", "????");
//unicode signature, this is UTF16 but will convert to UTF8 "EF BB BF"
file.write("\uFEFF");
file.lineFeed = "unix";
file.write(xml.toXMLString());
file.close();
};
};
//=========================================================================
Copy link to clipboard
Copied
Wow, thank you!
Copy link to clipboard
Copied
Wow!
We do need a repository with such gems. do you also post them at Ps-scripts?
Copy link to clipboard
Copied
No I haven't posted it there. Having login issues, which I just haven't bothered fixing yet.
Copy link to clipboard
Copied
Administrator Tom made me a moderator there. Try again, I'll try to help.
Copy link to clipboard
Copied
Will do.
Copy link to clipboard
Copied
Three to One how does one add a dislike to the thread? Just kidding Chuck. I normally just edit them not redraw them and usually they also need to be repositioned. After using your script I definitely would need to redraw some.
Copy link to clipboard
Copied
Chuck this is very impressive and you put a lot of amazing work into it. I feel compelled, however, to give the steps in Illustrator for others who may see this thread later. I do a lot of charts with arrows and dashed lines, and then the customer wants a different arrow head or line thickness or dash spacing.
In Illustrator:
I will save your script and give it a try later today. Thanks for sharing!
~ Jane
Copy link to clipboard
Copied
Arrows are useful. How to select any arrow from Tool where there are existing arrows selectable. I remember old PhotoShop version was very convenient but now new ones are very inconvenient so that we have to draw it.
Copy link to clipboard
Copied
The new default shapes are not so useful as the old ones, you can load them from the local menu of the shapes panel, legacy shapes.