I’m trying to find Java script for photoshop, that will crop to a square based on selection, preserving resolution of the image
Selections are irregular
This is very easy and a perfectly valid question. PhotoShop can crop to selection with a function.
cropToSelection();
// crop to selection
function cropToSelection()
{
executeAction( charIDToTypeID( "Crop" ), new ActionDescriptor(), DialogModes.NO );
}
But if you want the selection bounds coordinates then use:
var lb = get_selection_bounds();
// alerts current selection bounds
alert(lb[0] + ", " + lb[1] + ", " + lb[2] + ", " + lb[3] );
// function GET SELECTION BOUNDS ()
// ----------------------------------------------------------------
function get_selection_bounds()
{
// Only works with a selection
var x = parseFloat(app.activeDocument.selection.bounds[0]);
var y = parseFloat(app.activeDocument.selection.bounds[1]);
var x1 = parseFloat(app.activeDocument.selection.bounds[2]);
var y1 = parseFloat(app.activeDocument.selection.bounds[3]);
// return the results as an array
return [x, y, x1, y1];
}
Related
I'm using the jQuery Flot Charts plugin in one of my projects. I have several charts standing in the same column and what I'm trying to do is: Show the crosshair on all of the charts if you hover on any of them. I'm doing this successfully using the following code.
//graphs - this is an object which contains the references to all of my graphs.
$.each(graphs, function(key, value) {
$(key).bind("plothover", function (event, pos, item) {
$.each(graphs, function(innerKey, innerValue) {
if(key != innerKey) {
innerValue.setCrosshair({x: pos.x});
}
});
if(item) {
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
console.log("x:" + x + ", " + "y:" + y);
}
});
});
I'm iterating over the graphs, adding the crosshair and bind it to each other. So, now, when you hover over one of the graphs you'll see the crosshair in the same position on all of the others.
No problems with this. However I'm having problems with the second part of my code:
if(item) {
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
console.log("x:" + x + ", " + "y:" + y);
}
And the problem is that I'm getting the console.log to print values only when I hover the actual point with my mouse while I want to get that value whenever the crosshair crosses that point, not necessarily the mouse pointer. Any clues what I'm doing wrong or maybe there's a setting in the graph options for that to work?
And another thing is that I can get the value for one graph only - the one my mouse is on, I don't seem to be able to get the values for the rest of the graphs where the crosshair is also moving.
The highlighting with
if(item) {
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
console.log("x:" + x + ", " + "y:" + y);
}
only works when the cursor is near a point (otherwise item is null).
To get the nearest point to the crosshair, you have to do the highlighting manually by searching the nearest point and interpolate (for every graph). The code for that could look like this:
var axes = value.getAxes();
if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max ||
pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
return;
}
$('#output').html("x: " + pos.x.toPrecision(2));
$.each(graphs, function(innerKey, innerValue) {
var i, series = innerValue.getData()[0];
// Find the nearest points, x-wise
for (i = 0; i < series.data.length; ++i) {
if (series.data[i][0] > pos.x) {
break;
}
}
// Now Interpolate
var y,
p1 = series.data[i - 1],
p2 = series.data[i];
if (p1 == null) {
y = p2[1];
} else if (p2 == null) {
y = p1[1];
} else {
y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
}
$('#output').html($('#output').html() + "<br />" + "y (" + innerValue.getData()[0].label + "): " + y.toPrecision(2));
See this fiddle for a full working example. Some Remarks to the new code and fiddle:
has sine and cosine values as example data, so uses floating point numbers, change accordingly for int numbers and/or date values
uses a <p> element for output instead of the console
point-finding and interpolation code can be optimized further if needed (basic version here taken from the example on the Flot page)
works only if there is only one data series per graph
this is my first post on here. I am a beginner at java and extendscript.
I am using this script to find black pixels in a 100x100 grid which it scans line by line. X followed by Y increment.
But when it gets to the end of the first line of 10 it loses the x px unit value, then it loses the y px unit value. it still works but I am wondering if they are numbers or unit values..?
#target photoshop
app.bringToFront();
app.preferences.rulerUnits = Units.PIXELS;
//Removes All Color Samplers
app.activeDocument.colorSamplers.removeAll();
// Show Color Sampler/ I don't know how to do this with extend script - generated in console with script listner
// =======================================================
var idShw = charIDToTypeID( "Shw " );
var desc80 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list40 = new ActionList();
var ref68 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idBckg = charIDToTypeID( "Bckg" );
ref68.putProperty( idLyr, idBckg );
list40.putReference( ref68 );
desc80.putList( idnull, list40 );
executeAction( idShw, desc80, DialogModes.NO );
// =======================================================
//Gets Document Width & Height
var docWidth = activeDocument.width.as('px');
var docHeight = activeDocument.height.as('px');
//Default x Position - as a Unit Value in pixels needed for sampler position
var xPosition = new UnitValue( 0, 'px' );
var yPosition = new UnitValue( 0, 'px');
//End point Var - NOT USED
//var xEndPoint = activeDocument.width.as('px');
//var yEndPoint = activeDocument.height.as('px');
//Comparison Color Variables [Kind of like a crude memory, add more for more comparison, or recognized perception]
var WhiteColor = new RGBColor(); // initial default colour
WhiteColor.red = 255; // rest of the values default to 0
WhiteColor.green = 255;
WhiteColor.blue = 255
var BlackColor = new RGBColor(); // initial default colour
BlackColor.red = 0; // rest of the values default to 0
BlackColor.green = 0;
BlackColor.blue = 0;
//======================================================================
while( xPosition < docWidth &&
yPosition < docHeight){ // If the position of the sampler x is less than the doc width x Height - Stops at end of Doc
//Adds a color sampler
var sample = activeDocument.colorSamplers.add( [ xPosition + .5 , yPosition + .5 ] ); // X, Y position, Y position is set at 0 does not change**
app.backgroundColor=sample.color; //Sets thte background color to the sample color, maybe their could be a better way to store this
var colorB = new RGBColor(); // New color var to store background color
colorB = app.backgroundColor; //Assigns the background color to previous declare var
//Nested IF else statements
//Notes* Alerts Sampled Color - need to store this info, I don't know if I should store this as a RGB value?
// White Pixel detect
if (colorB.rgb.red === WhiteColor.red &&
colorB.rgb.blue === WhiteColor.blue &&
colorB.rgb.green === WhiteColor.green)
{
//alert("White Pixel");
}
// Black Pixel detect
else if (colorB.rgb.red === BlackColor.red &&
colorB.rgb.blue === BlackColor.blue &&
colorB.rgb.green === BlackColor.green)
{
alert("Black Pixel " + "x : " + xPosition + " y : " + yPosition + '\n'
+ "R = " + (colorB.rgb.red) + '\n'
+ "G = "+ (colorB.rgb.green) + '\n'
+ "B = "+ (colorB.rgb.blue));
}
// Other Pixel detect - Error option
else {
alert("Other Color");
}
//Final process
app.activeDocument.colorSamplers.removeAll(); //Removes the sampler so that there arn't to many
xPosition++; //increases the position by one, this is the end of the loop, starts again until while statement is void
//Once it arrives at the end of the line, increase y -value & reset x position
if (xPosition == docWidth) {
xPosition = xPosition - docWidth;
yPosition++;
}
} //bottom bracket of while statement
//======================================================================
Is x && y = z valid javascript?
When running the below code in ESTK it returns undefined.
var x,y;
// x = y = 12; // returns 12
x && y = 13; // returns undefined
$.writeln(x);
It gets even stranger when I comment out the third line and comment in the second. The result is then:
12
After that comment out the second and comment in the third again and the result still is:
12
This stays until I restart ESTK.
Anyway. I never saw a expression like x && y = z in JS. This could be your error.
Is there a zooming function in nvd3 that I can directly type in my R source code (doesn't matter if it requires javascript as long as I don't have to change nvd3 source code)? I tried the lineWithFocusChart, but that only zooms along the x-axis, whereas I would like to ideally draw a box around the zoom section and it will zoom to where I drew the box. Even if that's not possible, if nvd3 supports any kind of 2-d zoom, that would be awesome! I have provided a reproducible example of what I have so far, but I have not found a feature for the zoom I am looking for yet. Thank you!
library(rCharts)
temp <- data.frame(x = 1:100, y = 1:100, z = c(rep(1,50), rep(0,50)))
g <- nPlot(y ~ x, group = "z", data = temp, type = "lineChart")
g$templates$script <- "http://timelyportfolio.github.io/rCharts_nvd3_templates/chartWithTitle_styled.html"
g$set(title = "Example")
g$chart(transitionDuration = -1,
tooltipContent = "#! function(key, x, y) {
return 'z: ' + key + '<br/>' + 'x: ' + x + '<br/>' + 'y: ' + y
}!#",
showLegend = FALSE, margin = list(left = 200,
right = 100,
bottom = 100,
top = 100))
g$xAxis(axisLabel = "x")
g$yAxis(axisLabel = "y", width = 40)
g
You could use Highcharts with the zoomType option.
For example:
require(rCharts)
names(iris) = gsub("\\.", "", names(iris))
g<-hPlot(SepalLength ~ SepalWidth, data = iris, color = 'Species', type = 'line')
g$chart(zoomType = 'xy')
g
You can then drag and hold on the plot to zoom in an area.
I am trying to get the id of the shape my mouse is currently hovering over.
my shapes are in a container
// creating the layers
gridLayer = new PIXI.DisplayObjectContainer ();
gridLayer.setInteractive(true);
stage.addChild(gridLayer);
and i am creating each shape like this;
function drawHexagon(x,y, size, gap,scale, color, iterI, iterJ, type) {
var shape = new PIXI.Graphics();
// set a fill and line style
shape.beginFill(color);
shape.lineStyle(1, 0xa0a0a0, 1);
size = size-gap;
for (i = 0; i < 7; i++) {
angle = 2 * Math.PI / 6 * (i + 0.5);
var x_i = x + size * Math.cos(angle);
var y_i = y + size * Math.sin(angle);
if (i === 0) {
shape.moveTo(x_i, scale *y_i)
}
else {
shape.lineTo(x_i, scale * y_i)
}
};
shape.endFill();
// calculate and save the axial coordinates
var cX = iterJ - (iterI - (iterI&1)) / 2;
var cZ = iterI;
var cY = -1*(cX+cZ);
shape.hexId = cX + "x" + cY + "y" + cZ + "z";
shape.hexPosX = x;
shape.hexPosY = y;
shape.setInteractive(true);
shape.mouseover = function(mouseData){
console.log("MOUSE OVER " + shape.hexId);
}
shape.click = function(mouseData){
console.log("MOUSE CLICK " + shape.hexId);
}
gridLayer.addChild(shape);
}
However, clicking on any shape or hovering over it is not showing me anything in the console. what am i doing wrong?
i have tried both
shape.setInteractive(true)
and
shape.interactive = true
but neither seems to work for me.
EDIT: i have added a jsfiddle. it doesnt works (i dont know how to link things in jsfiddle) but you can see my entire code in there.
http://jsfiddle.net/9aqHz/1/
For a PIXI.Graphics object to be interactive you need to set a hitArea shape (it can be a Rectangle, Circle or a Polygon):
shape.hitArea = new PIXI.Polygon([
new PIXI.Point(/* first point */),
new PIXI.Point(/* second point */),
new PIXI.Point(/* third point */),
new PIXI.Point(/* fourth point */),
new PIXI.Point(/* fifth point */)
]);
Another approach would be to generate a texture from the shape and use a Sprite, but the hit area would be the entire rectangular bounds of the hexagon:
var texture = shape.generateTexture();
var sprite = new PIXI.Sprite(texture);
sprite.setInteractive(true);
sprite.anchor.set(0.5, 0.5);
Fiddle with this applied to your example
#imcg I updated your code so it workes with Pixi 3.0.8
- sprite.setInteractive(true);
+ shape.interactive = true;
+ shape.buttonMode = true;
- sprite.setInteractive(true)
+ sprite.interactive = true;
+ sprite.buttonMode = true;
http://jsfiddle.net/LP2j8/56/
I will add a bit of info for anyone who is in the same boat i was in;
When you define a shape as a geom, you have to explicitly state a hitarea.
So adding the following code makes it work;
shape.hitArea = new PIXI.Polygon(vertices);
shape.interactive = true;
shape.click = function(mouseData){
console.log("MOUSE CLICK " + shape.hexId);
}
But, when you define a shape as a sprite/texture, you dont need to do this.
in cases of sprites, just setting shape.interactive = true for the sprite is sufficient. You dont need to set the interactive property for the parent object or the stage.
With the below code, position of a mesh is returned as (0, 0, 0) but it is not. So is the positioın vector calculated after render process?
me.scene.add(objMesh); //me is a project class
objMesh.updateMatrixWorld(true);
alert(objMesh.position.x + ',' + objMesh.position.y + ',' + objMesh.position.z);
objMesh is created from objfile, it is added to the scene correctly and centroid is approx (-8, 3, 0)
but position vector of objMesh is (0, 0, 0) do we have to auto calculate something first or should i calculate it manually from geometry vertices of the mesh ?
http://81.214.75.32:8181/admin is the url
the site is in Turkish so i will translate the UI items
in the site there is "Dosya" menu item
oppen the menu item and select "Proje Aç"
a dialog appears
in that dialog select MUTFAK_1
scene will appear
in that scene, every meshes position is (0, 0, 0)
is that possible :)
object.position is always local to the object. If you want to get the position in world space you need to get it from object.matrixWorld.
Try with this:
scene.add(objMesh);
scene.updateMatrixWorld(true);
var position = new THREE.Vector3();
position.getPositionFromMatrix( objMesh.matrixWorld );
alert(position.x + ',' + position.y + ',' + position.z);
r58
Update:
The function getPositionFromMatrix() has been renamed to setFromMatrixPosition().
For finding where in world space is the geometry centroid, try this:
objMesh.geometry.computeBoundingBox();
var boundingBox = objMesh.geometry.boundingBox;
var position = new THREE.Vector3();
position.subVectors( boundingBox.max, boundingBox.min );
position.multiplyScalar( 0.5 );
position.add( boundingBox.min );
position.applyMatrix4( objMesh.matrixWorld );
alert(position.x + ',' + position.y + ',' + position.z);
r58
Yeah. after some talk with mrdoob, i realized that .position of objects are local to theirselves. My situation was to find the center point of my mesh considering the vertices. Below is the code to get the centroid which came from an answer #447 ( https://github.com/mrdoob/three.js/issues/447 )
geom.centroid = new THREE.Vector3();
for (var i = 0, l = geom.vertices.length; i < l; i++) {
geom.centroid.addSelf(geom.vertices[i]);
}
geom.centroid.divideScalar(geom.vertices.length);
Now we have centroid of geometry...
Update
according to https://github.com/mrdoob/three.js/wiki/Migration, the .addSelf had been renamed to .add after r55
alert(objMesh.matrixWorld.getPosition().x + ',' + objMesh.matrixWorld.getPosition().y + ',' + objMesh.matrixWorld.getPosition().z);
You can use .getWorldPosition() method of a mesh, to get its absolute position.
Docs here: https://threejs.org/docs/#api/en/core/Object3D.getWorldPosition
According to this post the center of gravity C for a mesh can be found by
C = [sum of all (A*R)] / [sum of all A]
A = (area of a face * 2)
R = face centroid = average of vertices making the face
and here is the code in three.js
function calculateCenterOfMass( mesh ){
var centroid = new THREE.Vector3();
// centroid = centroidNominator / centroidDenominator;
var centroidNominator = new THREE.Vector3();
var centroidDenominator = 0;
for(var i = 0; i < mesh.geometry.faces.length; i++){
var Pi = mesh.geometry.faces[i].a;
var Qi = mesh.geometry.faces[i].b;
var Ri = mesh.geometry.faces[i].c;
var a = new THREE.Vector3(mesh.geometry.vertices[Pi].x, mesh.geometry.vertices[Pi].y, mesh.geometry.vertices[Pi].z);
var b = new THREE.Vector3(mesh.geometry.vertices[Qi].x, mesh.geometry.vertices[Qi].y, mesh.geometry.vertices[Qi].z);
var c = new THREE.Vector3(mesh.geometry.vertices[Ri].x, mesh.geometry.vertices[Ri].y, mesh.geometry.vertices[Ri].z);
var ab = b.clone().sub(a);
var ac = c.clone().sub(a);
var cross = new THREE.Vector3();
cross.crossVectors( ab, ac );
var faceArea = cross.lengthSq() / 2;
var faceCentroid = new THREE.Vector3( (a.x + b.x + c.x)/3, (a.y + b.y + c.y)/3, (a.z + b.z + c.z)/3 );
if (!isNaN(faceArea)){
centroidNominator.add(faceCentroid.multiplyScalar(faceArea));
centroidDenominator += faceArea;
}
}
centroid = centroidNominator.divideScalar(centroidDenominator);
return centroid;
}
Tip. If you are getting the position of a mesh within an imported model (e.g. GLTF) make sure that the mesh has it's origin set to it's own centre before exporting. i.e. don't apply transforms to it. Otherwise it's world centre will be the centre of the gltf and not the mesh itself.