As an exercise to practice our expression coding skills, we would like to create a color wheel using a single shape layer and expressions. The wheel should be made with colored arcs of varying hue, saturation and lightness. We want 4 levels of tint and 12 arcs per level (subdivisions). The following figure shows the different parts of the wheel and the notation we’ll use in the expressions:
We want to create an initial arc, add expressions to it, and then duplicate that arc to construct the entire wheel. The setup consists of a shape group containing a trimmed stroked ellipse:
Since the wheel is made of concentric circles, the size of each circle depends on the level. We apply the following expression to the ellipse size:
subdivs = 12;
idx = parseInt(thisProperty.propertyGroup(3).name.split(" ")[1]) - 1;
levelIdx = Math.floor(idx / subdivs);
strokeW = content("Arc " + (idx + 1)).content("Stroke 1").strokeWidth;
diam = 0.8 * thisComp.height - levelIdx * 2 * strokeW;
[diam,diam];
We add the following expression to the start property of the Trim Paths effector:
subdivs = 12;
idx = parseInt(thisProperty.propertyGroup(3).name.split(" ")[1]) - 1;
arcIdx = idx % subdivs;
arcIdx * (100 / subdivs);
The expression is the same for the end property, except the last line:
...
(arcIdx + 1) * (100 / subdivs);
The stroke width is set to 10% of the comp height:
0.1 * thisComp.height;
And finally we apply the following expression to the stroke color:
subdivs = 12;
numLevels = 4;
idx = parseInt(thisProperty.propertyGroup(3).name.split(" ")[1]) - 1;
levelIdx = Math.floor(idx / subdivs);
arcIdx = idx % subdivs;
h = arcIdx / subdivs; // hue
s = 1 - levelIdx / numLevels; // saturation (from high to low)
l = linear(levelIdx, 0, numLevels-1, 0.5, 0.3); // lightness (remap range)
a = 1; // alpha (doesn't affect the result here)
hslToRgb([h,s,l,a]);
This should produce something like this:
Quite a lot of code for drawing a simple arc, but now comes the fun part. We simply press Ctrl+D (Cmd+D on Mac) to duplicate the base arc until the wheel is complete:
When the number of arcs reaches 48 (i.e., 4 x 12), the wheel is complete:ession to the ellipse size:
As a bonus we would like to animate the construction of the wheel. To this end, we add a second Trim Paths effector to the base arc (don’t forget to remove every other arc):
We add the following trim end expression to sequentially reveal the arcs with a short delay:
arcRevealDur = 8; // duration in frames
delay = 2; // delay in frames
subdivs = 12;
numLevels = 4;
totalArcs = numLevels * subdivs;
idx = parseInt(thisProperty.propertyGroup(3).name.split(" ")[1]) - 1;
startT = idx * delay * thisComp.frameDuration;
endT = startT + arcRevealDur * thisComp.frameDuration;
linear(time, startT, endT, 0, 100);
The expression is the same for the out tangent except the vector points in the opposite direction:
Through this little exercise we have seen how we can manipulate shapes and colors using simple expressions. Hope you find it useful!
You can also check ConnectLayers PRO, a tool that create lines that are dynamically linked to the layers using powerful path expressions. No keyframes at all!