Skip to content

Instantly share code, notes, and snippets.

@gfxhacks
Created August 9, 2020 04:51
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gfxhacks/058618bf728accb85c1c9895bdb3ab1c to your computer and use it in GitHub Desktop.
Save gfxhacks/058618bf728accb85c1c9895bdb3ab1c to your computer and use it in GitHub Desktop.
Full featured Countdown Timer rig for Adobe After Effects. More info at https://gfxhacks.com/timer-rig-in-after-effects-using-expressions
// Usage: In AE 2020 (17.0) or above, create a new composition or open an existing one. Then choose File -> Scripts -> Run Script File... to launch this script.
/*
Title: timer_rig.jsx
Author: gfxhacks.com
Description: Create a new Timer object in the active After Effects composition.
More Info: https://gfxhacks.com/timer-rig-in-after-effects-using-expressions
*/
app.beginUndoGroup("Create Timer");
// define timer expression
exp = '// get Timer properties\nrate = clamp(effect("Rate")("Slider"), 0, 100);\nh = effect("Start Time - Hours")("Slider");\nm = effect("Start Time - Minutes")("Slider");\ns = effect("Start Time - Seconds")("Slider");\nc = effect("Countdown")("Checkbox").value;\nms = effect("Milliseconds")("Checkbox").value;\nformat = effect("Time Format")("Menu").value;\nn = effect("Negative Time")("Checkbox").value;\n// convert Start Times to seconds and sum.\nst = h*3600 + m*60 + s;\n// count up or count down based on checkbox value\nt = c ? st - rate*(time - inPoint) : st + rate*(time - inPoint);\n// initialize time as [HH:MM:SS:MSS]\nf = t <= 0 ? [00, 00, 00, 000] : [t/3600, (t%3600)/60, t%60, t.toFixed(3).substr(-3)];\n// Round to whole numbers and add zero padding\nfor (i in f){ f[i] = String(Math.floor(f[i])).padStart(i>2?3:2, "0") }\n// remove ms if checkbox is off\nif(!ms) f.pop();\n// change Timer display based on chosen format\nswitch (format){\n // HH:MM:SS\n case 1:\n t = f.join(":");\n break;\n // MM:SS\n case 2:\n t = f.slice(1).join(":");\n break;\n // SS\n case 3:\n t = f.slice(2).join(":");\n}\n// prepend minus symbol to time if checkbox is on\nn ? "-" + t : t;';
// define expression control effects
effects = [
{
"type": "Checkbox Control",
"name": "Countdown",
"value": "1"
},
{
"type": "Dropdown Menu Control",
"name": "Time Format",
"value": ["HH:MM:SS", "MM:SS", "SS"]
},
{
"type": "Slider Control",
"name": "Rate",
"value": "1"
},
{
"type": "Slider Control",
"name": "Start Time - Hours",
"value": "24"
},
{
"type": "Slider Control",
"name": "Start Time - Minutes",
"value": "0"
},
{
"type": "Slider Control",
"name": "Start Time - Seconds",
"value": "0"
},
{
"type": "Checkbox Control",
"name": "Milliseconds",
"value": "1"
},
{
"type": "Checkbox Control",
"name": "Negative Time",
"value": "0"
},
]
try {
// get current comp
c = app.project.activeItem;
// add new text layer
t = c.layers.addText();
// rename text layer
t.name = "Timer";
try {
for (i in effects) {
// get current expression control effect
e = effects[i];
// add current expression control effect
s = t.property('Effects').addProperty(e.type);
// get current expression control effect index
id = s.propertyIndex;
// check if effect is of type dropdown, then set values.
// Dropdown Menu effect (new in 2020) is the only effect that requires to set values with: setPropertyParameters
s.property(1).isDropdownEffect ? s.property(1).setPropertyParameters(e.value) : s.property(1).setValue(e.value);
// rename effect using index reference - previous reference is lost when setting values.
t.property('Effects')(id).name = e.name;
}
// add timer expression to source text
t.text.sourceText.expression = exp;
} catch (e) {
alert('Script Failed!\nDropdown Menu control not found. Make sure you are running AE 2020 (17.0) or above.')
}
} catch (e) {
alert('Create or open a composition first!');
}
// add expression control effects to text layer
app.endUndoGroup();
@gfxhacks
Copy link
Author

gfxhacks commented Jan 27, 2021

I see are you getting this error? Script Failed! Dropdown Menu control not found. Make sure you are running AE 2020 (17.0) or above.

If so there might be a bug with the script running on your version of AE. You can try upgrading.. Otherwise try setting up the controls manually, following this guide: https://gfxhacks.com/timer-rig-in-after-effects-using-expressions/#quick-reference

@mackenziee4
Copy link

Hi. This is such a cool script! It beats what I've used in the past by far.
I have a question about Zero Padding.
What could changes could I make to make it so that the zero padding in the HH part of an HH:MM:SS clock does not appear but still does in the MM and SS parts?

@gfxhacks
Copy link
Author

Heya,
You can chain a second conditional within the padstart method: .padStart(i>2?3:i<1?1:2, "0")
Not very pretty but works nonetheless! - basically considering HH:MM:SS:MSS positioned in the array at [0, 1, 2, 3], if the current item's position is greater than 2 (so the MSS at pos 3), pad with 3 zeros. If the position is less than 1 (so the HH at pos 0), pad with 1 zero. MM and SS (at pos 1 and 2 respectively) will pad with 2. Hope it helps :)

@mackenziee4
Copy link

Thank you so much!! This is exactly what I was looking for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment