Forum Replies Created

Page 47 of 277
  • Hi Andrei, AFAIK, you can’t set any paragraph options via scripting.

    Here’s a dirty workaround using text-animators:

    text animators with expression selectors based on characters skip over the “\r” character so it’s hard to detect them while keeping textIndex and the characters of sourceText in sync.

    So to start, we’ll need an expression on the sourceText (or it can be done in your scripting) to replace every linebreak with an invisible zero-width space (unicode \0x200B) followed by a linebreak. This won’t alter anything of your layout, but the space does count as a character for the textIndex inside the expression selector.

    So the expression for sourceText:

    value.replace(/\r/g,"\u200b\r");

    Next we need a Text-Animator:

    • add a position property with value [0px, 10,000.0px]
    • Add an Expression selector based on characters (and remove the default range selector)
    • change the amount expression to:
    txt = text.sourceText.value.replace(/\r+/g,"");
    space_after = 90;
    paragraphNumber = txt.substr(0,textIndex).split("\u200b").length-1;
    paragraphNumber*space_after/100;

    This first line strips out the linebreaks from the sourcetext so the javascript string’s indexes and the way after effects counts characters via textIndex line up.

    space_after is the number of pixels you want each next paragraph to be pushed down.

    The variable paragraphNumber counts how many times an invisible space is present, those represent a “countable” paragraph break.

    The result of expression selectors needs to be a percentage between -100 and +100 of how much the position property gets applied, so using the set vertical change of 10,000 pixels means we can do an easy division to make for example 90 pixels translate to 0.9%

    If you need more then 10,000 pixels (in this example more than 111 paragraphs) simply add an extra order of magnitude to both the position [100,000px] and the division in the expression (/1000)

    Hope that works out.

    Filip

  • Filip Vandueren

    February 10, 2022 at 1:07 pm in reply to: Random value each keyframe

    Something like this:

    colors = [
    [1,0.6,0,1],
    [1,0,1,1],
    [0,0,1,1],
    [0.5,1,0,1],
    [0.6,0.2,0.4,1]
    ];
    prop = effect("Slider Control")("Slider"); // the property that has keyframes
    if (!prop.numKeys) {
    colors[0];
    } else {
    // we don't care about the value of the keyframes, just the number of keyframes that have occured.
    nk = prop.nearestKey(time);
    nki = nk.time < time ? nk.index : nk.index-1; // nki now is the index of the last keyframe we've passed, use it as an intializer for a non timevarying random number
    seedRandom(nki,true); // "true" makes random numbers the same each subsequent frame
    colors[Math.floor(random(5))];
    }

    Note that because of the nature of random numbers, you’re not guaranteed that the new random color is different from the previous random color.

  • Hi there,

    1: timeToTimecode(thisComp.duration);

    2: timeToFrames(time);

  • Filip Vandueren

    February 5, 2022 at 7:50 pm in reply to: cannot get simple OR statement to work!

    or:

    (a || b || c) == 1 …

    = sets a value, == checks for equality

  • Hi Andrew, in your project settings, make sure the expressions engine is set to “JavaScript” instead of legacy

  • Yes, the problem is that there’s no real mechanical way in which this would make sense if they were gears. Where is the point of rotation ? Are their center points “flexible”, so they always move close together ?

    Which of the two shapes is “driving” the rotation (so that’s the one that has a constant revolution speed, and the other shape follows). If it’s the semicircle: where is it’s axis: in the middle of the shape, or in the middle of the flat side (which would not work IRL)

  • Yes, this can be done with cos and sin, just subtract 90°, in Maths 0 degrees means the 3 o clock position.

  • I’ll see if I can figure it out.

    Maybe renderTom’s roll-it script on aescripts can help you? But kind of expensive for an expression you might only need once.

  • Hi Vincenzo,

    since you can’t be sure of the exact “path” to the Line Cap property (it can be embedded into a shapegroup, there could be multiple paths/shapes/rectangels etc, each with multiple strokes…) I think you need to go through each property recursively and if it’s the right one, apply the value.

    Something like this:

    var project = app.project;

    var comp = project.activeItem;

    app.beginUndoGroup("Process");

    var myLayers = comp.selectedLayers;

    for (var i = 0; i < myLayers.length; i++){

    tryLineCap(myLayers[i].property("ADBE Root Vectors Group"))

    }

    function tryLineCap(prop) {

    for (var j = 1; j <= prop.numProperties; j++){

    var subProp = prop.property(j);

    if (subProp.numProperties) {

    tryLineCap(subProp)

    } else {

    if (subProp.matchName == "ADBE Vector Stroke Line Cap") {

    subProp.setValue(2);

    }

    }

    }

    }

    app.endUndoGroup();

  • The image wasn’t included…

    do you mean something based on trigonometry ?

    Like:

    a=degreesToRadians(45);

    pos = [Math.cos(a),Math.sin(b)]*100;

Page 47 of 277

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy