I have a shape, in a shape layer, let's say a triangle. I apply a repeater to the shape, and I get lots of them. I can change the distance between them and their rotation ...
My question is: Is there a way to change their color? I mean to control what fill or stroke color each of the cloned ones have? either a random color or even specified color for each?


I don't think it's possible with repeater. You could do this with expressions and multiple duplicates of the shape however.

Here's an example I came up with:

enter image description here

And here's how I did it:

  • Firstly make your initial shape. Now duplicate that shape (with the shape selected hit
    ctrl / ⌘+D). You should see this:

    enter image description here

    Note that we'll be making as many copies as we want later, but for the moment only make one, and get it set up so that we can duplicate it and not have to apply expressions to dozens of copies individually.

  • For each of the properties you want to alter with every repetition we'll add an Expression Control effect, as a handy way to be able to control the whole thing from a single slider.
    Say we wanted to alter the position, scale and rotation: we'd add a Point Control effect to control position another for scale, and an Angle Control for rotation. Expression controls are in Effects>Expression Controls>
    effect controls

  • For ease of use rename each effect suitably. I've changed "Point Control" to "offset" and "scale ctrl", and changed "Angle Control" to "rotation":
    enter image description here

  • We're going to add expressions to control the transform>Position property, the Transform>Rotation property and the Transform>Scale property of each shape object. Note that this is the property inside the shape, not the Transform properties for the layer.
    enter image description here

  • In order to increment the rotation and scale etc. for each duplicate of the Polystar shape we have to find its index, or its serial number so to speak. With layers this is relatively easy, each layer has an index property, but shapes within a layer are layer sub-objects so we have to use a bit of magic to get the index of each. This thread is where I got the info I needed to work it out.

    the key bit of the expression you need is this:

    shapeIndex=thisProperty.propertyGroup(2).name.split(" ")[1]-1;

    The variable shapeIndex now gives you a unique index for each duplicate that you create. This index can then drive the value of the various properties.

Skip this section if you're not interested in how it works

The expression propertyGroup(2) returns the string "Polystar 2" and we use javascript string function split() to split it on the space which returns an array ["Polystar", "2"].
We select the second member of that array (or member[1], since javascript numbers arrays starting at 0) which returns "1". If javascript wasn't so sloppy with types we'd have to explicitly convert the string "1" into the integer 1, but it does the conversion without even being told. Yay Javascript!

  • So to add an offset to each duplicated shape layer we then use the shapeIndex variable and the expression control.

  • Firstly we'll add an expression to the shape's Transform>Position property. alt-click on the stopwatch next to the property to set an expression for that property. It will look like this:
    enter image description here

  • Delete what is there by default and paste in the shapeIndex variable definition mentioned above:
    shapeIndex=thisProperty.propertyGroup(2).name.split(" ")[1]-1;
    hit return (not enter) to start a new line

  • Now use the pickwhip to get the value of the Expression Control Effect that we created for the offset:
    don't spare the pickwhip

  • Now we multiply that offset by the shapeIndex variable. The expression should now look like this:

    shapeIndex=thisProperty.propertyGroup(2).name.split(" ")[1]-1;

    So if your offset is [20, 20], then the fist duplicate will have an offset of [20,20], the next [20,20]*2 which is [40, 40], then [60, 60] and so on. You'll be able to change the value of this point control and have the duplicates update as you do it, without having to type any more code.

  • The same applies to rotation:

    shapeIndex=thisProperty.propertyGroup(2).name.split(" ")[1]-1;

  • And scale. Scale is a bit different because we want to increment the difference between 100 and the value of the controll - if the control is 110% we want to add 10% to the scale. And once we start adding vectors and scalars it gets more complicated - we have to unpack the array, and the integer and pack it up again. So we use this expression:

    shapeIndex=thisProperty.propertyGroup(2).name.split(" ")[1]-1;
    [100+ (effect("scale ctrl")("Point")[0]-100)*shapeIndex, 100+ (effect("scale ctrl")("Point")[1]-100)*shapeIndex];

    If we only wanted uniform scale we could use a slider Expression Control effect, and the the same sort of expression we use for rotation:

    shapeIndex=thisProperty.propertyGroup(2).name.split(" ")[1]-1;
    (effect("scale ctrl")("Slider")/100)*shapeIndex;

  • Lastly we want to control the colour. Colour in AE is a four-element array [R, G, B, Alpha]. The individual components of the array are decimals from 0 to 1, where 1 is full on and 0 is off. So red is [1,0,0], yellow is [1,1,0] and mid grey is [0.5, 0.5, 0.5]. What you want to do with colour is up to you, but here's a demo. It fades out from red to green, with random variation on the blue channel.

    Note that the shapeIndex definition in this expression is different. That's because the color property is nested down a level inside the fill property, so we have to use propertyGroup(3) instead of propertyGroup(2).

    shapeIndex=thisProperty.propertyGroup(3).name.split(" ")[1]-1;
    seedRandom(shapeIndex, timeless = true);
    [r , g, b, 255]

    The seedRandom function creates a new, unchanging random number for each copy. If the timeless=true part is changed to timeless=false the random number will change with every frame. Another randomising function is the wiggle function, that softly changes values over time.

  • So now your shape layer should have two shape objects in it, and the second one will have expressions like this:
    enter image description here

    Here's where the magic happens

  • Now duplicate that second shape. If all goes well you should see new copies with offset, rotation and scale controlled by the expression control effects (make sure you have sane amounts for these values - the offset for example will default to half the width of the comp, which will move your duplicates out of sight. Try setting it to something like 50, 50 to start with). It should look something like the image at the start. Below is how the layer looks. enter image description here

One of the cool things about doing it this way is that the expression is actually based on the name of the shape object. So the layer order doesn't matter. As you can see here, the copies are in front of the original, I can move them around so that they're behind, or individually move them up or down. Using the name is a little bit kludgy though. If I rename one of the shapes I might break all the expressions that control it.

If that's all too hard to read, here's the project

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.