commit 0164914750112249fb19d3e26b2cbe0961311394 Author: MMaker Date: Tue Apr 13 16:06:13 2021 -0400 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1e5520d --- /dev/null +++ b/.gitignore @@ -0,0 +1,104 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next +dist + +# Nuxt.js build / generate output +.nuxt + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..81f990d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9beb598 --- /dev/null +++ b/README.md @@ -0,0 +1,133 @@ +# mmkr + +> This project was create with [create-expression-lib](https://github.com/motiondeveloper/create-expression-lib) + +## Use the library + +1. Download the latest version from the releases page. +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/ + +## Development + +1. **Clone project locally** + + ```sh + git clone repoUrl.git + cd mmkr + ``` + +2. **Start Rollup** + + Start Rollup in watch mode to automatically refresh your code as you make changes, by running: + + ```sh + npm run watch + ``` + + _You can run also run a once off build:_ `npm run build` + +3. **Edit the `src` files** + + _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 + ``` + + 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([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) diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..91a2d2c --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..f1e9b26 --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "mmkr", + "version": "1.0.1", + "description": "After Effects Expression Library", + "main": "dist/mmkr.jsx", + "scripts": { + "test": "jest --watch", + "tsc": "tsc", + "build": "rollup -c", + "watch": "rollup -cw", + "release": "npm run build && gh release create $(node -pe \"require('./package.json').version\") $(node -pe \"require('./package.json').main\")" + }, + "repository": { + "type": "git", + "url": "" + }, + "author": "", + "license": "MIT", + "bugs": { + "url": "" + }, + "homepage": "", + "devDependencies": { + "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-typescript": "^8.2.0", + "@types/jest": "^26.0.22", + "jest": "^26.6.3", + "prettier": "^2.2.1", + "rollup": "^2.42.4", + "rollup-plugin-ae-jsx": "^2.0.0", + "ts-jest": "^26.5.4", + "tslib": "^2.1.0", + "typescript": "^4.2.3" + }, + "dependencies": { + "expression-globals-typescript": "^3.1.6" + } +} diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..5741f9d --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,4 @@ +module.exports = { + trailingComma: 'es5', + singleQuote: true +} \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..f9ea33d --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,30 @@ +import typescript from '@rollup/plugin-typescript'; +import replace from '@rollup/plugin-replace'; +import afterEffectJsx from 'rollup-plugin-ae-jsx'; +import pkg from './package.json'; + +export default { + input: 'src/index.ts', + output: { + file: pkg.main, + format: 'cjs', + format: 'es', + }, + external: Object.keys(pkg.dependencies), + plugins: [ + replace({ + preventAssignment: true, + values: { + _npmVersion: pkg.version, + }, + }), + typescript({ + module: 'esnext', + target: 'esnext', + noImplicitAny: true, + moduleResolution: 'node', + strict: true, + }), + afterEffectJsx(), + ], +}; diff --git a/src/index.test.ts b/src/index.test.ts new file mode 100644 index 0000000..7b068f2 --- /dev/null +++ b/src/index.test.ts @@ -0,0 +1,11 @@ +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!'); +}); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..925913e --- /dev/null +++ b/src/index.ts @@ -0,0 +1,31 @@ +// 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 { fromOtherFile } from './otherFile'; + +// Creating a new composition object from CompBase +const thisComp = new Comp(); +const thisLayer = new Layer(); + +// Using the expression types in a function +function getLayerDuration(layerName: string) { + const layer: Layer = thisComp.layer(layerName); + return layer.outPoint - layer.inPoint; +} + +// Using expressions global functions +function remap(value: number) { + return thisLayer.linear(value, 0, 10, 0, 1); +} + +function welcome(name: string): string { + return `Welcome ${name}!`; +} + +const someValue: number = 2; + +const version: string = '_npmVersion'; + +// Export values to appear in jsx files +export { getLayerDuration, remap, welcome, someValue, version, fromOtherFile }; diff --git a/src/otherFile.ts b/src/otherFile.ts new file mode 100644 index 0000000..d2f8cd7 --- /dev/null +++ b/src/otherFile.ts @@ -0,0 +1 @@ +export const fromOtherFile = 'value in another file';