|
1 | | -<!-- Links --> |
| 1 | +# 🔑 aeFunctions |
2 | 2 |
|
3 | | -[back to top ↑]: #ekeys- |
4 | | - |
5 | | -<div align="center"> |
6 | | - |
7 | | -# eKeys <!-- omit in toc --> |
8 | | - |
9 | | -An After Effects animation engine built for expressions. |
10 | | - |
11 | | -**[Usage](#usage) | [Example](#example) | [Contact](#contact)** |
12 | | - |
13 | | - |
| 3 | +**Keyframe animation in After Effects Expressions** |
14 | 4 |
|
15 | 5 | --- |
16 | 6 |
|
17 | | -### [✨ Download eKeys ✨](https://github.com/motiondeveloper/eKeys/releases)<!-- omit in toc --> |
| 7 | +✨ View more details on our website: **[motiondeveloper.com/tools/eKeys](www.motiondeveloper.com/tools/ekeys)** |
18 | 8 |
|
19 | 9 | --- |
20 | 10 |
|
21 | | -</div> |
22 | | - |
23 | | -## Overview |
24 | | - |
25 | | -`eKeys` is a system of doing animation in Adobe After effects entirely within expressions, with the same level on control as keyframes. |
26 | | - |
27 | | -It comes in the form of a `.jsx` file that's imported into the project, and a set of expressions to be applied to each property you wish to animate, with the values for each 'keyframe' to be added in the expression. |
28 | | - |
29 | | -Its purpose is to speed up the creation of After Effects templates and other automated work. |
30 | | - |
31 | | -> **eKeys is written in TypeScript using our [Expression Library Template](https://github.com/motiondeveloper/expressions-library-template)** |
32 | | -
|
33 | | -### Features |
34 | | - |
35 | | -- Animate between numbers or arrays |
36 | | -- Full control over easing, including incoming and outgoing velocities |
37 | | -- No installation necessary, just import 1 file |
38 | | -- Simple and succinct expression interface |
39 | | -- Free and open source |
40 | | - |
41 | | -## Contents |
42 | | - |
43 | | -- [Overview](#overview) |
44 | | - - [Features](#features) |
45 | | -- [Contents](#contents) |
46 | | -- [Compatibility](#compatibility) |
47 | | -- [Usage](#usage) |
48 | | - - [1. **Download and import `eKeys.jsx` into your After Effects project**](#1-download-and-import-ekeysjsx-into-your-after-effects-project) |
49 | | - - [2. **Add a reference to the library in your expression**](#2-add-a-reference-to-the-library-in-your-expression) |
50 | | - - [3. **Create an array of keyframes**](#3-create-an-array-of-keyframes) |
51 | | - - [4. **Animate between the keys**](#4-animate-between-the-keys) |
52 | | -- [Example](#example) |
53 | | -- [Helpful Snippets](#helpful-snippets) |
54 | | -- [By animators, for animators](#by-animators-for-animators) |
55 | | -- [To Do](#to-do) |
56 | | -- [License](#license) |
57 | | -- [Contact](#contact) |
58 | | - |
59 | | -## Compatibility |
60 | | - |
61 | | -This version of eKeys is compatible with After Effects versions >= 16.0.1 (CC2019) which use the new [Javascript engine](https://helpx.adobe.com/after-effects/using/expression-language-reference.html). |
62 | | - |
63 | | -> ⚠️ Make sure your project is configured to use the JavaScript engine by going to `File > Project Settings > Expression Engine` and setting it to `JavaScript`. |
64 | | -
|
65 | | - |
66 | | - |
67 | | -For a legacy version that works in the ExtendScript engine, view the [ExtendScript Branch](https://github.com/motiondeveloper/ekeys/tree/extendscript). Please note, this version of `eKeys` is not actively maintained. |
| 11 | +- Animate dynamically with expressions |
| 12 | +- Full control over easing |
| 13 | +- Simple and keyframe-like API |
68 | 14 |
|
69 | | -[Back To Top ↑] |
70 | | - |
71 | | -## Usage |
72 | | - |
73 | | -### 1. **Download and import `eKeys.jsx` into your After Effects project** |
74 | | - |
75 | | -Head over to the [releases](https://github.com/motiondeveloper/eKeys/releases) page to download the latest version of the `eKeys.jsx` file. |
76 | | - |
77 | | -This is the JSON file that contains the necessary code to run eKeys. You may not be able to drag and drop it into your project, in which case you will need to use the import dialog. |
| 15 | +--- |
78 | 16 |
|
79 | | -### 2. **Add a reference to the library in your expression** |
| 17 | +🏗 This project was created with [create-expression-lib](https://github.com/motiondeveloper/create-expression-lib) - our utility for creating and managing After Effects `.jsx` libraries. |
80 | 18 |
|
81 | | -To reference the library in an expression, you need to assign it to a variable. This is done via the line: |
| 19 | +--- |
82 | 20 |
|
83 | | -```javascript |
84 | | -const eKeys = footage('eKeys.jsx').sourceData; |
85 | | -``` |
| 21 | +## Setup |
86 | 22 |
|
87 | | -> ⚠️ Since After Effects doesn't count footage items that are only referenced within expressions as used, it's recommended that you also place the `eKeys.jsx` file in any compositions where it is referenced. |
88 | | -> |
89 | | -> This will ensure After Effects includes the file when collecting assets or packaging into a Motion Graphics Template. |
| 23 | +1. Download the latest version from the [releases](https://github.com/motiondeveloper/ekeys/releases) page. |
| 24 | +2. Import it into After Effects |
90 | 25 |
|
91 | | -### 3. **Create an array of keyframes** |
| 26 | +## Expression |
92 | 27 |
|
93 | | -Each keyframe is represented as an object within an array. |
| 28 | +Usage: |
94 | 29 |
|
95 | | -```javascript |
96 | | -// Example keyframe array |
97 | | -const keys = [ |
| 30 | +```js |
| 31 | +const { animate } = footage('eKeys.jsx').sourceData; |
| 32 | +animate([ |
98 | 33 | { |
99 | | - keyTime: 1, |
| 34 | + keyTime: 0, |
100 | 35 | keyValue: [0, 0], |
101 | | - easeIn: 0, |
102 | | - easeOut: 66, |
103 | | - }, |
104 | | - { |
105 | | - keyTime: 2, |
106 | | - keyValue: [thisComp.width / 2, 0], |
107 | | - easeIn: 90, |
108 | | - easeOut: 0, |
109 | | - }, |
110 | | -]; |
111 | | -``` |
112 | | - |
113 | | -<details><summary><strong>Keyframe Object Properties</strong></summary> |
114 | | -<br> |
115 | | - |
116 | | -- `keyTime` Where the keyframe is in time, in seconds |
117 | | - - Type: `number` |
118 | | - - Required: `true` |
119 | | -- `keyValue` Value of the keyframe |
120 | | - - Type: `number` or `array` |
121 | | - - Required: `true` |
122 | | -- `easeIn` Ease in amount |
123 | | - - Type: `number` |
124 | | - - Required: `false` |
125 | | - - Default: `33` |
126 | | - - Range: `0-100` |
127 | | -- `easeOut` Ease out amount |
128 | | - - Type: `number` |
129 | | - - Required: `false` |
130 | | - - Default: `33` |
131 | | - - Range: `0-100` |
132 | | -- `velocityIn` Incoming speed |
133 | | - - Type: `number` |
134 | | - - Required: `false` |
135 | | - - Default: `0` |
136 | | - - Range: `0-100` |
137 | | -- `velocityOut` Outgoing speed |
138 | | - - Type: `number` |
139 | | - - Required: `false` |
140 | | - - Default: `0` |
141 | | - - Range: `0-100` |
142 | | - </details> |
143 | | - <br> |
144 | | - |
145 | | -> While it is recommended you order the keyframes according to their `keyTime` for the sake of readability, it is not required as they are sorted before the animation is calculated. |
146 | | -
|
147 | | -### 4. **Animate between the keys** |
148 | | - |
149 | | -The final animated value can be returned by calling the `animate` function. |
150 | | - |
151 | | -```javascript |
152 | | -eKeys.animate(keys, time? = thisLayer.time); |
153 | | -``` |
154 | | -
|
155 | | -#### `animate()` Function Inputs |
156 | | -
|
157 | | -- `keys` Array of keyframes |
158 | | - - Type: `array` |
159 | | - - Required: `true` |
160 | | -- `time` Incrementing animation time |
161 | | - - Type: `number` |
162 | | - - Required: `false` |
163 | | -
|
164 | | -[Back To Top ↑] |
165 | | -
|
166 | | -## Example |
167 | | -
|
168 | | -An example setup of an animation group with a couple of keyframes: |
169 | | -
|
170 | | -```javascript |
171 | | -// Import eKeys library |
172 | | -const eKeys = footage('eKeys.jsx').sourceData; |
173 | | - |
174 | | -// Create an array of keyframes |
175 | | -const inKeys = [ |
176 | | - { |
177 | | - keyTime: 1, |
178 | | - keyValue: 0, |
179 | | - easeIn: 0, |
180 | | - easeOut: 66, |
181 | | - }, |
182 | | - { |
183 | | - keyTime: 2, |
184 | | - keyValue: 250, |
185 | | - easeIn: 90, |
186 | | - easeOut: 0, |
187 | | - }, |
188 | | -]; |
189 | | - |
190 | | -// Animate |
191 | | -eKeys.animate(inKeys); |
192 | | -``` |
193 | | -
|
194 | | -You can also [destructure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) `animate` from the `sourceData` object: |
195 | | -
|
196 | | -```javascript |
197 | | -const { animate } = footage('eKeys.jsx').sourceData; |
198 | | -// ... |
199 | | -animate(inKeys); |
200 | | -``` |
201 | | -
|
202 | | -[Back To Top ↑] |
203 | | -
|
204 | | -## Helpful Snippets |
205 | | -
|
206 | | -- **Create default keyframe parameters** |
207 | | -
|
208 | | - Use the JavaScript [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) to use a set of default parameters across keyframes. |
209 | | -
|
210 | | - <details><summary>View Code</summary> |
211 | | - <p> |
212 | | -
|
213 | | - ```javascript |
214 | | - const keyDefaults = { |
215 | | - easeIn: 90, |
216 | | - easeOut: 50, |
217 | | - velocityIn: 10, |
218 | | - velocityOut: 50, |
219 | | - }; |
220 | | - |
221 | | - const keys = [ |
222 | | - { |
223 | | - keyTime: 0, |
224 | | - keyValue: [0, 50], |
225 | | - ...keyDefaults, |
226 | | - }, |
227 | | - { |
228 | | - keyTime: 2, |
229 | | - keyValue: [800, 50], |
230 | | - ...keyDefaults, |
231 | | - }, |
232 | | - ]; |
233 | | - ``` |
234 | | -
|
235 | | - </p> |
236 | | - </details> |
237 | | -
|
238 | | -- **Merge multiple keyframes groups** |
239 | | -
|
240 | | - Easily merge multiple keyframe arrays to be animated using the JavaScript [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax). |
241 | | -
|
242 | | - <details><summary>View Code</summary> |
243 | | - <p> |
244 | | -
|
245 | | - ```javascript |
246 | | - const inKeys; |
247 | | - const outKeys; |
248 | | - const animOut = true; |
249 | | - const keys = animOut ? [...inKeys] : [...inKeys, ...outKeys]; |
250 | | - eKeys.animate(keys); |
251 | | - ``` |
252 | | -
|
253 | | - </p> |
254 | | - </details> |
255 | | -
|
256 | | - This could also be done by creating multiple `AnimGroup's`. |
257 | | -
|
258 | | -- **Remove specific keyframes** |
259 | | -
|
260 | | - Remove one or more keyframes based on another variable. |
261 | | -
|
262 | | - <details><summary>View Code</summary> |
263 | | - <p> |
264 | | -
|
265 | | - ```javascript |
266 | | - const keys; |
267 | | - const enableSpin = true; |
268 | | - if (!enableSpin) { |
269 | | - // Remove keyframes 4 and 5 |
270 | | - keys.splice(3, 2); |
| 36 | + easeOut: 90, |
| 37 | + }, { |
| 38 | + keyTime: 3, |
| 39 | + keyValue: [960, 540], |
| 40 | + easeIn: 80, |
271 | 41 | } |
272 | | - ``` |
273 | | -
|
274 | | - </p> |
275 | | - </details> |
276 | | -
|
277 | | -[Back To Top ↑] |
278 | | -
|
279 | | -## By animators, for animators |
280 | | -
|
281 | | -`eKeys` is built in such a way to make it easy for animators to use, based on the inputs and workflows they're used to when creating standard After Effects keyframes. |
| 42 | +]); |
| 43 | +``` |
282 | 44 |
|
283 | | -Outside of this context, `eKeys` might not make much sense or appear a little strange. It's not for everyone! |
| 45 | +## Development |
284 | 46 |
|
285 | | -[Back To Top ↑] |
| 47 | +1. **Clone project locally** |
286 | 48 |
|
287 | | -## To Do |
| 49 | + ```sh |
| 50 | + git clone https://github.com/motiondeveloper/eKeys.git |
| 51 | + cd aeFunctions |
| 52 | + ``` |
288 | 53 |
|
289 | | -- [x] ~~Add incoming and outgoing velocity inputs~~ |
290 | | -- [x] ~~Updated curve sampling to Newton-Raphson~~ |
291 | | -- [x] ~~Update to Javascript engine (from ExtendScript)~~ |
292 | | -- [x] ~~Input validation and error checking~~ |
293 | | -- [ ] Add option to input easing as array, same as [css cubic-bezier](https://www.w3.org/TR/css-easing-1/). |
294 | | -- [ ] Add animation method input (overshoot, bounce etc) |
295 | | -- [ ] Add ability to write in standard js and transform into After Effects jsx using babel |
| 54 | +2. **Start Rollup** |
296 | 55 |
|
297 | | -[Back To Top ↑] |
| 56 | + Start Rollup in watch mode to automatically refresh your code as you make changes, by running: |
298 | 57 |
|
299 | | -## License |
| 58 | + ```sh |
| 59 | + npm run watch |
| 60 | + ``` |
300 | 61 |
|
301 | | -This project is licensed under the terms of the GNU GPLv3 license. In summary: |
| 62 | + _You can run also run a once off build:_ `npm run build` |
302 | 63 |
|
303 | | -> Permissions of this strong copyleft license are conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work, under the same license. Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. |
| 64 | +3. **Edit the `src` files** |
304 | 65 |
|
305 | | -The `bezier` function is from [Gaëtan Renaudeau's cubic-bezier](https://github.com/gre/bezier-easing) project, and is licensed under the terms of the MIT License. |
| 66 | + _The `index.ts` contains an example expression setup._ |
306 | 67 |
|
307 | | -[Back To Top ↑] |
| 68 | + Any values exported from this file will be included in your library, for example: |
308 | 69 |
|
309 | | -## Contact |
| 70 | + ```js |
| 71 | + export { someValue }; |
| 72 | + ``` |
310 | 73 |
|
311 | | -Bugs, issues and feature requests can be submitted by filing an [issue](https://github.com/motiondeveloper/ekeys/issues) on Github. For everything else, feel free to reach out to [@modeveloper](https://twitter.com/modeveloper) on twitter. |
| 74 | +4. **Import the `dist` file into After Effects** |
312 | 75 |
|
313 | | -[Back To Top ↑] |
| 76 | + Use the compiled output file as you would any other `.jsx` library. Any changes to the `src` files will be live updated, and After Effects will update the result of your expression. |
0 commit comments