Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions motion in a grid

  • Posted by Guillaume Charron on November 10, 2009 at 6:21 pm

    Hi,
    I have to animate 16 icons displayed in a grid of 4×4 squares in 1080×1080 ratio.

    I need to move them lets say 3 times. So at 0sec there are in “position 01”. At 01sec they move to “position 02” in 10 frames. At 3sec they moved to “position 03”, etc.

    Just to make it clear.. the grid has all the square filled with an icon in each position.

    It is just that I don’t want to keyframe everything.

    I have tried the script below but it is always at random and the squares are sometimes filled with 2 or 3 icons.

    Can you help me.

    origin = [10,10]; //upper left hand corner of grid
    dimX = 8; //number of columns
    dimY = 6; //number of rows
    gap = 20; // distance between cells (pixels)
    gridRate = 300; //speed (pixels per second)
    holdTime = .2; //(seconds)

    end = 0;
    j = 0;

    while (time >= end){
    seedRandom(j,true);
    startX = Math.floor(random(dimX))*gap + origin[0];
    startY = Math.floor(random(dimY))*gap + origin[1];
    j +=1;
    seedRandom(j,true)
    start = end;
    endX = Math.floor(random(dimX))*gap + origin[0];
    endY = Math.floor(random(dimY))*gap + origin[1];
    deltaX = Math.abs(endX - startX);
    deltaY = Math.abs(endY - startY);

    end += (deltaX + deltaY)/gridRate + 2*holdTime;
    }

    p1 = start + deltaX/gridRate;
    p2 = p1 + holdTime;
    p3 = p2 + deltaY/gridRate;

    if (time < p1){
    ease(time,start,p1,[startX,startY],[endX,startY])
    }else if (time < p2){
    [endX,startY]
    }else if (time < p3){
    ease(time,p2,p3,[endX,startY],[endX,endY])
    }else{
    [endX,endY]
    }

    Guillaume Charron replied 16 years, 5 months ago 2 Members · 6 Replies
  • 6 Replies
  • Dan Ebberts

    November 10, 2009 at 7:27 pm

    It’s not simple. I’m assuming that you want each icon to move only horizontally or vertically. If so, it’s possible to get yourself into a situation where an icon has nowhere to go, including the position it’s currently occupying.

    Dan

  • Guillaume Charron

    November 10, 2009 at 8:04 pm

    In fact they can move in diagonal also. I’m simulating a game where someone is cliking on the only square with (let say) a happy face in it. When the happy face is cliked, all of the icons are changing places in the grid. So the person has to find the happy face again and clic it as fast as possible. Each time the happy face is cliked… the icons change positions in the grid.

    is it possible? Maybe with slider Control… I don’t know.

  • Dan Ebberts

    November 11, 2009 at 7:19 am

    It’s complicated, because all the random calcs have to happen in a single expression so that all the positions can be accounted for and no locations have more than one layer in them. You can do this by putting a randomizing expression in a text layer (we’ll call it “control”) that you keep at the bottom of the layer stack so it doesn’t interfere with the grid. The text layer gets a source text expression like this:

    cols = 4;
    rows = 4;
    grid = [];
    nextGrid = [];
    for (i = 0; i < cols*rows; i++) nextGrid[nextGrid.length] = i; segment = Math.floor(time); for (j = 0; j <= segment; j++){ for (i = 0; i < nextGrid.length; i++)grid[i] = nextGrid[i]; seedRandom(j,true); for (i = 0; i < nextGrid.length; i++){ idx = i + Math.floor(random(nextGrid.length - i)); temp = nextGrid[i]; nextGrid[i] = nextGrid[idx]; nextGrid[idx] = temp; } } s = "" for (i = 0; i < rows; i++){ for(j = 0; j < cols; j++){ s += grid[i*cols + j] + " " } } s += "_"; for (i = 0; i < rows; i++){ for(j = 0; j < cols; j++){ s += nextGrid[i*cols + j] + " " } } Each of your 16 grid layers gets an expression like this: origin = [100,100]; gap = 50; cols = 4; rows = 4; moveFrames = 10; segment = Math.floor(time); txt = thisComp.layer("control").text.sourceText; spltTxt = txt.split("_"); mySrc = parseInt(spltTxt[0].split(" ")[index-1],10); myDst = parseInt(spltTxt[1].split(" ")[index-1],10); srcRow = Math.floor(mySrc/cols); srcCol = mySrc%cols; dstRow = Math.floor(myDst/cols); dstCol = myDst%cols; src = origin + [srcCol,srcRow]*gap; dst = origin + [dstCol,dstRow]*gap; ease(time,segment+1-moveFrames*thisComp.frameDuration,segment+1,src,dst) It will be slow, but it should work. Dan

  • Guillaume Charron

    November 11, 2009 at 3:03 pm

    It works perfectly. The only thing I don’t know how to control is when they start to move.

    If i change the moveFrames = 10; to moveFrames = 5; the icons are starting to move on frame 25 instead of 20. So it seems I can’t decide when they start to move. For now I surely can live with it (I know it is complicated). But if I could decide when they start, it would be wonderful (maybe with a marker triger). 🙂

    It is not the first time you’re helping me. Thank you very much… again.

  • Dan Ebberts

    November 11, 2009 at 5:30 pm

    I’m not sure what you’re asking. Are you looking for a way to control the overall start time (as in some number of seconds), or are you looking to control when, within each cycle, the icons start to move, and/or how long it takes to arrive at the new location?

    Dan

  • Guillaume Charron

    November 11, 2009 at 7:36 pm

    I’m looking for this one:

    “control when, within each cycle, the icons start to move“

    Sorry for the confusion.

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