How can I make the navtitle curve along the path of the slice and wrap the text if it's long.
Image of the wheel above
In long text, use '\n' in the title for wrap.
wheel.createWheel(["Long\ntext"]);
Currently, the navtitle curve along the path is an RC feature, so please use the source code instead of the last release.
You can find the new properties in this CodePen: https://codepen.io/softwaretailoring/pen/RQYzWm
var piemenu = new wheelnav("wheelDiv");
// New properties in wheelnav.js v1.8.0
piemenu.titleCurved = true;
piemenu.titleCurvedClockwise = false;
piemenu.titleCurvedByRotateAngle = false;
Unfortunately, the two above properties don't work together. :(
UPDATE: There is a way to achieve your needs. You can use two wheels on each other.
var piemenu = new wheelnav("wheelDiv");
setMenu(piemenu); // Set common properties
piemenu.titleRadiusPercent = 0.65; // Positioning first title
piemenu.markerEnable = true;
piemenu.slicePathFunction = slicePath().DonutSlice;
piemenu.sliceClickablePathFunction = slicePath().DonutSlice;
piemenu.titleHoverAttr = { fill: "#333" };
piemenu.createWheel(["Hello", "world!", "-------"]);
var piemenu2 = new wheelnav("wheelDiv2", piemenu.raphael);
setMenu(piemenu2); // Set common properties
piemenu2.wheelRadius = 520; // Positioning second title
piemenu2.slicePathFunction = slicePath().NullSlice; // There is no slice, only title
piemenu2.createWheel(["Bello", "space!", "*******"]);
// Link navigateFunctions to each other
for (var i = 0; i < piemenu.navItems.length; i++) {
piemenu.navItems[i].navigateFunction = function () {
piemenu2.navigateWheel(Math.abs(this.itemIndex));
}
}
for (var i = 0; i < piemenu2.navItems.length; i++) {
piemenu2.navItems[i].navigateFunction = function () {
piemenu.navigateWheel(Math.abs(this.itemIndex));
}
}
Here is a new CodePen for wrapped and curved text: https://codepen.io/softwaretailoring/pen/eLNBYz
Related
I Would like to create a script for photoshop who allow me to search some files with a specific name (for example : 300x250_F1.jpg, 300x250_F2.jpg, 300x600_F1.jpg, etc... ) in differents subfolders (all in the same parent folder) and after load them in my active document. The problem is names of subfolders will be everytime differents.
I definitely need some help :)
i found a code which almost do what i want (thank you).
I'm almost good but i have a problem: if the variable "mask" have only one value, it works. But with few values, it doesn't work anymore.
I think it's because i made an array with the mask variable and i have to update the script...
var topFolder = Folder.selectDialog("");
//var topFolder = new Folder('~/Desktop/PS_TEST');
var fileandfolderAr = scanSubFolders(topFolder, /\.(jpg)$/i);
//var fileandfolderAr = scanSubFolders(topFolder, /\.(jpg|tif|psd|bmp|gif|png|)$/i);
var fileList = fileandfolderAr[0];
var nom = decodeURI(fileList);
//all file paths found and amount of files found
//alert("fileList: " + nom + "\n\nFile Amount: " + fileList.length);
//alert(allFiles);
for (var a = 0; a < fileList.length; a++) {
var docRef = open(fileList[a]);
//do things here
}
function scanSubFolders(tFolder, mask) { // folder object, RegExp or string
var sFolders = [];
var allFiles = [];
var mask = ["300x250_F1", "300x250_F2"];
sFolders[0] = tFolder;
for (var j = 0; j < sFolders.length; j++) { // loop through folders
var procFiles = sFolders[j].getFiles();
for (var i = 0; i < procFiles.length; i++) { // loop through this folder contents
if (procFiles[i] instanceof File) {
if (mask == undefined) {
allFiles.push(procFiles); // if no search mask collect all files
}
if (procFiles[i].fullName.search(mask) != -1) {
allFiles.push(procFiles[i]); // otherwise only those that match mask
}
}
else if (procFiles[i] instanceof Folder) {
sFolders.push(procFiles[i]); // store the subfolder
scanSubFolders(procFiles[i], mask); // search the subfolder
}
}
}
return [allFiles, sFolders];
}
There are several ways you can accomplish this without reassigning mask within the scanSubFolders function.
Solution 1: use a regex
The function is already set up to accept a regex or string as a mask. You just need to use one that would match the pattern of the files you're targeting.
var fileandfolderAr = scanSubFolders(topFolder, /300x250_F(1|2)/gi);
Solution 2: call the function within a loop
If regex isn't your thing, you could still utilize an array of strings, but do it outside the function. Loop the array of masks and call the function with each one, then execute your primary logic on the results of each call.
var topFolder = Folder.selectDialog("");
var myMasks = ["300x250_F1", "300x250_F2"];
for (var index in myMasks) {
var mask = myMasks[index]
var fileandfolderAr = scanSubFolders(topFolder, mask);
var fileList = fileandfolderAr[0];
for (var a = 0; a < fileList.length; a++) {
var docRef = open(fileList[a]);
//do things here
}
}
Don't forget to remove var mask = ["300x250_F1", "300x250_F2"]; from within the scanSubFolders function or else these won't work.
I'm working on a script that should go through a photoshop document and relink all visible linked objects to a new specified file. I've gotten the loop working so that it cycles through every layer and collects only the visible layers, but for the life of me I can't find if there's a method available to relink a smart object. The closest I've found is this script:
https://gist.github.com/laryn/0a1f6bf0dab5b713395a835f9bfa805c
but when it gets to desc3.putPath(idnull, new File(newFile));, it spits out an error indicating that the functionality may not be present in the current Photoshop version. The script itself is 4 years old so it may be out of date.
Any help would be appreciated!
MY script as it stands is below:
// SELECT FILE //
var files = File.openDialog("Please select new linked file");
var selectedFile = files[0];
// GET ALL LAYERS //
var doc = app.activeDocument;
var allLayers = [];
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers)
{
for (var m = 0; m < doc.layers.length; m++)
{
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer")
{
allLayers.push(theLayer);
}
else
{
collectAllLayers(theLayer, allLayers);
}
}
return allLayers;
}
// GET VISIBLE LAYERS //
var visibleLayers = [];
for (i = 0; i < allLayers.length; i++)
{
var layer = allLayers[i];
if (layer.visible && layer.kind == LayerKind.SMARTOBJECT)
{
visibleLayers.push(layer);
}
}
// REPLACE LAYERS
for (i = 0; i < visibleLayers.length; i++)
{
var layer = visibleLayers[i];
//--> REPLACE THE FILE HERE
}
Note: I am aware that this script currently may be error-prone if you don't know exactly how it works; I'm not intending to publish it at this time so I'm not super concerned with that at the moment. Mostly I just need the core functionality to work.
I used an AM function for getting visible smart objects — it works much faster. But if you want you can use yours. The important bit is relinkSO(path);: it'll also work in your script (just don't forget to select a layer: activeDocument.activeLayer = visibleLayers[i];)
Note that it works similar to Photoshop Relink to File command — if used on one instance of Smart Object all the instances are going to be relinked. If you want to relink only specific layers you'll have to break instancing first (probably using the New Smart Object via Copy command)
function main() {
var myFile = Folder.myDocuments.openDlg('Load file', undefined, false);
if (myFile == null) return false;
// gets IDs of all smart objects
var lyrs = getLyrs();
for (var i = 0; i < lyrs.length; i++) {
// for each SO id...
// select it
selectById(lyrs[i]);
// relink SO to file
relinkSO(myFile);
// embed linked if you want
embedLinked()
}
function getLyrs() {
var ids = [];
var layers, desc, vis, type, id;
try
{
activeDocument.backgroundLayer;
layers = 0;
}
catch (e)
{
layers = 1;
}
while (true)
{
ref = new ActionReference();
ref.putIndex(charIDToTypeID('Lyr '), layers);
try
{
desc = executeActionGet(ref);
}
catch (err)
{
break;
}
vis = desc.getBoolean(charIDToTypeID("Vsbl"));
type = desc.getInteger(stringIDToTypeID("layerKind"));
id = desc.getInteger(stringIDToTypeID("layerID"));
if (type == 5 && vis) ids.push(id);
layers++;
}
return ids;
} // end of getLyrs()
function selectById(id) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID('Lyr '), id);
desc.putReference(charIDToTypeID('null'), ref);
executeAction(charIDToTypeID('slct'), desc, DialogModes.NO);
} // end of selectById()
function relinkSO(path) {
var desc = new ActionDescriptor();
desc.putPath( charIDToTypeID('null'), new File( path ) );
executeAction( stringIDToTypeID('placedLayerRelinkToFile'), desc, DialogModes.NO );
} // end of relinkSO()
function embedLinked() {
executeAction( stringIDToTypeID('placedLayerConvertToEmbedded'), undefined, DialogModes.NO );
} // end of embedLinked()
}
app.activeDocument.suspendHistory("relink SOs", "main()");
I'm trying to select some image files via a prompt, then add those files to the active document. Here's what I have so far:
#target photoshop
doc = app.activeDocument;
// choose image files
var files = File.openDialog(undefined,undefined,true);
// for each image, add to new layer and insert into doc
for (var file in files) {
var layer = doc.artLayers.add();
layer.image = file; // this doesn't work.
}
What's layer.image? ArtLayer doesn't have this property. Maybe placing will work better in your case:
doc = app.activeDocument;
// choose image files
var files = File.openDialog(undefined, undefined, true);
// for each image, add to new layer and insert into doc
for (var i = 0; i < files.length; i++)
{
var layer = placeImage(files[i]);
}
function placeImage(imageFile)
{
var desc554 = new ActionDescriptor();
desc554.putPath(cTID('null'), imageFile);
desc554.putEnumerated(cTID('FTcs'), cTID('QCSt'), cTID('Qcsa'));
var desc555 = new ActionDescriptor();
desc555.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), 0.000000);
desc555.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), 0.000000);
desc554.putObject(cTID('Ofst'), cTID('Ofst'), desc555);
executeAction(cTID('Plc '), desc554, DialogModes.NO);
return activeDocument.activeLayer
};
function cTID(s)
{
return app.charIDToTypeID(s);
};
function sTID(s)
{
return app.stringIDToTypeID(s);
};
Also Photoshop doesn't like when for...in loops are used on Array (sometimes it works, sometimes it doesn't: in case of File object it doesn't work)
I've made a particle system in P5.js that explodes particles on mousepressed(). However, I'd also like expanding circles to output on mousepressed(). I was able to draw a circle on mousepressed(), however it seems to be under the background. I am having a brain fart on this. Why isn't the circle appearing along with the particles, above the black background? Thanks for help!
var lifeConstant = 50000;
var startVelMin = -10;
var startVelMax = 7;
var drag = -50;
var planetArray = [];
var planet;
var planet0;
var planet1;
var planet3;
//var planets = ['planet1.gif', 'planet2.gif', 'planet3.gif', 'planet4.gif']// for loop to loop through image files
//for (var i = 0; i < planets.length; i++) { //
function preload(){
//for (var i = 0; i < planetArray.length; i++) {
planet = loadImage('Assets/planet2.gif');
append(planetArray, planet);
planet3 = loadImage('Assets/planet3.gif');
append(planetArray, planet3);
planet0 = loadImage('Assets/planet4.gif');
append(planetArray, planet0);
planet1 = loadImage('Assets/planet1.gif');
append(planetArray, planet1);
}
//planetArray.add(planet);
function setup() {
createCanvas(windowWidth, windowHeight);
systems = [];
background(51);
}
function draw() {
background(0)
for (i = 0; i < systems.length; i++) {
systems[i].run();
systems[i].addParticle();
}
if (systems.length==0) {
fill(255);
textAlign(CENTER);
textSize(42);
text("Click mouse to create Big Bangs", width/2, height/2);
}
}
function mousePressed() {
this.p = new ParticleSystem(createVector(mouseX, mouseY));
systems.push(p);
fill(230,120, 0);
ellipse(mouseX, mouseY, 100, 100);
}
// A simple Particle class
var Particle = function(position) {
this.acceleration = createVector(0, .1);
this.velocity = createVector(random(startVelMin,startVelMax), random(startVelMin,startVelMax));
this.position = position.copy();
this.lifespan = lifeConstant;
};
Particle.prototype.run = function() {
this.update();
this.display();
};
// Method to update position
Particle.prototype.update = function(){
this.velocity.add(drag*this.acceleration);
this.position.add(this.velocity);
this.lifespan -= 150;
};
// Method to display
Particle.prototype.display = function () {
//fill(random(255), random(255), random(200));
//stroke(20, this.lifespan);
//strokeWeight(1);
//fill(random(255),this.lifespan);
//ellipse(this.position.x, this.position.y, 15, 15);
image(planetArray[floor(random(4))], this.position.x, this.position.y, 15, 15);
};
// Is the particle still useful?
Particle.prototype.isDead = function () {
if (this.lifespan < 0) {
return true;
} else {
return false;
}
};
var ParticleSystem = function (position) {
this.origin = position.copy();
this.particles = [];
};
ParticleSystem.prototype.addParticle = function () {
// Add either a Particle or CrazyParticle to the system
if (int(random(0, 2)) == 0) {
p = new Particle(this.origin);
}
else {
p = new
CrazyParticle(this.origin);
}
this.particles.push(p);
};
ParticleSystem.prototype.run = function () {
for (var i = this.particles.length - 1; i >= 0; i--) {
var p = this.particles[i];
p.run();
if (p.isDead()) {
this.particles.splice(i, 1);
}
}
};
// A subclass of Particle
function CrazyParticle(origin) {
// Call the parent constructor, making sure (using Function#call)
// that "this" is set correctly during the call
Particle.call(this, origin);
// Initialize our added properties
this.theta = 0.0;
};
// Create a Crazy.prototype object that inherits from Particle.prototype.
// Note: A common error here is to use "new Particle()" to create the
// Crazy.prototype. That's incorrect for several reasons, not least
// that we don't have anything to give Particle for the "origin"
// argument. The correct place to call Particle is above, where we call
// it from Crazy.
CrazyParticle.prototype = Object.create(Particle.prototype); // See note below
// Set the "constructor" property to refer to CrazyParticle
CrazyParticle.prototype.constructor = CrazyParticle;
// Notice we don't have the method run() here; it is inherited from Particle
// This update() method overrides the parent class update() method
CrazyParticle.prototype.update=function() {
Particle.prototype.update.call(this);
// Increment rotation based on horizontal velocity
this.theta += (this.velocity.x * this.velocity.mag()) / 10.0;
}
// This display() method overrides the parent class display() method
CrazyParticle.prototype.display=function() {
// Render the ellipse just like in a regular particle
// Particle.prototype.display.call(this);
}
The mousePressed() function is called whenever the mouse button is pressed down. The draw() function is called 60 times per second. So anything you draw in the mousePressed() function will almost immediately be drawn over with whatever you draw in the draw() function.
You need to have all of your drawing code called from your draw() function. You could do this by using a variable that keeps track of whether the mouse is pressed. Luckily, p5.js already has a variable that does exactly that: mouseIsPressed
I'm using ExtendScript for scripting Adobe Illustrator. I was wondering if there was a sneaky way or a script available to programmatically capture and then replicate a path shape, sort of JavaScript's .toSource() equivalent.
Thanks
Try this:
main();
function main(){
var doc = app.activeDocument; // get the active doc
var coords = new Array(); // make a new array for the coords of the path
var directions = new Array();
var sel = doc.selection[0];// get first object in selection
if(sel == null) {
// check if something is slected
alert ("You need to sevlect a path");
return;
}
var points = sel.pathPoints;// isolate pathpoints
// loop points
for (var i = 0; i < points.length; i++) {
// this could be done in one lines
// just to see whats going on line like
//~ coords.push(new Array(points[i].anchor[0],points[i].anchor[1]));
var p = points[i]; // the point
var a = p.anchor; // his anchor
var px = a[0];// x
var py = a[1]; // y
var ldir = p.leftDirection;
var rdir = p.rightDirection;
directions.push(new Array(ldir,rdir));
coords.push(new Array(px,py));// push into new array of array
}
var new_path = doc.pathItems.add(); // add a new pathitem
new_path.setEntirePath(coords);// now build the path
// check if path was closed
if(sel.closed){
new_path.closed = true;
}
// set the left and right directions
for(var j = 0; j < new_path.pathPoints.length;j++){
new_path.pathPoints[j].leftDirection = directions[j][0];
new_path.pathPoints[j].rightDirection = directions[j][1];
}
}