When working on branded content, a design system will define tokens such as colors and fonts that the whole team will use.
Whenever these tokens update, you need to update lots of After Effects projects, anywhere the values are used.
By storing brand tokens in .jsx files, modifying them in one place will update them in every project.
Writing the JSX file
In its most basic form, the .jsx file can be a list of key value pairs without any logic, much like writing a .json file.
brandProps.jsx
js{// Colors should be [r, g, b, a]// and 0 ... 1colors: {red: [220 / 255, 96 / 255, 105 / 255, 1],green: [141 / 255, 187 / 255, 110 / 255, 1],blue: [87 / 255, 165 / 255, 237 / 255, 1],},// Font names are the same as// text style expressionsfontFamily: {mono: "FiraCode-Light"heading: "Inter-Bold",body: "Inter-Regular",},fontSize: {small: "16",regular: "26",large: "42",}}
Make sure the values are in the same format you would use in an expression, for example color values should be an [r, g, b, a] array of values ranging from 0 to 1.
Referencing in Ae
To use these values in After Effects, import the .jsx file into your project and reference it in an expression.
For example, on a color property:
color
js// Destructure the properties we need from the jsx fileconst { colors } = footage("brandProps.jsx").sourceData();// And reference their valuescolors.red;
Or on a text layers Source Text:
sourceText
js// Destructure the properties we needconst { fontFamily, fontSize } = footage("brandProps.jsx").sourceData();text.sourceText.style.setFontSize(fontSize.regular).setFont(fontFamily.body);
For more information on writing and referencing .jsx files, see our post on writing expressions in external files.
Since you've stored the value in a .jsx file, rather than putting it directly into the property, anytime you update the file all projects that reference it will get the new value.
This allows you to share brand tokens across your whole team, and update them all at once.
Adding theming
Since you're storing the brand tokens in code, you have the flexibility to define them in any way the suits your design system. For example, storing different color values for light and dark mode.
brandProps.jsx
js{colors: {dark: {red: [],green: [],blue: [],},light: {red: [],green: [],blue: [],}},}
Which adds the ability to easily switch between themes in After Effects:
color
js// Destructure the properties we need from the jsx fileconst { colors } = footage("brandProps.jsx").sourceData();// Could link to a checkbox controlconst isDarkMode = true;// Get either the dark or light set of colorscolors[isDarkMode ? "dark" : "light"].red;
Adding logic
Since .jsx files can contain functions, you can add logic to your token system.
Complex theming
For example, your color system might contain two types of tokens:
- Palette tokens: a series of hues and tones
- Usage tokens: tokens for specific use cases, that reference a palette token
By wrapping the values in a function you can return the usage tokens, without giving user access to the underlying palette tokens.
brandProps.jsx
js{function getColors() {const palette = {red: {0: [],100: [],200: [],},green: {0: [],100: [],200: [],},blue: {0: [],100: [],200: [],},};return {light: {text: palette.red.0;background: palette.red.200,accent: palette.green.100,},dark: {text: palette.red.200,background: palette.red.0,accent: palette.green.0,}}},}
Value type conversion
After Effects expects color values to be a four dimensional array ([red, green, blue, alpha]), with each channel ranging from 0 to 1.
This can make adding new colors complicated, as you need to have an understanding of After Effects expressions, adding risk of getting these conversion wrong.
Rather than doing this conversion yourself, you can use After Effects built in color conversion functions.
brandProps.jsx
js{function getColors() {const colors = {navy: thisLayer.hexToRgb("#282C35"),black: thisLayer.hexToRgb("#21242B"),// and so on};return colors;}
By wrapping each color value in thisLayer.hexToRgb(color), After Effects will convert the hex value to the format expressions expect.
Using proxies
Wrapping every color in your .jsx file gets tedious, and if you have a large amount of colors, performing conversions on every one (even if you're not using them) can slow down performance.
Rather than wrapping every color value, you can use a JavaScript Proxy to wrap them before they're accessed.
By only wrapping the values you use, you can speed up expressions for .jsx files that define a lot of colors.
brandProps.jsx
js{function getColors() {const colors = {navy: "#282C35",black: "#21242B",grey: "#BDBDBD",lightGrey: "#F2F2F2",white: "#FFFFFF",green: "#B4DC96",tan: "#D39763",yellow: "#FFDA6E",blue: "#5DAEE6",red: "#E36A79",purple: "#C774E8",};return new Proxy(colors, {get: (target, prop) => {return thisLayer.hexToRgb(target[prop]);}});}
The proxy intercepts calls to the color object, and rather than returning the value directly, it uses our custom get method.
This method wraps the original value (target[prop]) in the After Effects hexToRgb conversion, returning the color in the format expressions expect.
Other uses
Since .jsx files are (mostly) just JavaScript files, you can place any values or logic in there that you want to share between projects.
For example, screen sizes for templates:
js{screens: {instagram: [800, 1000],facebook: [1080, 1920],// ...}}
Commonly used strings:
js{strings: {name: "Motion Developer",description: "We're a consultancy of animators and developers",}}
Or a space system:
js{space: {small: 4,medium: 16,large: 32,}}
We're big fans of using .jsx files to share logic between projects, such as our library of utility functions aeFunctions and our animation engine eKeys.
Blog