Forums › Adobe After Effects Expressions › Delay textIndex based on slider/position control with expression selectors
-
Delay textIndex based on slider/position control with expression selectors
-
Julian Chojnacki
January 23, 2023 at 7:27 pmGetting fantastic results, Filip. Thanks a bunch.
One outstanding thing I noticed with your code is that the delay works either starting inwards, or outwards of the comp’s center depending on whether the delay time is negative or positive.
I also remember that previously, when the first keyframe of an animation was the absolute position, I had to compensate for the delay by shifting the keyframes forward a bit, which isn’t necessary anymore. I couldn’t be happier!
-
Julian Chojnacki
February 3, 2023 at 8:06 pmHey again, Filip! I ran into this little issue with the code, and I was wondering if perhaps you’d be able to give me a hand on it.
Literally all I’m trying to do is split the selection into 2 equal parts now, each doing the same, so the pseudo matte I’m working with follows the stacked text’s position.
Quick explanation: My text consists of 2 “layers”. First, there are x lines of text, followed by the same amount of lines with the “|” character, which is then layered onto the text with a position animator, stretched out with a scale animator, and finally filled with a color to create the pseudo matte which you can see in my previous video.
So far, I’ve managed to band-aid the code, so it only applies for the first half and remains static for the other, which looks like this:
const flip = effect("Flip")("Checkbox");
const stggr = effect("Stagger")("Slider");
const tot = textTotal-1;
const ind = textIndex-1;
const range = textTotal/4;
const offst = range - ind;
const rO = offst/range;
const mod = Math.cos(Math.PI*2-.25+rO*2) + 1;
let sel1 = linear(textIndex, 1, textTotal/2, -100, 100); //0-50% selection
sel = textIndex > textTotal/4 && flip == 1 ? sel1 : -sel1;
//let sel2 = linear(textIndex, textTotal/2, textTotal, -100, 100);
if(stggr <= 0) {
easeL = sel * mod/2;
v = ease(stggr, -100, 0, easeL, sel);
} else if(stggr >= 0) {
easeH = sel / mod/2;
v = ease(stggr, 0, 100, sel, easeH);
}
const pos = effect("XYZ")("3D Point");
const delaySldr = effect("Time Delay")("Slider");
const delay = effect("Time Delay")("Slider").value * thisComp.frameDuration;
let p = ind < range ?
pos.valueAtTime(time + delay*ind)
:
pos.valueAtTime(time + delay*(Math.round((tot/2)-ind-1)));
textIndex <= textTotal/2 ? p*v/10000 : 0
…but obviously that’s just a substitute.
I’ve tried overly complicated if else’s and a bunch of other stuff I can’t even remember anymore, but either the whole distribution was distorted or the timing of the delay didn’t match between the two halves… Maybe you know an elegant fix for this, or can explain to me how to split a slightly more complex text selection like this into multiple segments?
-
Filip Vandueren
February 4, 2023 at 12:47 pmCould you post a project ? I’m having a hard time imagining how the mattes are working and how the final sourceText is set up.
-
Julian Chojnacki
February 4, 2023 at 5:57 pmHad to clean it up a little, but here you go:
https://drive.google.com/drive/folders/1vdlmhN9yyc2klLr5o90XxCFXVtJZ0IT5?usp=sharing
And for a quick overview, here’s my source text:
const y1 = effect("Vertical Copies")("Slider");
const y2 = value.split('\r').length;
if (y2 == 1) { //textmode detection
txt = (value.repeat(1)+"\n").repeat(y1)+("|\n").repeat(y1); // textmode1: repeat 1 word vertically, then repeat stack with the "|" char for matte
} else {
txt = (value+"\n")+("|\n").repeat(y2); // textmode 2: option for multiple words, then repeat stack with the "|" char for matte
}
txt.replace(/\n$/, "") // remove last linebreak
Thanks Filip 🙂
-
Filip Vandueren
February 6, 2023 at 1:18 pmI think this does the trick:
const ind = (textIndex-1) % (textTotal/2);
then replace all following uses of textIndex by ind
-
Julian Chojnacki
February 23, 2023 at 7:11 pmThis indeed did the trick and makes total sense! Thanks Filip 🙂
Log in to reply.