Skip to main content
May 6, 2016
Answered

Mouse coordinate Or Action?

  • May 6, 2016
  • 5 replies
  • 2563 views

Dear all:

I am a new comer in PS scripts. Recently i come across a problem that i want to realize to draw a stable selection as the following picture.

The ideal situation would be:when i click mouse it may draw a box with script. The rectangle is 50*25 pixels. The sharp one can be missed at first.

If the ideal situaion cannot be realized, the sharp corner can be placed in the middle of above line, which length is 10.

Now i have two ideas. The first one, when i click in the pic, it may get may mouse coordinates in the info(pressing F8). I want to get the coordinates into memroy, so that scripts can call them to draw a box with selection tool. But i don't know how to get coordinates to memory.

The second one, when i click the mouse, i can use actions to complete it. But i don't know how to do it.

Thanks all.

This topic has been closed for replies.
Correct answer c.pfaffenbichler

for floor 11:

1.Yeah, i add 2 color samplers in the layer, the script can run successfully and it is so cool.

2.In fact, what i want to do is just like you show, two nearest points are very good.

3.Maybe I can modify the script so that the triangle stay at stable direction in order to fit the entire pic.

For floor 12:

I agree with you. But my ThinkPad laptop (E530-i3-2G RAM)can only exist 4 color samplers at the same time. I must delete them when there are four points. Why may occur this situation? Maybe my computer is too old? Its cpu only is i3-3110M, and i buy it in 2012.


Please give this a try:

// create shape layer consisting of one rectangle and one triangle based on the last two colorsamplers;

// 2016, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

if (myDocument.colorSamplers.length > 1) {

// pixels,;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS

var originalResolution = myDocument.resolution;

myDocument.resizeImage (null, null, 72, ResampleMethod.NONE);

var halfWidth = 25;

var halfHeight = 12.5;

// get coordinates;

var theCoord1 = myDocument.colorSamplers[myDocument.colorSamplers.length-2].position;

var theCoord2 = myDocument.colorSamplers[myDocument.colorSamplers.length-1].position;

// define rectangle;

var point1 = [theCoord1[0]-halfWidth,theCoord1[1]-halfHeight];

var point2 = [theCoord1[0]+halfWidth,theCoord1[1]-halfHeight];

var point3 = [theCoord1[0]+halfWidth,theCoord1[1]+halfHeight];

var point4 = [theCoord1[0]-halfWidth,theCoord1[1]+halfHeight];

var subPath1 = [[point1, point1, point1, false], [point2, point2, point2, false], [point3, point3, point3, false], [point4, point4, point4, false], true, 1097098272];

// get angle;

var theAngle = getAngle(theCoord1, theCoord2);

//alert (theAngle);

// define triangle ponts;

switch (true) {

case (theAngle >= 27 && theAngle < 153):

var tr1 = [theCoord1[0]-(halfWidth/3), theCoord1[1]+halfHeight];

var tr2 = [theCoord1[0]+(halfWidth/3), theCoord1[1]+halfHeight];

break;

case (theAngle >= 153 && theAngle < 207):

var tr1 = [theCoord1[0]-halfWidth, theCoord1[1]-(halfHeight/3)];

var tr2 = [theCoord1[0]-halfWidth, theCoord1[1]+(halfHeight/3)];

break;

case (theAngle >= 207 && theAngle < 333):

var tr1 = [theCoord1[0]-(halfWidth/3), theCoord1[1]-halfHeight];

var tr2 = [theCoord1[0]+(halfWidth/3), theCoord1[1]-halfHeight];

break;

default:

var tr1 = [theCoord1[0]+halfWidth, theCoord1[1]-(halfHeight/3)];

var tr2 = [theCoord1[0]+halfWidth, theCoord1[1]+(halfHeight/3)];

break;

};

var subPath2 = [[tr1, tr1, tr1, false], [tr2, tr2, tr2, false], [theCoord2, theCoord2, theCoord2, false], true, 1097098272];

var theArray = [subPath1, subPath2];

// create path;

var aPath = createPath2015(theArray, Math.random());

var theShape = solidColorLayer (5, 128, 205);

aPath.remove();

// remove color samplers;

myDocument.colorSamplers[myDocument.colorSamplers.length-1].remove();

myDocument.colorSamplers[myDocument.colorSamplers.length-1].remove();

// reset;

app.preferences.rulerUnits = originalRulerUnits;

myDocument.resizeImage (null, null, originalResolution, ResampleMethod.NONE);

};

};

////// create a path from collectPathInfoFromDesc2012-array //////

function createPath2015(theArray, thePathsName) {

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.POINTS;

// thanks to xbytor;

cTID = function(s) { return app.charIDToTypeID(s); };

sTID = function(s) { return app.stringIDToTypeID(s); };

    var desc1 = new ActionDescriptor();

    var ref1 = new ActionReference();

    ref1.putProperty(cTID('Path'), cTID('WrPt'));

    desc1.putReference(sTID('null'), ref1);

    var list1 = new ActionList();

for (var m = 0; m < theArray.length; m++) {

  var thisSubPath = theArray;

    var desc2 = new ActionDescriptor();

    desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);

    var list2 = new ActionList();

    var desc3 = new ActionDescriptor();

    desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);

    var list3 = new ActionList();

for (var n = 0; n < thisSubPath.length - 2; n++) {

  var thisPoint = thisSubPath;

    var desc4 = new ActionDescriptor();

    var desc5 = new ActionDescriptor();

    desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);

    desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);

    desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);

    var desc6 = new ActionDescriptor();

    desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);

    desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);

    desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);

    var desc7 = new ActionDescriptor();

    desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);

    desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);

    desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);

    desc4.putBoolean(cTID('Smoo'), thisPoint[3]);

    list3.putObject(cTID('Pthp'), desc4);

  };

    desc3.putList(cTID('Pts '), list3);

    list2.putObject(cTID('Sbpl'), desc3);

    desc2.putList(cTID('SbpL'), list2);

    list1.putObject(cTID('PaCm'), desc2);

  };

    desc1.putList(cTID('T   '), list1);

    executeAction(cTID('setd'), desc1, DialogModes.NO);

// name work path;

var check = false;

var x = activeDocument.pathItems.length - 1;

while (check == false) {

if (activeDocument.pathItems.kind == PathKind.WORKPATH) {

app.activeDocument.pathItems.name = thePathsName;

var myPathItem = app.activeDocument.pathItems;

check = true

};

x--

};

/*for (var x = 0; x < activeDocument.pathItems.length; x++) {

  if (activeDocument.pathItems.kind == PathKind.WORKPATH) {

  app.activeDocument.pathItems.name = thePathsName;

  var myPathItem = app.activeDocument.pathItems

  }

  };*/

app.preferences.rulerUnits = originalRulerUnits;

return myPathItem

};

////// get a distance between two points //////

function getDistance (pointOne, pointTwo) {

// calculate the triangle sides;

  var width = pointTwo[0] - pointOne[0];

  var height = pointTwo[1] - pointOne[1];

  var sideC = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

  return sideC

  };

////// get an angle, 3:00 being 0˚, 6:00 90˚, etc. //////

function getAngle (pointOne, pointTwo) {

// calculate the triangle sides;

  var width = pointTwo[0] - pointOne[0];

  var height = pointTwo[1] - pointOne[1];

  var sideC = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

// calculate the angles;

  if (width+width > width) {theAngle = Math.asin(height / sideC) * 360 / 2 / Math.PI}

  else {theAngle = 180 - (Math.asin(height / sideC) * 360 / 2 / Math.PI)};

  if (theAngle < 0) {theAngle = (360 + theAngle)};

// if (theAngle > 180) {theAngle = (360 - theAngle) * (-1)};

  return theAngle

  };

////// create solid color layer //////

function solidColorLayer (theR, theG, theB) {

// solid color layer;

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc16 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref4 = new ActionReference();

        var idcontentLayer = stringIDToTypeID( "contentLayer" );

        ref4.putClass( idcontentLayer );

    desc16.putReference( idnull, ref4 );

    var idUsng = charIDToTypeID( "Usng" );

        var desc17 = new ActionDescriptor();

        var idType = charIDToTypeID( "Type" );

            var desc18 = new ActionDescriptor();

            var idClr = charIDToTypeID( "Clr " );

                var desc19 = new ActionDescriptor();

                var idRd = charIDToTypeID( "Rd  " );

                desc19.putDouble( idRd, theR );

                var idGrn = charIDToTypeID( "Grn " );

                desc19.putDouble( idGrn, theG );

                var idBl = charIDToTypeID( "Bl  " );

                desc19.putDouble( idBl, theB );

            var idRGBC = charIDToTypeID( "RGBC" );

            desc18.putObject( idClr, idRGBC, desc19 );

        var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );

        desc17.putObject( idType, idsolidColorLayer, desc18 );

    var idcontentLayer = stringIDToTypeID( "contentLayer" );

    desc16.putObject( idUsng, idcontentLayer, desc17 );

executeAction( idMk, desc16, DialogModes.NO );

return activeDocument.activeLayer

};

////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////

function sortArrayByIndexedItem(a,b) {

//var theIndex = 1;

if (a[1]<b[1]) return -1;

if (a[1]>b[1]) return 1;

return 0;

};

5 replies

May 20, 2016

I come across a new problem as following.

I notice the circle is created by 4 points, but i don't how to create path to a circle. The other part is also a triangle. I can solve the little triangle by myself.

Thanks all.

c.pfaffenbichler
Community Expert
May 20, 2016

Roughly like this (I am not good at triangulation so I tried getting the value from a circular Path I created with the Ellipse Tool):

// 2016, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

if (myDocument.colorSamplers.length > 1) {

// pixels,;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS

var originalResolution = myDocument.resolution;

myDocument.resizeImage (null, null, 72, ResampleMethod.NONE);

var halfWidth = 25;

var halfHeight = 25;

var theBezierHandle = 0.55226734110625;

var bezierHor = halfWidth*theBezierHandle;

var bezierVert = halfHeight*theBezierHandle;

// get coordinates;

var theCoord1 = myDocument.colorSamplers[myDocument.colorSamplers.length-2].position;

var theCoord2 = myDocument.colorSamplers[myDocument.colorSamplers.length-1].position;

// define rectangle;

var point1 = [theCoord1[0]-halfWidth,theCoord1[1]];

var point2 = [theCoord1[0],theCoord1[1]-halfHeight];

var point3 = [theCoord1[0]+halfWidth,theCoord1[1]];

var point4 = [theCoord1[0],theCoord1[1]+halfHeight];

var subPath1 = [[point1, [point1[0],theCoord1[1]-bezierVert], [point1[0],theCoord1[1]+bezierVert], false],

[point2, [theCoord1[0]+bezierHor,point2[1]], [theCoord1[0]-bezierHor,point2[1]], false],

[point3, [point3[0],theCoord1[1]+bezierVert], [point3[0],theCoord1[1]-bezierVert], false],

[point4, [theCoord1[0]-bezierHor,point4[1]], [theCoord1[0]+bezierHor,point4[1]], false], true, 1097098272];

etc.

c.pfaffenbichler
Community Expert
May 10, 2016

If you do not need Color Samplers otherwise you could link the Script to the vvent »Mk  « for the object »ClSm« in Script Events Manager and then it would run whenever a second Color Sampler is created.

c.pfaffenbichler
Community Expert
May 8, 2016

I guess the Count Tool might be even better than Color Sampler or Pen Tool, one could set any number of pairs of points and then have the shapes created based on those in one go.

May 9, 2016

wow, how to do this? It may solve my problem probably. Please tell me details about the Count Tool. I never used it before.

I cannot run the script with Color Sample Tool (floor 7) successfully. Firstly, open a file.Then, creating a Color Sample? (Please offer some details on this step.)

Thanks!

c.pfaffenbichler
Community Expert
May 7, 2016

Unfortunately I see no current option to collect the mouse position via a Photoshop Script directly.

Work-arounds exist in that

• the Pen Tool and

• the Color Sampler Tool for example

can be used to get the coordinates of a click.

But this is disruptive nonetheless and would not provide for immediate, live interaction per se.

But again a work-around seems possible if one links the event (of creating a new Color Sampler for example) to a Script with Script Events Manager.

May 8, 2016

I get a new idea.

  • creating a new layer.
  • creating a anchor with pen tool. (Layer only has an anchor.)
  • can i select this anchor in the script, then get the coordinate of this anchor? (This step may use script event manager.)
  • creating an special shape with the coordinate by scripts.

Is the idea feasible?

c.pfaffenbichler
Community Expert
May 8, 2016

The following code creates a Shape Layer (as seen in the screenshot) based on the last two Color Samplers, the second to last defines the senator of the rectangle, the last one defines one point of a triangle.

Naturally you could just as easily use a two point path as the basis, possibly even the Ruler Tool; I just picked Solor Samplers because I seldom use them and so it would – for me – be fairly unproblematic to use them for something different, so to speak.

// create shape layer consisting of one rectangle and one triangle based on the last two colorsamplers;

// 2016, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

if (myDocument.colorSamplers.length > 1) {

// pixels,;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS

var originalResolution = myDocument.resolution;

myDocument.resizeImage (null, null, 72, ResampleMethod.NONE);

var halfWidth = 25;

var halfHeight = 12.5;

// get coordinates;

var theCoord1 = myDocument.colorSamplers[myDocument.colorSamplers.length-2].position;

var theCoord2 = myDocument.colorSamplers[myDocument.colorSamplers.length-1].position;

// define rectangle;

var point1 = [theCoord1[0]-halfWidth,theCoord1[1]-halfHeight];

var point2 = [theCoord1[0]+halfWidth,theCoord1[1]-halfHeight];

var point3 = [theCoord1[0]+halfWidth,theCoord1[1]+halfHeight];

var point4 = [theCoord1[0]-halfWidth,theCoord1[1]+halfHeight];

var subPath1 = [[point1, point1, point1, false], [point2, point2, point2, false], [point3, point3, point3, false], [point4, point4, point4, false], true, 1097098272];

// define triangle;

var distances = [[point1, getDistance(point1, theCoord2)], [point2, getDistance(point2, theCoord2)], [point3, getDistance(point3, theCoord2)], [point4, getDistance(point4, theCoord2)]];

distances.sort(sortArrayByIndexedItem);

var subPath2 = [[distances[0][0], distances[0][0], distances[0][0], false], [distances[1][0], distances[1][0], distances[1][0], false], [theCoord2, theCoord2, theCoord2, false], true, 1097098272];

var theArray = [subPath1, subPath2];

// create path;

createPath2015(theArray, Math.random());

var theShape = solidColorLayer (5, 128, 205);

// reset;

app.preferences.rulerUnits = originalRulerUnits;

myDocument.resizeImage (null, null, originalResolution, ResampleMethod.NONE);

};

};

////// create a path from collectPathInfoFromDesc2012-array //////

function createPath2015(theArray, thePathsName) {

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.POINTS;

// thanks to xbytor;

cTID = function(s) { return app.charIDToTypeID(s); };

sTID = function(s) { return app.stringIDToTypeID(s); };

    var desc1 = new ActionDescriptor();

    var ref1 = new ActionReference();

    ref1.putProperty(cTID('Path'), cTID('WrPt'));

    desc1.putReference(sTID('null'), ref1);

    var list1 = new ActionList();

for (var m = 0; m < theArray.length; m++) {

  var thisSubPath = theArray;

    var desc2 = new ActionDescriptor();

    desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);

    var list2 = new ActionList();

    var desc3 = new ActionDescriptor();

    desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);

    var list3 = new ActionList();

for (var n = 0; n < thisSubPath.length - 2; n++) {

  var thisPoint = thisSubPath;

    var desc4 = new ActionDescriptor();

    var desc5 = new ActionDescriptor();

    desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);

    desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);

    desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);

    var desc6 = new ActionDescriptor();

    desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);

    desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);

    desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);

    var desc7 = new ActionDescriptor();

    desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);

    desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);

    desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);

    desc4.putBoolean(cTID('Smoo'), thisPoint[3]);

    list3.putObject(cTID('Pthp'), desc4);

  };

    desc3.putList(cTID('Pts '), list3);

    list2.putObject(cTID('Sbpl'), desc3);

    desc2.putList(cTID('SbpL'), list2);

    list1.putObject(cTID('PaCm'), desc2);

  };

    desc1.putList(cTID('T   '), list1);

    executeAction(cTID('setd'), desc1, DialogModes.NO);

// name work path;

var check = false;

var x = activeDocument.pathItems.length - 1;

while (check == false) {

if (activeDocument.pathItems.kind == PathKind.WORKPATH) {

app.activeDocument.pathItems.name = thePathsName;

var myPathItem = app.activeDocument.pathItems;

check = true

};

x--

};

/*for (var x = 0; x < activeDocument.pathItems.length; x++) {

  if (activeDocument.pathItems.kind == PathKind.WORKPATH) {

  app.activeDocument.pathItems.name = thePathsName;

  var myPathItem = app.activeDocument.pathItems

  }

  };*/

app.preferences.rulerUnits = originalRulerUnits;

return myPathItem

};

////// get a distance between two points //////

function getDistance (pointOne, pointTwo) {

// calculate the triangle sides;

  var width = pointTwo[0] - pointOne[0];

  var height = pointTwo[1] - pointOne[1];

  var sideC = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

  return sideC

  };

////// create solid color layer //////

function solidColorLayer (theR, theG, theB) {

// solid color layer;

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc16 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref4 = new ActionReference();

        var idcontentLayer = stringIDToTypeID( "contentLayer" );

        ref4.putClass( idcontentLayer );

    desc16.putReference( idnull, ref4 );

    var idUsng = charIDToTypeID( "Usng" );

        var desc17 = new ActionDescriptor();

        var idType = charIDToTypeID( "Type" );

            var desc18 = new ActionDescriptor();

            var idClr = charIDToTypeID( "Clr " );

                var desc19 = new ActionDescriptor();

                var idRd = charIDToTypeID( "Rd  " );

                desc19.putDouble( idRd, theR );

                var idGrn = charIDToTypeID( "Grn " );

                desc19.putDouble( idGrn, theG );

                var idBl = charIDToTypeID( "Bl  " );

                desc19.putDouble( idBl, theB );

            var idRGBC = charIDToTypeID( "RGBC" );

            desc18.putObject( idClr, idRGBC, desc19 );

        var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );

        desc17.putObject( idType, idsolidColorLayer, desc18 );

    var idcontentLayer = stringIDToTypeID( "contentLayer" );

    desc16.putObject( idUsng, idcontentLayer, desc17 );

executeAction( idMk, desc16, DialogModes.NO );

return activeDocument.activeLayer

};

////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////

function sortArrayByIndexedItem(a,b) {

//var theIndex = 1;

if (a[1]<b[1]) return -1;

if (a[1]>b[1]) return 1;

return 0;

};

JJMack
Community Expert
May 6, 2016

I do not understand if your drawing interactively with a mouse why would you want to slow the process down trying to script it.  You also can not get the mouse coordinates with scripting and if you could you may be be moveing how would your scriop know when to use the point the mouse is over.

For you all you may need to learn is click move and shift click. straight shart line are easy. You can also use the Pen tool to create a Path then stroke the paths with a tool.

Custom Shapes work well and can be edited.

JJMack
May 8, 2016

Yeah, i know the pen tool and brush tool. The reason i want to use scripts is that i will create the rectangle with sharp corner many many times, maybe more than several thousand. What is a boring thing. In order to make is easier and intersrting,  i want to use scripts.