Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Forums Adobe After Effects Expressions Weird sourceRectAtTime bug… or is it?

  • Weird sourceRectAtTime bug… or is it?

  • Nick Hill

    November 25, 2022 at 5:16 pm

    Bashing my head against the desk a bit with this one… I have a series of title cards representing categories, named like “TITLE1”, “TITLE2”, etc. Each is 5 seconds long, and between each one is a series of clips. The title cards are between layer 16 and 20, in order – the clips are from about 25 onwards.

    I want to have a text layer whose sourceText varies depending on what was the last title card to pop up. So after TITLE1 has been on screen and disappeared again, it should say TITLE1, until TITLE2 appears, after which it says TITLE2, etc. So, this code works on the sourceText:

    L = thisComp.layer("CONTROL"); // a "buffer layer" we don't want to go past
    doThis = false;
    i = 16; // the first "title card" layer
    nm = "";
    while (doThis == false) {
    m = thisComp.layer(i);
    n = thisComp.layer(i+1);
    if ((m.outPoint <= time) && (n.inPoint >= time)) {
    doThis = true;
    nm = m.name;
    } else {
    i+=1;
    }
    if (i == L.index) { // we've somehow gone too far, or we're at the end
    nm = m.name;
    break;
    }
    }
    nm

    BUT – I also want a shape layer as a backing for this text layer, so it stands out on brighter footage. It should resize based on the layer’s changing sourceText and therefore length. This, I think, *should* work on the rectangle size, but it doesn’t.

    L = thisComp.layer("Category"); // text layer
    b = L.sourceRectAtTime(time, false);
    bd = effect("borders")("Point"); // a point layer to add a little border round the text
    w = L.position[0] + b.left + b.width + bd[0]*2; // it's left-aligned so this should resize the rectangle based on the rightmost edge of the text layer
    h = b.height + bd[1]*2;
    [w,h]

    Expected behaviour: the shape layer’s rectangle element resizes to always fit the text layer.

    Actual behaviour: 5 seconds before each new title card comes in, the backing layer resizes to the width of the text layer at the end of the comp – this happens to be the widest title. It’s as if rather than picking up the text layer’s sourceText at the current time, for some reason it’s picking it up from the end of the comp. This is despite the text layer showing the text I’d expect.

    In practice I’ve just keyframed the size as there are only 5 title cards, but I’ve had this bug happen a couple of times on other projects so I don’t know if it’s something I’m doing wrong!

  • Dan Ebberts

    November 25, 2022 at 5:43 pm

    Can you post a screen shot of your timeline, showing how you have the layers arranged?

  • Dan Ebberts

    November 25, 2022 at 6:29 pm

    I’m kind of shooting in the dark here, but it seems like this line:

    if ((m.outPoint <= time) && (n.inPoint >= time)) {

    should be like this:

    if ((m.inPoint <= time) && (n.inPoint >= time)) {

  • Nick Hill

    November 25, 2022 at 7:10 pm

    Thanks Dan. Not in front of it now so I can’t check – but it’s weird the text is doing what I’d expect, while the backing layer which is getting the text layer’s dimensions isn’t!

  • Dan Ebberts

    November 25, 2022 at 9:41 pm

    Understood. In playing around (and trying to guess how you have your comp organized) I couldn’t get the text to work until I made that change to your expression, after which I started getting expected results from sourceRectAtTime(), so there may be a connection.

  • Nick Hill

    November 25, 2022 at 10:01 pm

    Thanks so much Dan. That did change how the backing (not the text) behaves, although it didn’t fix things… here’s how the layers are set up, with the titles up top, the text layer and shape layer backing in the middle, and all the layers (stock) going off the screen at the bottom. Changing to …

    if ((m.inPoint <= time) && (n.inPoint >= time)

    still caused the backing layer to change size 5 seconds before it should, but now it was changing to the size it should have been *after* the new title has come in. So I then tried this

    if ((m.outPoint <= time) && (n.outPoint > time)) {

    which works (the backing layer changes size as soon as the title layer appears, which is fine as it covers the other text and its backing).

    I’m not quite sure why sourceRectAtTime was seemingly being thrown by dynamically generated text, but in any case it does work. Thank you again!

  • Dan Ebberts

    November 25, 2022 at 10:36 pm

    Do you have it set up so that the Category layer doesn’t start at time = 0? If so, try changing this line:

    b = L.sourceRectAtTime(time, false);

    to this:

    b = L.sourceRectAtTime(time - L.startTime, false);

  • Nick Hill

    November 30, 2022 at 2:39 pm

    Had to do it manually for the deadline – only just come back and had the time to play around with it. Yes, that fixes it. I was thinking the inPoint was enough, but I realise the layer was offset in time (I’d moved it forward in the timeline, then pulled the start of the layer back to 0, so the startTime was >0). Thanks again!

Viewing 1 - 8 of 8 posts

Log in to reply.

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