@animatorkit/editor 0.0.0-stage → 0.5.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE.md +39 -0
  2. package/README.md +92 -2
  3. package/cli.js +34 -0
  4. package/editor.js +747 -0
  5. package/editorkitkey.js +7 -0
  6. package/llm.txt +572 -0
  7. package/package.json +47 -4
  8. package/server.js +7 -0
  9. package/types/anime-helpers.d.ts +22 -0
  10. package/types/editor.d.ts +54 -0
  11. package/types/editorkitkey.d.ts +48 -0
  12. package/types/editortweaks.d.ts +126 -0
  13. package/types/gui/animation.d.ts +17 -0
  14. package/types/gui/drag.d.ts +55 -0
  15. package/types/gui/easearea.d.ts +114 -0
  16. package/types/gui/easetweak.d.ts +28 -0
  17. package/types/gui/gates/eases/irregular.d.ts +1 -0
  18. package/types/gui/gates/eases/spring.d.ts +1 -0
  19. package/types/gui/gates/eases/steps.d.ts +1 -0
  20. package/types/gui/gates/gate.d.ts +59 -0
  21. package/types/gui/gates/gizmo/controls.d.ts +8 -0
  22. package/types/gui/gates/gizmo/index.d.ts +9 -0
  23. package/types/gui/gates/kitstatus.d.ts +4 -0
  24. package/types/gui/gates/modes.d.ts +21 -0
  25. package/types/gui/gates/onscrolltweak.d.ts +14 -0
  26. package/types/gui/gates/randomtweak.d.ts +1 -0
  27. package/types/gui/gates/staggertweak.d.ts +8 -0
  28. package/types/gui/gates/styles.d.ts +1 -0
  29. package/types/gui/helpers.d.ts +56 -0
  30. package/types/gui/index.d.ts +56 -0
  31. package/types/gui/keyframes.d.ts +232 -0
  32. package/types/gui/keys.d.ts +31 -0
  33. package/types/gui/layout.d.ts +25 -0
  34. package/types/gui/license.d.ts +35 -0
  35. package/types/gui/magnet.d.ts +35 -0
  36. package/types/gui/multitweaks.d.ts +40 -0
  37. package/types/gui/mute.d.ts +21 -0
  38. package/types/gui/playback.d.ts +239 -0
  39. package/types/gui/props.d.ts +314 -0
  40. package/types/gui/rows.d.ts +215 -0
  41. package/types/gui/save.d.ts +16 -0
  42. package/types/gui/selection.d.ts +511 -0
  43. package/types/gui/status.d.ts +19 -0
  44. package/types/gui/styles.d.ts +1 -0
  45. package/types/gui/targetprops.d.ts +103 -0
  46. package/types/gui/timeline.d.ts +151 -0
  47. package/types/gui/timeoverlay.d.ts +31 -0
  48. package/types/gui/tweakclipboard.d.ts +77 -0
  49. package/types/gui/tweens.d.ts +28 -0
  50. package/types/gui/tweentweak.d.ts +189 -0
  51. package/types/gui/ui.d.ts +204 -0
  52. package/types/gui/versions.d.ts +11 -0
  53. package/types/gui/viewport.d.ts +66 -0
  54. package/types/helpers.d.ts +366 -0
  55. package/types/index.d.ts +2 -0
  56. package/types/serialize.d.ts +113 -0
  57. package/types/server.d.ts +11 -0
  58. package/types/singleeditor.d.ts +1 -0
  59. package/types/utils.d.ts +417 -0
  60. package/types/version.d.ts +2 -0
  61. package/types/vite.d.ts +20 -0
  62. package/version.js +7 -0
  63. package/vite.js +7 -0
package/LICENSE.md ADDED
@@ -0,0 +1,39 @@
1
+ # Anime.js Editor License
2
+
3
+ Copyright (c) 2026 Julian Garnier. All rights reserved.
4
+
5
+ The Anime.js Editor (the "Software") is free to use. For more editor features, check out Editor Kit at [https://animejs.com/animatorkit](https://animejs.com/animatorkit).
6
+
7
+ ## License Grant
8
+
9
+ The copyright holder grants you a free, on-going, non-exclusive, non-transferable license to use the Software as distributed.
10
+
11
+ ## You can
12
+
13
+ - use the Software to create, edit, and save animations in any number of projects, personal or commercial, including projects you build for clients
14
+ - ship the animations and the code you create with the Software in your projects. They are yours, and they need no license
15
+ - show the Software in a non-commercial demo, tutorial, or showcase
16
+ - install and share the Software as the unmodified `@animatorkit/editor` package, for example as a dependency of a project or a template
17
+
18
+ ## You cannot
19
+
20
+ - modify, copy, adapt, reverse engineer, or create derivative works of the Software
21
+ - distribute the Software in any other form than the unmodified `@animatorkit/editor` package
22
+ - offer the Software, or any part of it, as a feature of a commercial product or service, a product or service that is sold or supports a paid offering, for example a website builder, a design tool, a CMS, or a hosting platform that lets its own users edit animations with it
23
+ - remove or alter any copyright, license, or attribution notices contained in the Software
24
+
25
+ ## Other uses
26
+
27
+ If you need a use this license does not allow, write to support@animejs.com.
28
+
29
+ ## Enforcement
30
+
31
+ This license terminates automatically if you violate any of its terms. Upon termination, you must stop using the Software and remove it from your projects. The copyright holder reserves the right to pursue any and all legal remedies for unauthorized use of the Software.
32
+
33
+ ## Warranty
34
+
35
+ 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 non-infringement.
36
+
37
+ ## Liability
38
+
39
+ In no event shall the author 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.
package/README.md CHANGED
@@ -1,3 +1,93 @@
1
- # Temporary Holding Version
1
+ # Anime.js Editor
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A free visual editor for [anime.js](https://animejs.com) animations. Tweak durations, delays, easing curves, keyframes, and more in real time, then save the changes back to your source code as plain anime.js.
4
+
5
+ The editor runs on [tweaks](https://github.com/juliangarnier/tweaks). Set it up in your project folder:
6
+
7
+ ```bash
8
+ npx @animatorkit/editor
9
+ ```
10
+
11
+ The command installs `animejs`, and `tweaks` and `@animatorkit/editor` as dev dependencies, when they are missing, adds the Vite plugin to your Vite config, or creates one when your project uses Vite with no config. Without Vite, it adds an `editor` script that starts the save server. It also creates `editor.config.json`, and points `AGENTS.md` and `CLAUDE.md` to `llm.txt`.
12
+
13
+ To update the editor, update `@animatorkit/editor` with your package manager, for example `npm i -D @animatorkit/editor@latest`. With Editor Kit, use the kit command instead, see [Editor Kit](#editor-kit).
14
+
15
+ ## With Vite
16
+
17
+ The plugin loads the editor on every page `vite dev` serves and saves through the Vite server. Builds ship untouched.
18
+
19
+ ```js
20
+ // vite.config.js
21
+ import { defineConfig } from 'vite';
22
+ import editor from '@animatorkit/editor/vite';
23
+
24
+ export default defineConfig({ plugins: [editor()] });
25
+ ```
26
+
27
+ ## Without Vite
28
+
29
+ Start the save server with the `editor` script that the setup command adds, then import the editor in your code:
30
+
31
+ ```bash
32
+ npm run editor
33
+ ```
34
+
35
+ ```js
36
+ import '@animatorkit/editor';
37
+ ```
38
+
39
+ The script runs `animejs-editor serve`. To start it on another port, run `npm run editor 7349`.
40
+
41
+ ## Using the editor
42
+
43
+ The editor reads every running `animate`, `createTimeline`, `utils.set`, and `createLayout` call that has an id:
44
+
45
+ ```js
46
+ import { animate } from 'animejs';
47
+
48
+ animate('.box', {
49
+ id: 'my animation', // Required for the editor to register it
50
+ x: 200,
51
+ duration: 1000,
52
+ });
53
+ ```
54
+
55
+ ## Demo pages
56
+
57
+ On a page with no save server, such as a non-commercial public demo, disable saving right after the import. The panel and its versions keep working in the session, and the page never contacts a server:
58
+
59
+ ```js
60
+ import { editor } from '@animatorkit/editor';
61
+
62
+ editor.config({ save: false });
63
+ ```
64
+
65
+ The editor plays each animation once. To keep a looping demo looping, turn the transport loop on by default with `editor.config({ defaultPlayback: { loop: true } })`.
66
+
67
+ To open the demo on one animation or timeline child, select it by its id after the call that carries it:
68
+
69
+ ```js
70
+ editor.select('letters pop');
71
+ ```
72
+
73
+ ## Coding agents
74
+
75
+ Point your coding agent to `node_modules/@animatorkit/editor/llm.txt`, the rules for writing animations the editor can edit.
76
+
77
+ ## Editor Kit
78
+
79
+ The stagger, random, onScroll, spring, steps, and irregular editors and the on-page gizmo are Editor Kit features. The free version still shows, retimes, copies, and saves those values when your code uses them.
80
+
81
+ Get Editor Kit at [https://animejs.com/animatorkit](https://animejs.com/animatorkit). To upgrade, run the kit command, then paste the Editor Kit key from your account page at animejs.com:
82
+
83
+ ```bash
84
+ npx @animatorkit/editor kit
85
+ ```
86
+
87
+ It saves the key in your user config folder: `~/.config/animatorkit/` on macOS and Linux, `$XDG_CONFIG_HOME/animatorkit/` when that variable is set, and `%APPDATA%\animatorkit\` on Windows, downloads Editor Kit into `.animatorkit/`, which it adds to `.gitignore`, and installs it from there as an optional dependency, the `@animatorkit/editor-kit` package. With Vite, your config and your pages stay as they are: the plugin loads Editor Kit when it is installed. Without Vite, import `@animatorkit/editor-kit` in place of `@animatorkit/editor`. A build server or a teammate without a seat installs the project and gets the free editor. With Yarn 2 and later, set `nodeLinker: node-modules` in `.yarnrc.yml`. Yarn then fails an install without Editor Kit, so each developer and build server needs a seat.
88
+
89
+ Run the same command to update Editor Kit to the newest version your key allows, and after a clone to install it again, as git does not keep `.animatorkit/`. It moves `@animatorkit/editor` to the Editor Kit version. The two versions must match. A package manager only warns when they differ, and `npx @animatorkit/editor` then prints the kit command that matches them. To go back to the free editor, run `npx @animatorkit/editor free`. It removes Editor Kit from the project and keeps your key, which your other projects use. Without Vite, import `@animatorkit/editor` again in your pages. To remove the key from this machine, delete that `animatorkit` folder.
90
+
91
+ ## License
92
+
93
+ Free to use under the Anime.js Editor License, see [LICENSE.md](./LICENSE.md).
package/cli.js ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ /*!
3
+ * Anime.js Editor v0.5.0-beta
4
+ * Copyright (c) Julian Garnier. All rights reserved.
5
+ * Free to use under the Anime.js Editor License, see LICENSE.md. It may be redistributed only
6
+ * as the unmodified @animatorkit/editor package, and it may not be copied or modified.
7
+ */
8
+ import{spawnSync as U}from"node:child_process";import{existsSync as f,readFileSync as x,readdirSync as C,rmSync as D,mkdirSync as V,writeFileSync as j,renameSync as tt,appendFileSync as B,rmdirSync as et}from"node:fs";import{createRequire as ot}from"node:module";import{dirname as F,join as s,basename as T,relative as nt,sep as it}from"node:path";import{createInterface as st}from"node:readline";import{styleText as p}from"node:util";import{Writable as rt}from"node:stream";import{r as R,k as G,a as at}from"./editorkitkey.js";const l="@animatorkit/editor",h="@animatorkit/editor-kit",ct={npm:"-O",pnpm:"-O",yarn:"--optional",bun:"--optional"},N=`import editor from '${l}/vite';`,dt=`import { defineConfig } from 'vite';
9
+ ${N}
10
+
11
+ export default defineConfig({
12
+ plugins: [editor()],
13
+ });
14
+ `,lt="https://animejs.com/documentation/editor/getting-started/installation",L="editor.config.json",W={"pnpm-lock.yaml":"pnpm","yarn.lock":"yarn","bun.lock":"bun","bun.lockb":"bun","package-lock.json":"npm"},S=/^animatorkit-editor-kit-(\d+\.\d+\.\d+(?:-[\w.]+)?)\.tgz$/,y=".animatorkit",z=/^\w+-[0-9a-f]{20}$/i,M=["vite.config.js","vite.config.mjs","vite.config.ts","vite.config.mts","vite.config.cjs","vite.config.cts"],_=ot(import.meta.url)("./package.json"),a=process.cwd(),I=[];for(let t=a;!I.includes(t);t=F(t))I.push(t);const g=t=>p("cyan",t),J=(t,e,o)=>console.log(`${p(e,t)} ${o}`),u=t=>J("\u2714","green",t),c=t=>{J("\u2716","red",t),process.exit(1)},$=[];function ft(){console.log(p("bold","Usage")),console.log(` ${g("npx @animatorkit/editor")} set up the editor in this project`),console.log(` ${g("npx @animatorkit/editor kit")} add or update Editor Kit with the key of your account page`),console.log(` ${g("npx @animatorkit/editor free")} remove Editor Kit, the project keeps the free editor`),console.log(` ${g("npm run editor [port]")} start the save server, without Vite`)}const k=process.argv[2];if(k==="serve")(await import("./server.js")).serve(process.argv.slice(3));else if(k==="free")gt(Q());else{z.test(k||"")&&c(`Pass no key on the command line, it would stay in your shell history and the npm logs. Run ${g("npx @animatorkit/editor kit")} and paste the key when asked.`),k!==void 0&&k!=="kit"&&(ft(),c(`Unknown command ${k}`));const t=Q(),e=k==="kit"&&await kt();ut(t),e&&await pt(e,t);const o=A(),n=O(),i=K(h),r=K(l);n&&i!==r&&$.push({text:i?`Editor Kit ${i} needs @animatorkit/editor ${i}, this project has ${r}. Match them with your key:`:"Editor Kit is not installed here. Install it with your key:",code:"npx @animatorkit/editor kit"}),console.log(`
15
+ ${p(["bold","cyan"],`Setting up ${n?"Editor Kit":"the Anime.js Editor"}`)}
16
+ `),Y()?wt():Et(o,n,t),xt(),jt(),!n&&R()&&$.push({text:"An Editor Kit key is saved on this machine. Add Editor Kit here with:",code:"npx @animatorkit/editor kit"}),$.length&&(console.log(`
17
+ ${p("bold","Next steps")}
18
+ `),$.forEach(({text:m,code:d,note:v},E)=>{console.log(` ${E+1}. ${m}`),d&&console.log(` ${g(d)}`),v&&console.log(` ${p("dim",v)}`)})),console.log(`
19
+ ${p("dim","Docs")} ${lt}`)}function A(){const t=s(a,"package.json"),e=f(t)?JSON.parse(x(t,"utf8")):{};return{manifest:e,deps:{...e.dependencies,...e.devDependencies}}}function O(){return!!A().manifest.optionalDependencies?.[h]}function Y(){return M.some(t=>f(s(a,t)))||!!A().deps.vite}function ut(t){const{deps:e}=A();e.animejs||w(t,["add",`animejs@${_.peerDependencies.animejs}`]),e.tweaks||w(t,["add","-D",`tweaks@${_.peerDependencies.tweaks}`]),e[l]||w(t,["add","-D",`${l}@${_.version}`])}async function pt({tarball:t,token:e},o){const n=T(t),i=S.exec(n)[1],r=`${y}/${n}`;await ht(t,e,s(a,r)),mt(),K(l)!==i&&w(o,["add","-D",`${l}@${i}`]),O()&&!K(h)&&w(o,["remove",h]),w(o,["add",ct[o],`${h}@file:${r}`]),K(h)!==i&&c("Editor Kit did not install, see the output above");for(const m of C(s(a,y)))m!==n&&S.test(m)&&D(s(a,y,m))}async function ht(t,e,o){let n;try{n=await fetch(t,{redirect:"error",headers:{authorization:`Bearer ${e}`}})}catch{c(`Could not download ${T(t)}, check your connection and try again`)}n.ok||c(`The site answered ${n.status} for ${T(t)}, check the key on your account page`);try{V(F(o),{recursive:!0}),q(o,Buffer.from(await n.arrayBuffer()))}catch{c(`Could not download ${T(t)}`)}}function q(t,e,o){const n=`${t}.${process.pid}`;try{j(n,e,{mode:o,flag:"wx",flush:!0}),tt(n,t)}catch(i){throw D(n,{force:!0}),i}}function mt(){const t=s(a,".gitignore"),e=f(t)?x(t,"utf8"):"";e.split(/\r?\n/).includes(`${y}/`)||(B(t,`${e&&!e.endsWith(`
20
+ `)?`
21
+ `:""}${y}/
22
+ `),u(`Added ${y}/ to .gitignore, the Editor Kit tarball stays out of git`))}function gt(t){O()&&w(t,["remove",h]);const e=s(a,y);if(f(e)){for(const n of C(e))S.test(n)&&D(s(e,n));C(e).length||et(e)}u("Removed Editor Kit, this project uses the free editor"),Y()||console.log(`Import ${g(`'${l}'`)} again in your pages, in place of '${h}'.`);const o=R();o&&console.log(p("dim",`Your Editor Kit key stays in ${G(o.folder)} for your other projects. Delete that file to remove it from this machine.`))}function P(t){const e=I.map(o=>s(o,"node_modules",t));return e.find(o=>f(s(o,"package.json")))??e[0]}function K(t){const e=s(P(t),"package.json");return f(e)?JSON.parse(x(e,"utf8")).version:void 0}function H(t){return nt(a,t).split(it).join("/")}function $t(){const t=R();let e=!1,o=!1,n=0;const i=new rt({write:(d,v,E)=>{e||process.stdout.write(d),E()}}),r=st({input:process.stdin,output:i,terminal:process.stdin.isTTY});r.on("SIGINT",()=>{process.stdout.write(`
23
+ `),process.exit(130)});const m=()=>{if(o)return;const d=r.line.length;process.stdout.write(d>n?"*".repeat(d-n):"\b \b".repeat(n-d)),n=d};return process.stdin.on("keypress",m),new Promise(d=>{const v=E=>{if(o)return;o=!0,process.stdin.off("keypress",m),e&&process.stdout.write(`
24
+ `);const Z=E.trim();d(Z||t?.token||""),r.close()};r.question("Paste your Editor Kit key, or press Enter if you saved one before: ",v),e=!0,r.on("close",()=>v(""))})}async function yt(t,e){let o;try{o=await fetch(new URL("editor.tgz",t),{redirect:"manual",headers:{authorization:`Bearer ${e}`}})}catch{c(`Could not reach ${t.origin}, check your connection and try again`)}const n=o.headers.get("location");if(n===null){if(o.status===401){const r=O()?`. To go back to the free editor, run ${g("npx @animatorkit/editor free")}`:"";c(`This key is not valid, copy it again from your account page${r}`)}(o.headers.get("content-type")||"").startsWith("text/plain")&&c((await o.text()).replace(/[\x00-\x08\x0b-\x1f\x7f-\x9f]/g,"").slice(0,300)||`No Editor Kit release found at ${t.href}`),c(`The site answered ${o.status} and no download, check the key on your account page`)}const i=URL.canParse(n,t)?new URL(n,t).href:"";return(!i.startsWith(t.href)||!S.test(i.slice(t.href.length)))&&c("The site answered a download address the setup does not accept"),i}async function kt(){const t=at();t||c(`Refused the site ${process.env.EDITOR_KIT_SITE}, it must use https`);const e=await $t();e===""&&c("No key pasted, copy it from your account page"),z.test(e)||c("That is not an Editor Kit key, copy it from your account page");const o=await yt(t,e),n=G(t);try{V(F(n),{recursive:!0,mode:448}),q(n,`${e}
25
+ `,384)}catch{c(`Could not save your Editor Kit key in ${n}`)}return u(`Saved your Editor Kit key in ${n}`),{tarball:o,token:e}}function Q(){for(const e of I)for(const o in W)if(f(s(e,o)))return W[o];const t=(process.env.npm_config_user_agent||"").split("/")[0];return["pnpm","yarn","bun"].includes(t)?t:"npm"}function w(t,e){console.log(p("dim",`> ${t} ${e.join(" ")}`));const o=process.platform==="win32"?U(`${t} ${e.map(n=>`"${n}"`).join(" ")}`,{cwd:a,stdio:"inherit",shell:!0}):U(t,e,{cwd:a,stdio:"inherit"});o.status!==0&&c(o.error?`Could not start ${t}`:"The command failed, see its output above")}function wt(){const t=M.find(i=>f(s(a,i)));if(!t){j(s(a,"vite.config.mjs"),dt),u("Created vite.config.mjs with the editor plugin");return}const e=s(a,t),o=x(e,"utf8");if(o.includes(`${l}/vite`)){u(`${t} already loads the editor plugin`);return}const n=/\.c[jt]s$/.test(t)?null:vt(o);n?(j(e,n),u(`Added the editor plugin to ${t}`)):$.push({text:`Add the editor plugin to ${t}:`,code:`${N}
26
+ plugins: [editor()],`})}function vt(t){const e=[...t.matchAll(/\bplugins\s*:\s*\[(\s*)/g)],o=[...t.matchAll(/(?:defineConfig\(\s*|export default\s*)\{(\s*)/g)];let n;if(e.length===1)n=X(t,e[0],t[b(e[0])]==="]"?"editor()":`editor(),${e[0][1]||" "}`);else if(!e.length&&o.length===1)n=X(t,o[0],t[b(o[0])]==="}"?" plugins: [editor()] ":`plugins: [editor()],${o[0][1]||" "}`);else return null;const i=[...n.matchAll(/^import\s(?:[^'"]*?\sfrom\s*)?['"][^'"]+['"];?/gm)],r=i.length?b(i[i.length-1]):0;return`${n.slice(0,r)}${r?`
27
+ `:""}${N}${r?"":`
28
+ `}${n.slice(r)}`}function b(t){return t.index+t[0].length}function X(t,e,o){return t.slice(0,b(e))+o+t.slice(b(e))}function Et({manifest:t},e,o){t.scripts?.editor||(t.scripts={...t.scripts,editor:"animejs-editor serve"},j(s(a,"package.json"),JSON.stringify(t,null,2)+`
29
+ `),u('Added the "editor" script that starts the save server')),$.push({text:"Start the save server next to your dev server:",code:`${o} run editor`}),$.push({text:"Import the editor first in your page, before the code that creates animations:",code:`import '${e?h:l}';`,note:e?`It replaces import '${l}'. A teammate without a seat needs the free import.`:void 0})}function xt(){const t=s(a,L);if(f(t)){u(`${L} already exists`);return}j(t,`{
30
+ "$schema": "./${H(s(P("tweaks"),"config.schema.json"))}"
31
+ }
32
+ `),u(`Created ${L}`)}function jt(){const t=H(s(P(l),"llm.txt")),e=`Before writing animation code, read ${t} and follow its rules.`,o=["AGENTS.md","CLAUDE.md"].filter(n=>f(s(a,n)));for(const n of o){const i=s(a,n);x(i,"utf8").includes(t)||(B(i,`
33
+ ${e}
34
+ `),u(`Added the llm.txt rule to ${n}`))}o.length||$.push({text:"Tell your coding agent:",code:e})}