:)
This commit is contained in:
parent
0164914750
commit
fb927e5bcd
1
.eslintignore
Normal file
1
.eslintignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/dist
|
38
.eslintrc.json
Normal file
38
.eslintrc.json
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 12,
|
||||||
|
"sourceType": "script"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
"tab"
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"windows"
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"single"
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
|
"brace-style": [2, "allman", { "allowSingleLine": true }]
|
||||||
|
},
|
||||||
|
"ignorePatterns": ["*.config.js", "*.jsx"] // how do you actually do this
|
||||||
|
}
|
145
README.md
145
README.md
|
@ -1,133 +1,46 @@
|
||||||
# mmkr
|
# mmkr
|
||||||
|
_It's just my handle but shorter_
|
||||||
|
|
||||||
> This project was create with [create-expression-lib](https://github.com/motiondeveloper/create-expression-lib)
|
> This project was created thanks to the help of [create-expression-lib](https://github.com/motiondeveloper/create-expression-lib)!
|
||||||
|
|
||||||
## Use the library
|
## Overview
|
||||||
|
|
||||||
1. Download the latest version from the releases page.
|
This expressions library is mostly a collection of tools I find personally useful. Some pertain to general tasks and others more specific, i.e. YTPMV/音MAD.
|
||||||
2. Import into After Effects and reference in your expressions
|
|
||||||
|
|
||||||
Learn more about writing `.jsx` files for After Effects here: https://motiondeveloper.com/blog/write-expressions-external-files/
|
## Usage
|
||||||
|
|
||||||
|
1. Download the latest version of `mmkr.jsx` from the releases page.
|
||||||
|
2. Import `mmkr.jsx` into your After Effects project.
|
||||||
|
3. Reference the library in your expressions like so:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const MMKR = footage('mmkr.jsx').sourceData.get_functions();
|
||||||
|
```
|
||||||
|
|
||||||
|
Functions will now be usable from the `MMKR` object:
|
||||||
|
```js
|
||||||
|
const MMKR = footage('mmkr.jsx').sourceData.get_functions();
|
||||||
|
MMKR.inertial_bounce(5, 2, 4); // Apply a bounce to the current property
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also destructure the returned object:
|
||||||
|
```js
|
||||||
|
const { inertial_bounce } = footage('mmkr.js').sourceData.get_functions();
|
||||||
|
inertial_bounce(5, 2, 4);
|
||||||
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
1. **Clone project locally**
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone repoUrl.git
|
git clone repoUrl.git
|
||||||
cd mmkr
|
cd mmkr
|
||||||
```
|
|
||||||
|
|
||||||
2. **Start Rollup**
|
# Automatically refresh .jsx output file
|
||||||
|
|
||||||
Start Rollup in watch mode to automatically refresh your code as you make changes, by running:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run watch
|
npm run watch
|
||||||
```
|
|
||||||
|
|
||||||
_You can run also run a once off build:_ `npm run build`
|
# Once off build
|
||||||
|
npm run build
|
||||||
|
|
||||||
3. **Edit the `src` files**
|
# Distribute release
|
||||||
|
|
||||||
_The `index.ts` contains an example expression setup._
|
|
||||||
|
|
||||||
Any values exported from this file will be included in your library, for example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
export { someValue };
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Import the `dist` file into After Effects**
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
5. **Distribute releases**
|
|
||||||
|
|
||||||
To distribute your output file using Github releases (via [Hub](https://github.com/github/hub)), use the command:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run release
|
npm run release
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the GitHub CLI to create a new tag and release
|
|
||||||
|
|
||||||
The release version number is the `"version"` in `package.json`, and it will attach the `"main"` file to the release.
|
|
||||||
|
|
||||||
> You can add this version to the output file by placing the string `_npmVersion` in your code, which will be replaced with the version number in `package.json` at build time.
|
|
||||||
|
|
||||||
## After Effects API
|
|
||||||
|
|
||||||
> This template uses the [`expression-globals-typescript`](https://github.com/motiondeveloper/expression-globals-typescript) package to provide types for the expressions API.
|
|
||||||
|
|
||||||
### Classes
|
|
||||||
|
|
||||||
To create layers, compositions and properties, you can use the classes exported from the library. For example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { Comp, Layer } from 'expression-globals-typescript';
|
|
||||||
const thisComp = new Comp();
|
|
||||||
const thisLayer = new Layer();
|
|
||||||
```
|
|
||||||
|
|
||||||
To create properties (such as position or scale), you can use the `Property` class.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { Property, Vector } from 'expression-globals-typescript';
|
|
||||||
const thisProperty = new Property<Vector>([0, 100]);
|
|
||||||
```
|
|
||||||
|
|
||||||
> The `Property` constructor takes a value to set as the property value, and a type (`<>`) to set as the type for the property.
|
|
||||||
|
|
||||||
### After Effects Types
|
|
||||||
|
|
||||||
You can import After Effect's specific types such as `Color` and `Vector` from the package to properly type your expressions.
|
|
||||||
|
|
||||||
#### _To see all the Types and Base Objects available, see the [`expression-globals-typescript`](https://github.com/motiondeveloper/expression-globals-typescript) source code._
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
You can test your expression library code using [Jest](https://jestjs.io/), which comes pre-configured in this template repo.
|
|
||||||
|
|
||||||
You write tests in the `index.test.ts` file, importing the code you want to test from `index.ts`, for example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { welcome } from './index';
|
|
||||||
|
|
||||||
test('returns correct welcome string', () => {
|
|
||||||
expect(welcome('test')).toEqual('Welcome test!');
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
And then run the test suite:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run test
|
|
||||||
```
|
|
||||||
|
|
||||||
Which will run Jest in watch mode.
|
|
||||||
|
|
||||||
> You can learn more about testing using Jest from the [Jest docs](https://jestjs.io/docs/en/getting-started).
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
There a couple of files you may wish to change to reflect the content of your project:
|
|
||||||
|
|
||||||
- `package.json`:
|
|
||||||
- `version`: The current version of the library, which is used for releases and added to `dist` files.
|
|
||||||
- `main`: The build output file which will be attached to releases
|
|
||||||
- `rollup.config.js`:
|
|
||||||
- `input`: The source file to be built
|
|
||||||
- `typescript()`: Custom typescript compiler options
|
|
||||||
|
|
||||||
## How
|
|
||||||
|
|
||||||
- [expression-globals-typescript](https://github.com/motiondeveloper/expression-globals-typescript) mocks the After Effects expressions API in typescript, so you can use global functions and objects such as `linear()` and `time`, while also providing expression specific types such as `Layer`.
|
|
||||||
|
|
||||||
- [Rollup](https://rollupjs.org/) is a lightweight module bundler that handles outputting the `.jsx` file via the plugins below.
|
|
||||||
|
|
||||||
- The Rollup [Typescript plugin](https://www.npmjs.com/package/@rollup/plugin-typescript) runs the TypeScript compiler
|
|
||||||
|
|
||||||
- The Rollup plugin [rollup-plugin-ae-jsx](https://www.npmjs.com/package/rollup-plugin-ae-jsx) transforms the JavaScript output into After Effects JSON (`.jsx`) compliant syntax
|
|
||||||
|
|
||||||
- Testing via [Jest](https://jestjs.io/), and [ts-jest](https://github.com/kulshekhar/ts-jest)
|
|
||||||
|
|
5752
package-lock.json
generated
Normal file
5752
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "mmkr",
|
"name": "mmkr",
|
||||||
"version": "1.0.1",
|
"version": "1.0.0",
|
||||||
"description": "After Effects Expression Library",
|
"description": "MMaker's After Effects Expression Library",
|
||||||
"main": "dist/mmkr.jsx",
|
"main": "dist/mmkr.jsx",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest --watch",
|
"test": "jest --watch",
|
||||||
|
@ -14,18 +14,17 @@
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": ""
|
"url": ""
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "MMaker",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"homepage": "https://mmaker.moe",
|
||||||
"url": ""
|
|
||||||
},
|
|
||||||
"homepage": "",
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-replace": "^2.4.1",
|
"@rollup/plugin-replace": "^2.4.1",
|
||||||
"@rollup/plugin-typescript": "^8.2.0",
|
"@rollup/plugin-typescript": "^8.2.0",
|
||||||
"@types/jest": "^26.0.22",
|
"@types/jest": "^26.0.22",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||||
|
"@typescript-eslint/parser": "^4.22.0",
|
||||||
|
"eslint": "^7.24.0",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"prettier": "^2.2.1",
|
|
||||||
"rollup": "^2.42.4",
|
"rollup": "^2.42.4",
|
||||||
"rollup-plugin-ae-jsx": "^2.0.0",
|
"rollup-plugin-ae-jsx": "^2.0.0",
|
||||||
"ts-jest": "^26.5.4",
|
"ts-jest": "^26.5.4",
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
trailingComma: 'es5',
|
|
||||||
singleQuote: true
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { welcome } from './index';
|
|
||||||
|
|
||||||
jest.mock('expression-globals-typescript', () => ({
|
|
||||||
Layer: jest.fn(),
|
|
||||||
Comp: jest.fn(),
|
|
||||||
Property: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
test('returns correct welcome string', () => {
|
|
||||||
expect(welcome('test')).toEqual('Welcome test!');
|
|
||||||
});
|
|
83
src/index.ts
83
src/index.ts
|
@ -1,31 +1,78 @@
|
||||||
// Importing object bases (CompBase, LayerBase, PropertyBase)
|
|
||||||
// TypeScript types (Layer, Comp, Value, Color etc)
|
|
||||||
// and global functions from 'expression-globals-typescript'
|
|
||||||
import { Comp, Layer } from 'expression-globals-typescript';
|
import { Comp, Layer } from 'expression-globals-typescript';
|
||||||
import { fromOtherFile } from './otherFile';
|
|
||||||
|
|
||||||
// Creating a new composition object from CompBase
|
const version = '_npmVersion';
|
||||||
const thisComp = new Comp();
|
const thisComp = new Comp();
|
||||||
const thisLayer = new Layer();
|
const thisLayer = new Layer();
|
||||||
|
let thisProperty;
|
||||||
|
|
||||||
// Using the expression types in a function
|
function get_functions(time: number = thisLayer.time)
|
||||||
function getLayerDuration(layerName: string) {
|
{
|
||||||
const layer: Layer = thisComp.layer(layerName);
|
function get_key_index(forward = false, input_property = thisProperty)
|
||||||
return layer.outPoint - layer.inPoint;
|
{
|
||||||
|
let n = 0;
|
||||||
|
if (input_property.numKeys > 0)
|
||||||
|
{
|
||||||
|
n = input_property.nearestKey(time).index;
|
||||||
|
if (input_property.key(n).time > time && !forward) n--;
|
||||||
|
else if (input_property.key(n).time <= time && forward) n++;
|
||||||
|
}
|
||||||
|
return Math.min(n, input_property.numKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using expressions global functions
|
function angle_offset(rot: number, pos: number)
|
||||||
function remap(value: number) {
|
{
|
||||||
return thisLayer.linear(value, 0, 10, 0, 1);
|
rot = thisLayer.degreesToRadians(rot - 90);
|
||||||
|
const x = Math.cos(rot);
|
||||||
|
const y = Math.sin(rot);
|
||||||
|
|
||||||
|
return [pos*x, pos*y];
|
||||||
}
|
}
|
||||||
|
|
||||||
function welcome(name: string): string {
|
// https://gist.github.com/animoplex/aafd6a157282351c8dfeea385d969ef2
|
||||||
return `Welcome ${name}!`;
|
function inertial_bounce(amp: number, freq: number, decay: number, input_property = thisProperty)
|
||||||
|
{
|
||||||
|
const n = get_key_index();
|
||||||
|
let t = 0;
|
||||||
|
|
||||||
|
if (n != 0)
|
||||||
|
{
|
||||||
|
t = time - input_property.key(n).time;
|
||||||
}
|
}
|
||||||
|
|
||||||
const someValue: number = 2;
|
if (n > 0 && t < 1)
|
||||||
|
{
|
||||||
|
const v = input_property.velocityAtTime(input_property.key(n).time - thisComp.frameDuration/10);
|
||||||
|
return input_property.value + v * (amp / 100) * Math.sin(freq * t * 2 * Math.PI) / Math.exp(decay*t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const version: string = '_npmVersion';
|
const YTPMV = {
|
||||||
|
flip: function(mult = 100, input_property = thisProperty)
|
||||||
|
{
|
||||||
|
const n = get_key_index(input_property);
|
||||||
|
return (n % 2 != 0 || n == 0) ? 1*mult : -mult;
|
||||||
|
},
|
||||||
|
|
||||||
// Export values to appear in jsx files
|
time_reset: function(input_property = thisProperty)
|
||||||
export { getLayerDuration, remap, welcome, someValue, version, fromOtherFile };
|
{
|
||||||
|
const n = get_key_index(undefined, input_property);
|
||||||
|
return (n > 0) ? time - input_property.key(n).time : 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
get_key_index,
|
||||||
|
angle_offset,
|
||||||
|
inertial_bounce,
|
||||||
|
YTPMV
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
version,
|
||||||
|
get_functions
|
||||||
|
};
|
|
@ -1 +0,0 @@
|
||||||
export const fromOtherFile = 'value in another file';
|
|
Loading…
Reference in New Issue
Block a user