Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity › Forums › Adobe After Effects Expressions › so easy I could cry – shift position

  • so easy I could cry – shift position

    Posted by Calipoop on August 25, 2007 at 6:44 pm

    I just want to shift a layer’s x position by 60 pixels in a loop. Everytime the loop fires (say every 15 frames), the layer’s x would be + 60.

    also it would be great if the first fire was AT the 15th frame – i.e. the loop wouldn’t start until frame 15…

    My forte is actionscript, my noobiness at AE expressions is killing me.

    Thanks so much for any help on this…

    Mike Clasby replied 19 years, 1 month ago 2 Members · 5 Replies
  • 5 Replies
  • Mike Clasby

    August 25, 2007 at 8:48 pm

    This hack seems to do what you want. Put this expression on Position:

    if (n == 0){
    value;
    }else{
    xMoveAmount = 60;
    moveFrames = 0;
    holdFrames = 15;
    f = Math.round(time/thisComp.frameDuration);
    period = Math.floor(f / (moveFrames + holdFrames))
    phase = f%(moveFrames + holdFrames);
    x = xMoveAmount* period + linear(phase,0,moveFrames,0,xMoveAmount)

    value + [x,0,0]

    This is a hack from a Dan expression, with “value +” added so you can just place you layer anywhere you want to start and it will go from there. If you change “moveFrames” to, say 5, the move will take 5 frames then hold for the remaining 10 frames. Here’s the original Dan post (’twas for rotation):

    https://forums.creativecow.net/readpost/227/6860

    To get it to start at frame 15, I’m using this expression so a marker triggers the above expression.

    n = 0;
    if (marker.numKeys > 0){
    n = marker.nearestKey(time).index;
    if (marker.key(n).time > time){
    n–;
    }
    }

    if (n == 0){
    value;
    }else{

    //your expression here

    }

    So place a Marker at frame 15 (select layer, hit * (asterisk) on the nemric pad). The whole expression is:

    n = 0;
    if (marker.numKeys > 0){
    n = marker.nearestKey(time).index;
    if (marker.key(n).time > time){
    n–;
    }
    }

    if (n == 0){
    value;
    }else{

    xMoveAmount = 60;
    moveFrames = 0;
    holdFrames = 15;
    f = Math.round(time/thisComp.frameDuration);
    period = Math.floor(f / (moveFrames + holdFrames))
    phase = f%(moveFrames + holdFrames);
    x = xMoveAmount* period + linear(phase,0,moveFrames,0,xMoveAmount)

    value + [x,0,0]

    }

    Dan probably has a cleaner way to do this, but I love to hack, so I did.

    To find out about Loop expressions (loops keyframes), see this (Intro comp has examples of the different loops):

    https://library.creativecow.net/articles/ebberts_dan/layer_looping.php

    Since you know code, Dan’s site should be a God-send, here:

    https://www.motionscript.com/

    Also an older but great beginning site is here:

    https://www.jjgifford.com/expressions/

  • Calipoop

    August 25, 2007 at 10:50 pm

    Thanks so much for your reply.

    I plugged the code in but got the error “Class ‘global’ has no property or method named ‘n'”… I should have mentioned that I’m on AE 6. Would that have any impact on the code?

    I’m going to check out those links you posted now, thanks again.

  • Calipoop

    August 25, 2007 at 11:26 pm

    Using the link you posted for the original rotation code, I think I’m on the right track with this:

    shiftAmount = 60
    movingFrames = 1;
    holdFrames = 30;
    f = Math.round(time/thisComp.frameDuration);
    period = Math.floor(f / (movingFrames + holdFrames))
    phase = f%(movingFrames + holdFrames);
    [shiftAmount * period + linear(phase,0,movingFrames,0,shiftAmount),85]

    However, I have a feeling there’s a lot of redundant code?Namely period & phase, since my usage doesn’t involve rotation? Would you know how to streamline this?

    My second question is how can I get the layer to start back at zero after it has moved 600px (ten loops)?

    Thanks for the help!

  • Calipoop

    August 26, 2007 at 12:16 am

    Okay… I think I got it…

    shiftAmount = 60;
    holdFrames = 30;
    f = Math.round(time/thisComp.frameDuration);
    period = Math.floor(f / holdFrames);
    [(shiftAmount * period)%600,position[1]];

    If there’s any additional streamlining that can be made, or a simpler method please let me know…

    Thanks for the help!

  • Mike Clasby

    August 26, 2007 at 8:36 am

    “Looks good to me”, said Dr Franken-yikes as he examines a new specimen.

    OK, too wierd.

    I like your version of the expression.

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