Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions linking value to specific time

  • linking value to specific time

    Posted by Bart Stevens on May 5, 2013 at 6:02 pm

    I have a light that has its color linked to a fill effect.
    The fill effect is driven by a wiggle point on a gradient (the sampleImage expression).

    Currently the fill updates every frame with the wiggle effect.
    I want to have the light select only a single frame (random) for it’s color.
    Ultimately, I want to have control to have it update on every frame or sample a single frame.
    Any ideas?
    Thanks

    Neil Redman replied 13 years ago 3 Members · 7 Replies
  • 7 Replies
  • Neil Redman

    May 6, 2013 at 3:07 am

    You can use valueAtTime to sample a value at a specific time:

    LAYER = the layer that contains the fill effect
    x = the time in seconds at which you want to sample the colorvalue

    LAYER.effect(“Fill”)(“Color”).valueAtTime(x)

    If you want the values for x to be random use:
    a = smallest possible time in seconds
    b = largest possible time in seconds
    x = random(a,b)

  • Bart Stevens

    May 6, 2013 at 4:55 pm

    Thanks for the information Neil.
    when using the expression:
    LAYER.effect(“Fill”)(“Color”).valueAtTime(x)
    (this is to generate my light color from a fill effect)
    I had some strange issues come up.
    It didn’t seem to be referencing the correct color at the specific time, and if my frame exceeded (9), (10 and above) my color went black.

    The fill color effect is being driven by a wiggle point expression on my background layer(precomp ramp effect):

    targetLayer = thisComp.layer(“background”);
    samplePoint = targetLayer.effect(“Point Control”)(“Point”);
    sampledColor = targetLayer.sampleImage(samplePoint, radius = [.5, .5]);
    sampledColor

    I adjusted the script for a frame offset, (which I want for variance between my light colors)and this seems to be working pretty good. (except the expected end of comp when my positive offset has nothing to sample)

    thisComp.layer(“Control Master”).effect(“Fill”)(“Color”).valueAtTime(time + 4*thisComp.frameDuration);

    Follow up question:
    I’m trying to alternate between a continuous update of color (with the time offset) or a single frame hold.(or simply turning the expression off and the light resuming its native color)
    I’m guessing the Checkbox Control would be the way to do this.

    My expression language is very limited but, here’s my attempt at implementing this:

    chBx = thisComp.layer(“Control Master”).effect(“Checkbox Control”)(“Checkbox”)
    if (control == 1){
    thisComp.layer(“Control Master”).effect(“Fill”)(“Color”).valueAtTime(time + 2*thisComp.frameDuration);
    }else{
    value;
    }thisComp.layer(“Control Master”).effect(“Fill”)(“Color”).valueAtTime(1);

    Obviously getting errors with this command, thought it might help.
    Thanks

  • Dan Ebberts

    May 6, 2013 at 5:59 pm

    It sounds like you are trying to select from three modes with a two-state control. Or am I reading it wrong?

    Dan

  • Bart Stevens

    May 6, 2013 at 6:22 pm

    Most likely my communication is confusing (especially if you’re trying to read my hacked together expression)
    I think it’s just a two state control.
    I might have made it more confusing by suggesting an alternative method.
    State 1 – Light color reads the fill color with frame offset (the fill is animated by a wiggle expression and samplePoint)
    State 2 – Light color expression is either turned off (Light is native color) or the light color reads only single frame (both possible solutions would present a non-animated light color)

    Does this makes more sense?
    Thanks again….

  • Dan Ebberts

    May 6, 2013 at 6:40 pm

    I think you were very close then:

    chBx = thisComp.layer(“Control Master”).effect(“Checkbox Control”)(“Checkbox”);
    if (chBx == 1){
    thisComp.layer(“Control Master”).effect(“Fill”)(“Color”).valueAtTime(time + 2*thisComp.frameDuration);
    }else{
    thisComp.layer(“Control Master”).effect(“Fill”)(“Color”).valueAtTime(1);
    }

    For the other variation you would just change the else{} clause to value;

    Dan

  • Bart Stevens

    May 6, 2013 at 8:03 pm

    Once again, Thanks Dan!

  • Neil Redman

    May 7, 2013 at 2:38 am

    [bart stevens] “It didn’t seem to be referencing the correct color at the specific time, and if my frame exceeded (9), (10 and above) my color went black.”

    Hey, I believe you might have been using frame numbers instead of seconds in your expression.

    valueAtTime(x) uses seconds and not frames. So valueAtTime(1) would refer to the value at 1 second in your timeline (in a 25fps timeline it would refer to the value at frame 25)

    When you want to refer to say the second frame in your timeline you could write it either as:
    valueAtTime(2/fps) e.g. for a 25fps timeline that would be valueAtTime (2/25)
    or you could write it as
    valueAtTime(framesToTime(2))

    Cheers,
    Neil

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