How do you change the color of a text layer in After Effects 2017 using ExtendScript? - extendscript

I need to know how to change the color of a text layer in After Effects 2017 using ExtendScript. I can change the text itself very simply, like so:
var comp=app.project.item(10);
comp.layer(1).property('Source Text').setValue('My Text Here');
But how do I set the color of that text layer? I would think this would be very simple but despite much searching I haven't found anything that clearly explains how to do this.
Thanks in advance!

Page 182 of the After Effects CS6 Scripting guide (the most recent documentation that Adobe have deigned to give us) describes the TextDocument object, which is the data type for a text layer's Source Text property. Amongst the attributes is fillColor and strokeColor.
edit it's not as simple as it seems, you can't just assign the values to the source text, you have to make a new textDocument object, make your changes to it, and then assign the value of the source text property to the textDocument object you created.
So you can set it thus:
var textProp = comp.layer(1).property('Source Text');
//make a new textDocument, copying the values of the current one
var textDocument = textProp.value;
// change any attributes of the textDocument here, e.g.:
textDocument.fillColor = [R, G, B];
// write the textDocument over the existing one
textProp.setValue(textDocument);
R, G and B are floating-point values, where 1.0 ⇒ 255 in 8-bit colour.
You can also see that scripting guide online at aeenhancers There's a typo where it describes the constructor, it says newTextDocument it should be new TextDocument

Related

What is the difference between M11 and M21 cells in a transformation Matrix?

I need to interpret an SVG input data and identify the displayed points.
In the SVG format, any point may be part of a group ( element ) to which transformations (translate/rotate/scale) may be applied. For every point, I need to bubble up and apply transformation of every ancestor, in order to find the position that the point has in the rendering. After reading some web pages on the subject (and trying to remember from school), I understand that the usual way to do this in .NET is to use 3x3 mathematical matrices, so I try to figure out the System.Windows.Media.Matrix class.
It's been a while since I took Math, and I can't recall this one particular detail.
I typed up the following code in LINQPad:
var matrix = new Matrix(1,1,1,6,0,0);
var matrix2 = new Matrix(2,1,0,6,0,0);
var matrix3 = new Matrix(0,1,2,6,0,0);
var pts = new[]{
new System.Windows.Point(0,0),
new System.Windows.Point(1,1),
new System.Windows.Point(2,2),
new System.Windows.Point(3,3),
new System.Windows.Point(4,4),
new System.Windows.Point(5,5)
}.ToArray();
pts.Select(org=>new{org,changed=matrix.Transform(org),changed2=matrix2.Transform(org),changed3=matrix3.Transform(org)}).Dump("Transformation Samples");
... and trying out different values in the Matrix constructor.
However it seems that these values have no impact on the final result.
new Matrix(1,1,1,6,0,0);
new Matrix(2,1,0,6,0,0);
new Matrix(0,1,2,6,0,0);
(same is true for arguments 2 and 4)
The only thing that seems to matter is the sum of the two (which in this case is 2). I assume that this is due to my limited input data and that given other input data, some difference could be seen that would make sense in some visual tranformation.
Can anybody help me out here?
Perhaps the section in the SVG spec about how transform matrixes work will be of use to you?
http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined

Raphael JS combine paths

I'm pretty new at SVG and Raphael, but I've been using Illustrator for many years, so I have some assumptions on how it works. I want to combine two paths which should return a single element.
I need to make a speech bubble, but it could be anything really. In this case I tried to make two rect, one with round corners and another square rect which was rotated. It looked alright, but when I tried to move the speech bubble, the rotated element moved in the wrong direction, because of the 45 degree rotation.
How can I compbine paths which I can later manipulate as if it was a single element/path?
Here you go DEMO
var paper = Raphael('canvas',400,400),
r1 = paper.rect(100,100,200,100).attr({fill:'black'}),
r2 = paper.rect(130,130,140,40,5).attr({fill:'white','stroke':'white'}),
r3 = paper.path("M200 170L240 170 220 180z").attr({fill:'white', 'stroke':'white'}),
p = paper.set(r1,r2,r3);
// the rest of the code is in the demo
Note, that it is easier to create triangle via path() and not worry about rotation.
Good Luck ;)
If you mean merging paths like using the Illustrator Pathfinder panel - turning several paths into one path (not a set of paths), merging overlap - I'm pretty sure there's no direct Raphael or SVG equivalent.
The closest thing is, creating a compound path (aka composite path) - the equivalent of cmd-8 or Object > Make Compound Path in Illustrator. This merges paths together into one path, but doesn't remove areas of overlap.
Basically, for a set paper.set( paper.path('M0,0 4,0 0,4z'),paper.path('M9,9 4,9 9,4z') );, an equivalent compound path would be paper.path('M0,0 4,0 0,4z M9,9 4,9 9,4z'); - just joining the path definitions into one, each starting with its own M.
Some differences to Raphael sets:
Less overhead (it's just one complex path, not several separate individual path elements)
Fewer surprises when you move it, sort it, etc:
Things applied to a Raphael set apply to each item in turn, not to the set as a unit - so for example toFront() changes the order within the set, and transforms centre around each item, like Illustrator's transform each, unless you give the transform static co-ordinates.
Things applied to a compound path, however, apply to the whole compound path as one unit.
It's not possible for subpaths of a compound path to have different attributes
Things like gradients apply once across the whole of the compound path, whereas with sets, there will be separate gradients on each separate path
JSBIN demo - compare the gradients, and see how the compound pair is just one path on the DOM.
Here's a simple plugin that adds the ability to take a set and create a compound path from it:
Raphael.st.compoundPath = function(){
var positions = [];
this.forEach( function( element ){
positions.push( element.compoundPath() );
});
return positions.join('');
}
Raphael.el.compoundPath = function(){
var path = this.attr('path');
return path ? Raphael.parsePathString( path ).join('') : '';
}
Then use it like this:
var someSet = paper.set(paper.path('M0,0 4,0 0,4z'),paper.path('M9,9 4,9 9,4z'));
var compPath = paper.path( someSet.compoundPath() );
someSet.remove(); // if you want to replace the set with a compound path
Note that it only combines paths in a set - if you need to combine other shapes with paths, you'll need a way to convert them into paths first.
First thing is that you could push your 2 elements into a Raphael set which you would later move with Element.transform(). This would let you apply the move handler once, and not twice.
Also for your issue, it is acually documented:
... There are also alternative “absolute” translation, rotation and
scale: T, R and S. They will not take previous transformation into
account. For example, ...T100,0 will always move element 100 px
horisontally, while ...t100,0 could move it vertically if there is r90
before. Just compare results of r90t100,0 and r90T100,0. ...

Visual Studio Extension highlight based on passed in code block

Trying to write a visual studio extension that will let me pass in a string and value pair and highlight the value.
I have an extension that looks for specific code and example is that it runs and might returns all if statements
If(someString == someOtherString){
return “This was something”;
}
If(someStringElse == someOtherString){
return “This was interesting”;
}
In this example my value might be the open parentheses that is part of
If(someString
I played around with the tutorial on the MSDN site but it seems to only show an all or nothing. I can get it to highlight all open parentheses and I cannot seem to limit it to only the code block I want (pass in the code blocks I want to search for)
If you're following that prototype, then you can adjust these lines here:
//Find the new spans
FindData findData = new FindData(currentWord.GetText(), currentWord.Snapshot);
findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase;
wordSpans.AddRange(TextSearchService.FindAll(findData));
TextSearchService.FindAll is returning the list of spans in the editor that matched the text passed in. Nothing is stopping you from simply changing the spans or computing new ones before calling AddRange. Customize that logic to whatever you want. Obviously, if what you want to highlight doesn't depend upon the position of the caret, there's a fair bit of code you can delete for the determination of currentWord.

How to get the filename and line number of a particular JetBrains.ReSharper.Psi.IDeclaredElement?

I want to write a test framework extension for resharper. The docs for this are here: http://confluence.jetbrains.net/display/ReSharper/Test+Framework+Support
One aspect of this is indicating if a particular piece of code is part of a test. The piece of code is represented as a IDeclaredElement.
Is it possible to get the filename and line number of a piece of code represented by a particular IDeclaredElement?
Following up to the response below:
#Evgeny, thanks for the answer, I wonder if you can clarify one point for me.
Suppose the user has this test open in visual studio: https://github.com/fschwiet/DreamNJasmine/blob/master/NJasmine.Tests/SampleTest.cs
Suppose the user right clicks on line 48, the "player.Resume()" expression.
Will the IDeclaredElement tell me specifically they want to run at line 48? Or is it going to give me a IDeclaredElement corresponding to the entire class, and a filename/line number range for the entire class?
I should play with this myself, but I appreciate tapping into what you already know.
Yes.
The "IDeclaredElement" entity is the code symbol (class, method, variable, etc.). It could be loaded from assembly metadata, it could be declared in source code, it could come from source code implicitly.
You can use
var declarations = declaredElement.GetDeclarations()
to get all AST elements which declares it (this could return multiple declarations for partial class, for example)
Then, for any IDeclaration, you can use
var documentRange = declaration.GetDocumentRange()
if (documentRange.IsValid())
Console.WriteLine ("File: {0} Line:{1}",
DocumentManager.GetInstance(declaration.GetSolution()).GetProjectFile(documentRange.Document).Name,
documentRange.Document.GetCoordsByOffset(documentRange.TextRange.StartOffset).Line
);
By the way, which test framework extension are you developing?
Will the IDeclaredElement tell me specifically they want to run at
line 48?
Once more: IDeclaredElement has no positions in the file. Instead, it's declaration have them.
For every declaration (IDeclaration is a regular AST node) there is range in document which covers it. In my previous example, I used TextRange.StartOffset, though you can use TextRange.EndOffset.
If you need more prcise position in the file, please traverse AST tree, and check the coordinates in the document for specific expression/statement

How can I render mixed-colour text in DirectWrite?

I want to use DirectWrite for mixed-colour text formatting (syntax highlighting, to be precise), but can't seem to find a way to do it, either in the Layout or Typography options. The only option is passing a Brush when rendering the text, which doesn't work for me because I basically have just one Layout. Help!
Use IDWriteTextLayout::SetDrawingEffect to apply drawing effects on subranges. If you're using DWrite with D2D DrawTextLayout, which it sounds like you are, then that drawing effect would just be a brush (such as ID2D1Brush via CreateSolidColorBrush or one of the gradient brushes). If you have implemented your own IDWriteTextRenderer for IDWriteTextLayout::Draw, then the drawing effect can be whatever you interpret it to be. In the IDWriteTextRenderer::DrawGlyphRun callback, you then call QueryInterface on the drawingEffect parameter, or if you are certain it is your own type, just static_cast it directly.
// ... create the colored brushes and determine where to draw ...
wchar_t const* text = L"Red Green";
dwriteFactory->CreateTextLayout(....., OUT &textLayout);
DWRITE_TEXT_RANGE textRange1 = {0,3}, textRange2 = {4,5};
textLayout->SetDrawingEffect(redBrush, textRange1);
textLayout->SetDrawingEffect(greenBrush, textRange2);
renderer->DrawTextLayout(point, textLayout, defaultBrush);

Resources