I have around 200 SVG files on which I need to change the strokecolor to gray and change the strokewidth of all lines to .2pt.
I would like to script out the equivalent of doing in the interface - 'Select ALL' and then entering the .2 pt for the strokewidth manually.
Right now, my script is changing all the colors to gray (working fine) and SOME of the lines to a stroke width of .2pt.
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
var doc = app.activeDocument;
for ( i = 0; i <doc.pathItems.length; i++ ) {
pathArt = doc.pathItems[i];
pathArt.strokeWidth = .2;
pathArt.strokeColor = makeColor(153,153,153);
pathArt.filled = false;
}
function makeColor(r,g,b){
var c = new RGBColor();
c.red = r;
c.green = g;
c.blue = b;
return c;
}
Perhaps I am not selecting all objects through the script correctly?
Is selecting the pathitems as I have done above the correct approach to achieve the equivalent of a CTRL-A, and then some operation manually?
Thanks so much for your time!
As of AI CS3, when a path is not stroked, the .strokeColor property applies while the .strokeWidth property doesn't.
Add the code pathArt.Stroked = True; to fix your problem
Also note that you don't iterate CompoundPathItems
Here is the complete script, that will ask you to select the folder. So select folder that has 200 SVG files. This script will process all SVG files in the selected folder and change stroke color to gray and also change its width.
var folder = Folder.selectDialog();
if (folder) {
app.userInteractionLevel = UserInteractionLevel.DONTDISPLAYALERTS;
var color = makeColor(153, 153, 153);
var files = folder.getFiles("*.svg");
for (var j = 0; j < files.length; j++) {
app.open(files[j]);
var doc = app.activeDocument;
for (i = 0; i < doc.pathItems.length; i++) {
pathArt = doc.pathItems[i];
pathArt.stroked = true;
pathArt.strokeWidth = .2;
pathArt.strokeColor = color;
pathArt.filled = false;
}
doc.close(SaveOptions.SAVECHANGES);
doc = null;
}
}
function makeColor(r, g, b) {
var c = new RGBColor();
c.red = r;
c.green = g;
c.blue = b;
return c;
}
You can change the script for locked and hidden items as well if you want to handle for locked and hidden items.
Related
I have a color code like #8B8989
And i also have 5 different Colors Code
Like
***Red
***Yellow
***Blue
***White
***Black
Now i have to mix this colors code to generate my targeted color code.
What i have tried so far---
So far i tried to add those color hex code and try to achieve my targeted color but so far But its not giving what i expecting
function docalc(colorCode) {
let redCount = 0,
yellowCount = 0;
let oldColor = document.getElementById("output_color_code").value;
if (oldColor != "") {
c = (parseInt(oldColor, 16) + parseInt(colorCode, 16)).toString(16);
console.log(c);
} else {
c = colorCode;
}
document.getElementById("output_color_code").value = c;
document.getElementById("output").style.backgroundColor = c;
let givenColor = document.getElementById("given_color").value;
document.getElementById("given_output").style.backgroundColor = givenColor;
}
What i want to achieve is implemented in https://trycolors.com/game But i failed to find the algorithm of this
Have you considered doing a weighted mean of the components of the hex code? That is, if you have added 3 of color A and 2 of color B, you could break each color down into its Red, Green, and Blue components using the hex code #RRGGBB.
Then, your new color would have (3*Red Component of A + 2*Red Component of B) / (3+2) for its red component, (3*Green Component of A + 2*Green Component of B) / (3+2) for its green component, and (3*Blue Component of A + 2*Blue Component of B) / (3+2).
Keep in mind that each component of the 6-hexdigit color code has a maximum value of 0xFF (255 in decimal), so a sum would eventually just lead to white (#FFFFFF). Additionally, if you don't separate components, then you will see some strange color behavior when one component overflows to another.
You might be able to use the following code as a guide:
// keep track of how many times colors have already been added in some variable addCounter. It probably shouldn't be global, but you'll need a way to keep track of this across many function calls.
var addCounter = 0;
function addColor(colorCode) {
let oldColor = document.getElementById("output_color_code").value;
if (oldColor != "") {
// assuming oldColor and newColor do not contain leading '#'
let oldRed = parseInt(oldColor.slice(0,2),16);
let oldGreen = parseInt(oldColor.slice(2,4),16);
let oldBlue = parseInt(oldColor.slice(4,6),16);
let newRed = parseInt(newColor.slice(0,2),16);
let newGreen = parseInt(newColor.slice(2,4),16);
let newBlue = parseInt(newColor.slice(4,6),16);
let avgRed = oldRed * addCounter + newRed;
let avgGreen = oldGreen * addCounter + newGreen;
let avgBlue = oldBlue * addCounter + newBlue;
let c = avgRed.toString(16) + avgGreen.toString(16) + avgBlue.toString(16);
console.log(c);
} else {
c = colorCode;
}
addCounter++;
document.getElementById("output_color_code").value = c;
document.getElementById("output").style.backgroundColor = "#"+c;
let givenColor = document.getElementById("given_color").value;
document.getElementById("given_output").style.backgroundColor = "#"+c;
}
I am trying to design some code in Apps Script that can be put on any Google Slides presentation and split every text box by paragraphs so every paragraph has its own text box.
I started out using var shape = slide.insertShape(SlidesApp.ShapeType.TEXT_BOX, 50, 50, 300, 300); to make the new text boxes like google describes to use in most of its tutorials but it 'couldn't identify the TEXT_BOX type' so I found .insertTextBox and that seems to work better but I've found other problems.
I can use .getParagraphs to find the number of paragraphs in a text box but I can't tell if it doesn't include the contents of each paragraph or if I'm just not using the correct command to get the text from the paragraph. I have also tried to find an alternative to find the beginning of each paragraph and divide the text from there but I can't find a command for that either. Maybe would I have to use .indexOf to find each /n or /r, or is there a simpler way?
I'm also having a problem where my equations to divide up the text box size are giving me undefined answers and I've tried declaring the variables as numbers but it just makes things worse.
function myFunction() { // get slides in the presentation and establish 'for' variables
var slide = SlidesApp.getActivePresentation().getSlides();
var i;
var j;
var k;
for (i = 0; i < slide.length; i++) { // get the text boxes on each slide
var text = slide[i].getShapes();
for (j = 0; j < text.length; j++) { // get the location of and the paragraphs in each textbox (locations don't work)
var top = text[j].getTop;
var left = text[j].getLeft;
var width = text[j].getWidth;
var height = text[j].getHeight;
var paragraph = text[j].getText().getParagraphs();
for (k = 0; k < paragraph.length; k++){ // make a textbox for each paragraph distributed vertically over the original textbox
var content = text[j].getRange(paragraph[k]); //I was hoping this would fill with the contents of current paragraph
var shapeheight = height / paragraph.length; //NaN and I don't know why
var shapetop = height * k + top; //also doesn't work these should all be numbers
slide[i].insertTextBox(content, left, shapetop, width, shapeheight);
}
text[j].remove(); //delete original textbox on slide
}
}
}
Here are pictures of what I'm trying to do:
Slide before intended changes
Approximate slide after intended changes
I believe your goal as follows.
You want to split each paragraph in a text box as each text box on Google Slides.
You want to achieve this using Google Apps Script.
Modification points:
In your script,
getTop, getLeft, getWidth and getHeight are the method. So please add ().
About var content = text[j].getRange(paragraph[k]), getRange has no arguments.
About var shapeheight = height / paragraph.length, in this case, this can be put outof the for loop.
About var shapetop = height * k + top, in this case, that might be var shapetop = shapeheight * k + top.
When above points are reflected to your script, it becomes as follows.
Modified script:
function myFunction() {
var slide = SlidesApp.getActivePresentation().getSlides();
var i;
var j;
var k;
for (i = 0; i < slide.length; i++) {
var text = slide[i].getShapes();
for (j = 0; j < text.length; j++) {
var top = text[j].getTop(); // Modified
var left = text[j].getLeft(); // Modified
var width = text[j].getWidth(); // Modified
var height = text[j].getHeight(); // Modified
var paragraph = text[j].getText().getParagraphs();
var shapeheight = height / paragraph.length; // Modified
for (k = 0; k < paragraph.length; k++) {
var content = paragraph[k].getRange().asString(); // Modified
var shapetop = shapeheight * k + top; // Modified
slide[i].insertTextBox(content, left, shapetop, width, shapeheight);
}
text[j].remove();
}
}
}
Note:
In the current stage, it seems that AutoFit cannot be set. By this, when slide[i].insertTextBox(content, left, shapetop, width, shapeheight) is used, the text deviates a little from the box. So in this case, how about not using shapeheight? In this case, please modify slide[i].insertTextBox(content, left, shapetop, width, shapeheight); as follows.
var t = slide[i].insertTextBox(content);
t.setLeft(left);
t.setTop(shapetop);
t.setWidth(width);
References:
getTop()
getLeft()
getWidth()
getHeight()
getRange()
insertTextBox(text)
var selectedElements = selection.getSelectedElements();
for (var i = 0; i < selectedElements.length; ++i) {
var selectedElement = selectedElements[i];
// Only modify elements that can be edited as text; skip images and other
// non-text elements.
var text = selectedElement.getElement().editAsText();
// Change the background color of the selected part of the element, or the
// full element if it's completely selected.
if (selectedElement.isPartial()) {
text.setColor(selectedElement.getStartOffset(),
selectedElement.getEndOffsetInclusive(), '#69359c');
}
}
}
The above text takes a selection inside of a Google Doc and changes it to the hex code #69359c (a dark purple). I have searched many websites, many gits, and asked many friends for help with my project.
My end project is this:
Create a menu for Google Docs with my selector (DONE)
Be able to highlight a certain amount of text and change it to an array of colors (ROY G. BIV / the rainbow).
Have the format be only for Google Documents.
If anyone can help me it would be highly appreciated.
I just found this question and am happy to provide some working code from my Rainbow Font Google Docs add-on (Magic Rainbow Unicorns).
The first problem is that you need to set the foreground color on the text, and the second is that the code above only allows for partial paragraph selections.
For whole selections use this code:
var elementText = element.editAsText();
if (elementText) {
var paragraph = elementText.getText();
for (var j = 0; j < paragraph.length; j++) {
elementText.setForegroundColor(j, j, getNextRainbowColour(...));
}
}
For partial selections, I used this:
var elementText = element.asText();
var startIndex = element.getStartOffset();
var endIndex = elements.getEndOffsetInclusive();
for (var j = startIndex; j < endIndex+1; j++) {
elementText.setForegroundColor(j, j, getNextRainbowColour(...));
}
You are pretty close to the answer already. Try iterating over the elements within your 'text' variable, so you can change the background on each one.
You could use something like this to iterate over each letter:
var letters = elementText.getText();
for(var j = 0 ; j< letters.length-1; j++)
{
elementText.setBackgroundColor(j, j+1, getRandomColor())
}
Here is a sample of a function to use different colors:
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ )
{
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
For your last question, since the Text class is not part of Javascript, but from app-script library, this will not work outside Google environment.
Hey guys I'm having an issue that hopefully someone can help me with,
I have a JSFiddle here of applying the averaged colors to new div block,
so I know it is working, I am having trouble applying them to gradient backgrounds though, and I think I have something seriously messed up, here is the repo
the issue is definetly in this portion of code somehow, I recommend cloning it out for review
var isWebkit = 'webkitRequestAnimationFrame' in window;
var values = $.makeArray($('.value'));
for(var i = 0; i < sigma; i++)
{
var newColor = [
Math.floor(minColor[0]+maxIncrements[0]*i),
Math.floor(minColor[1]+maxIncrements[1]*i),
Math.floor(minColor[2]+maxIncrements[2]*i)
];
var hex = this.toHex(newColor[0], newColor[1], newColor[2]);
(isWebkit) ? $(values[i]).css('background', '-webkit-gradient(linear, left top, left bottom, from(#'+hex+'), to(#000));')
: $(values[i]).css('background', '-moz-linear-gradient(top, #'+hex+', #000);');
}
for(var i = 1; i < sigma+1; i++)
{
var newColor = [
Math.min(255,Math.floor(maxColor[0]+minIncrements[0]*i)),
Math.min(255,Math.floor(maxColor[1]+minIncrements[1]*i)),
Math.min(255,Math.floor(maxColor[2]+minIncrements[2]*i))
];
var hex = this.toHex(newColor[0], newColor[1], newColor[2]);
var c = (sigma+i);
if (c <= values.length) // prevent overlap if we have an odd sigma
{
(isWebkit) ? $(values[c]).css('background', '-webkit-gradient(linear, left top, left bottom, from(#'+hex+'), to(#000));')
: $(values[c]).css('background', '-moz-linear-gradient(top, #'+hex+', #000);');
}
}
EDIT
it looks like in my version compared to my fiddle I am NOT iterating, and always end up with a single hex of 000000 ???
The issue was that it was trying to parse a HASH when hashes weren't accounted for
The fix
/** hex parsers */
(
function(a)
{
a["toRGB"] = function(a)
{
var b = parseInt(a.replace('#', ''), 16); //drop our hash if it exists
return[b>>16,b>>8&255,b&255]
};
a["toHex"] = function(a,b,c)
{
return'#'+(c|b<<8|a<<16|1<<24).toString(16).slice(1) // re-add our hash
}
})(this);
Is there any way to access a pathItem's fill opacity with javascript? I can access the overall opacity, but I want to lower the opacity of the fill while keeping the stroke fully opaque.
I can't find anything in the documentation, nor can I find anyone else asking this question.
I can set the overall opacity like so:
var selection = app.activeDocument.selection;
selection[0].opacity = 50;
I've tried every variant of "fillOpacity" that I can think of, like this:
var selection = app.activeDocument.selection;
selection[0].fillOpacity = 50;
selection[0].FillOpacity = 50;
selection[0].fill.opacity = 50;
...but it doesn't work.
Am I going about this wrong, or is this just not possible?
You cannot access it, as you cannot access it normally even in illustrator. This is a Photoshop property only. I checked the documentation as well just to make sure. What you could do is this though and it would accomplish same thing:
doc = app.activeDocument;
i = 0
var selection = doc.selection[i];
var storedColor = doc.selection[i].fillColor;
//new object with only fill, we send it to back so it doesn't overlap stroke, if there is one
var newObject = app.selection[i].duplicate(doc, ElementPlacement.PLACEATEND);
//turn off fill for first object
doc.selection[i].filled = false;
i = i + 1;
newObject.stroked = false;
//apply stored color from earlier to new shape
newObject.fillColor = storedColor;
newObject.opacity = 50;
newObject.name = "50p fill";
What I did to solve the problem is to apply a spotcolor to the objects where I uses the tint property
var docRef = app.activeDocument;
var selectedObjects = docRef.selection;
var theTint;
var fillwithSwatch = function (pathItems, sname ){
for (var i=0;i< pathItems.length; i++){
pathItems[i].fill = true;
theTint = pathItems[i].fillColor.gray;
pathItems[i].fillColor = docRef.swatches.getByName ( sname ).color ;
pathItems[i].fillColor.tint = theTint;
}
}
theTint = fillTint(selectedObjects);
// the spotcolor should be in the swatchpallet already
fillwithSwatch (selectedObjects, "myBlue" );