@docyrus/animaguru 0.36.0 → 0.39.0
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.
- package/README.md +77 -14
- package/dist/animaguru.js +281 -134
- package/package.json +1 -1
- package/skills/animaguru/SKILL.md +20 -4
- package/skills/animaguru/references/avatars.md +15 -2
- package/skills/animaguru/references/cloud.md +2 -2
- package/skills/animaguru-video/SKILL.md +19 -1
- package/templates/video/src/kit/gif.ts +40 -0
package/package.json
CHANGED
|
@@ -17,7 +17,8 @@ Before creative work in a multi-animation workspace, select or create the intend
|
|
|
17
17
|
|
|
18
18
|
Share the [animation-style gallery](https://animaguru.com/animation-styles), or open that URL in the internal browser when available, while asking the user to choose a style. Read the installed `animaguru.templates.json` for available styles and their skill names; `animaguru templates` lists the current CLI catalog. Offer the local catalog's choices so users select a skill actually installed in their workspace. Templates define appearance and motion; derive audience, message and story from the brief. Local scaffolding is separate from `projects create`, which creates a remote asset project. Never run `create` over an existing workspace.
|
|
19
19
|
|
|
20
|
-
- Run `animaguru schema` for the installed command structure and flags, and `animaguru catalog` for styles, subject kinds, actions, asset types, models, video settings, and speech voices; `catalog --type music|speech|sfx|model|image|vector|video|sprites|avatars` prints one section. Use `--help` on a leaf command for details.
|
|
20
|
+
- Run `animaguru schema` for the installed command structure and flags, and `animaguru catalog` for styles, subject kinds, actions, asset types, models, video settings, and speech voices; `catalog --type music|speech|sfx|model|image|vector|gif|video|sprites|avatars` prints one section. Use `--help` on a leaf command for details.
|
|
21
|
+
- AnimaGuru's CLI needs a plan on the account: Individual Starter, Individual Pro or Team. Every account starts with a 7-day Individual Starter trial, and members of a team on the Team plan are covered. `animaguru auth status` shows `plan` (with `trial.endsAt` during the trial) and `agents.allowed`. A `plan_required` error (HTTP 403), or a browser sign-in that says the CLI needs a plan, means the account has none: tell the person to choose a plan at https://animaguru.com/app/billing, and don't retry or work around it. The browser studio keeps working with their credits.
|
|
21
22
|
- Check `animaguru auth status`, `animaguru workspaces list`, and `animaguru credits` before generation. If sign-in is needed, run `animaguru auth login --no-browser` and let the user approve the printed browser URL. Select the user's requested Personal or team workspace with `animaguru workspaces use personal|TEAM_ID` before listing or creating projects. Do not read or print stored credentials. Agent runners may inject `ANIMAGURU_TOKEN` and `ANIMAGURU_WORKSPACE` as secrets or configuration.
|
|
22
23
|
- The default service is `https://animaguru.com`. Respect an existing `ANIMAGURU_URL` or pass `--url` to the leaf command when the user chooses another service. HTTP is supported only for loopback development.
|
|
23
24
|
- `animaguru skills install [--dir PATH]` (CLI 0.28.0) installs every AnimaGuru and PixiJS skill, the latest published on animaguru.com, into `.claude/skills/` and `.agents/skills/` with `npx skills`, and records them in `skills-lock.json`; run it when the user wants the skills in a folder or refreshed. `npx skills update --project --yes` refreshes them later. In a workspace made by an older CLI, newer skills may name commands or kit helpers its code lacks, so suggest updating the workspace as well.
|
|
@@ -74,11 +75,26 @@ HeyGen Voice (`heygen-voice-1`, or the faster and cheaper `heygen-voice-1-turbo`
|
|
|
74
75
|
|
|
75
76
|
CLI 0.27.0 adds vectors: `--type vector` draws an editable SVG with Ideogram on fal (`fal/ideogram-vector`), for logos, icons, mascots and flat illustrations that must stay sharp at any size or move shape by shape. `--workflow text-to-vector` (default) draws `--prompt` at `--quality low|medium|high` (13, 16 or 20 credits; 32 at high with references), with `--aspect-ratio auto` (default) or 1:4–4:1, `--seed`, and up to five `--references` (this project's images or sprite art, the first leading, named Image 1… in the prompt). `--workflow image-to-vector --source IMAGE_SHA` traces a saved image or sprite for 10 credits, with `--shapes detailed|simple` and no `--prompt`; to vectorize a brand logo or a generated picture, save it as an image asset first. `--download` saves `NAME.svg`. Vectors can't be used as image or video references. Check `catalog --type vector` before using them with an installed CLI.
|
|
76
77
|
|
|
78
|
+
CLI 0.38.0 adds a second vector model, GPT Image 2.6 (`--model fal/gpt-image-2.6-vector`). It draws from `--prompt` alone at `--quality low|medium|high`, with `--aspect-ratio auto` (default) or 1:3–3:1, and `--transparent` leaves out the background. It takes no `--references`, `--seed` or image-to-vector; use Ideogram to follow or trace an image. Its dry run holds 8, 12 or 22 credits by quality, and the job is charged the tokens fal meters.
|
|
79
|
+
|
|
77
80
|
```sh
|
|
78
81
|
animaguru assets generate PROJECT_ID --type vector --name "Fox mascot" \
|
|
79
82
|
--prompt "A friendly fox mascot waving, flat colors, bold clean outlines" --quality medium --dry-run
|
|
80
83
|
animaguru assets generate PROJECT_ID --type vector --name "Logo" \
|
|
81
84
|
--workflow image-to-vector --source IMAGE_SHA --shapes simple --dry-run
|
|
85
|
+
animaguru assets generate PROJECT_ID --type vector --model fal/gpt-image-2.6-vector --name "Badge" \
|
|
86
|
+
--prompt "A round coffee shop badge, two flat colors" --transparent --dry-run
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
CLI 0.38.0 adds animated GIFs: `--type gif` draws a short loop with GPT Image 2.6 on fal, for a sprite's walk or idle cycle, an icon that moves or a sticker. `--prompt` is required; describe one motion that loops and say the subject stays the same in every frame. `--frames 2–16` (default 9), `--frame-ms 20–2000` per frame (default 200, rounded to 10), `--aspect-ratio 1:1|3:2|2:3|16:9|9:16` (default 1:1), `--quality low|medium|high` (default medium), `--transparent` for frames without a background, and up to four `--references` (this project's images, GIF stills or sprite art, named Image 1… in the prompt) to animate or follow. `--model fal/gpt-image-2.6-gif` (Flare, default) is faster and `fal/gpt-image-2.6-sunburst-gif` finer and slower. All frames share one 3840×2160 picture, so more frames are smaller: nine square frames are 960×960, sixteen 720×720 (`catalog --type gif` lists every size). The dry run holds credits at still-image prices for those frames (about 31 for the defaults); fal meters what is charged. `--download` saves `NAME.gif`. A GIF's `file` SHA, or its `preview` (a PNG of the first frame), works wherever a saved image does: a video's `--reference`, `--end-reference` or `--references`, an image's `--references`, a vector to trace, a 3D model's `--reference`. So to put a GIF in a generated video, pass its SHA as the frame or reference. In a film workspace, play the GIF itself with the kit's `gifClip()` (see `animaguru-video`). Check `catalog --type gif` before using GIFs with an installed CLI.
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
animaguru assets generate PROJECT_ID --type gif --name "Fox walk" \
|
|
93
|
+
--prompt "A cartoon fox walk cycle, side view, the same fox in every frame" --frames 8 --frame-ms 120 --transparent --dry-run
|
|
94
|
+
animaguru assets generate PROJECT_ID --type gif --name "Fox wave" \
|
|
95
|
+
--prompt "The fox from Image 1 waves its paw, then holds still" --references CHARACTER_SHA --frames 6 --dry-run
|
|
96
|
+
animaguru assets generate PROJECT_ID --type video --name "Fox walks off" \
|
|
97
|
+
--prompt "The fox walks out of the frame to the right" --reference GIF_SHA --dry-run
|
|
82
98
|
```
|
|
83
99
|
|
|
84
100
|
CLI 0.28.0 adds 3D models: `--type model` builds a GLB from a saved image (`--reference SHA`, best) or from `--prompt` alone, with `--model tripo-h3.1` (default) or `hunyuan-3d-3.1-pro`, `--no-texture`, `--no-pbr` and `--faces`. `--rig` auto-rigs a humanoid character standing in a T- or A-pose, with `--animations idle,walk,wave` (named clips from `catalog --type model`, or Meshy library numbers; default idle,walk) and `--height` in metres. Downloads are `.glb`. CLI 0.35.0 adds `--model idol`: photoreal Gaussian splats of the object in a saved image (`--reference SHA`, required; `--photo` for a camera photo, `--splats`, `--seed`), downloaded as `.spz` and staged with the kit's `stage.splat()`. Read `animaguru-3d-models` before generating models or building 3D shots: it covers costs, rig limits (no fingers or facial blend shapes), when splats or meshes fit, optimisation and the kit's three.js stage.
|
|
@@ -102,7 +118,7 @@ animaguru files get PROJECT_ID references/ID/document.pdf --output references/le
|
|
|
102
118
|
|
|
103
119
|
`jobs wait` tracks only the specified job. Drawing can queue follow-up animations: inspect `jobs list` and wait for the relevant jobs before exporting. A timeout or CLI exit does not cancel server work. CLI 0.32.0 adds `jobs cancel PROJECT_ID JOB_ID --yes`. A project runs its jobs one at a time; this cancels a queued job, or stops a running one at its next check on the provider, and the job fails with the reason. Credits it already spent stay spent, and a result the provider hasn't returned is lost. Use it when the user asks, or when one job is stuck and holds up the jobs behind it; never to hurry a job that is only slow. Inspect existing jobs before retrying a paid submission to avoid duplicate charges. Report failed jobs and their errors instead of repeatedly submitting the same work.
|
|
104
120
|
|
|
105
|
-
`projects move PROJECT_ID --to OTHER_PROJECT_ID [--characters SLUG,SLUG] [--assets ASSET_ID] [--avatars GROUP_ID]` moves work between projects for free: characters with all their animations, saved assets and the
|
|
121
|
+
`projects move PROJECT_ID --to OTHER_PROJECT_ID [--characters SLUG,SLUG] [--assets ASSET_ID] [--avatars GROUP_ID]` moves work between projects for free: characters with all their animations, saved assets and, to a project in another workspace, the workspace's own avatars. Use it to gather work into one project instead of regenerating it; it needs CLI 0.16.0.
|
|
106
122
|
|
|
107
123
|
`files get` downloads one file by its path from `files list`, such as an image, clip or PDF the user attached as a reference. `files export` downloads a ZIP. Both refuse to overwrite an existing file. Choose a fresh output path. Inspect the exported manifest and actual assets before integrating them into the game or app; use their real dimensions, frame ordering, and animation metadata.
|
|
108
124
|
|
|
@@ -138,7 +154,7 @@ CLI 0.20.0 also adds quiz films for educational explainers, lessons and training
|
|
|
138
154
|
|
|
139
155
|
## Asset library
|
|
140
156
|
|
|
141
|
-
|
|
157
|
+
Every plan (Individual Starter and its trial, Individual Pro, Team): `animaguru library search DESCRIPTION [--type sprite|image|video|music|speech|sfx] [--labels a,b]` finds ready-made assets; `animaguru library import ID --project PROJECT_ID` copies one into a project and `animaguru library download ID --output DIR` saves its files. Search it before generating common assets (whooshes, background music, stock clips, characters); importing spends no credits.
|
|
142
158
|
|
|
143
159
|
## Saved brand kits
|
|
144
160
|
|
|
@@ -149,6 +165,6 @@ Pro and Team accounts: `animaguru library search DESCRIPTION [--type sprite|imag
|
|
|
149
165
|
Read these only when the task needs them:
|
|
150
166
|
|
|
151
167
|
- `references/sprites.md`: animate, redraw or import sprite characters (`jobs submit` JSON).
|
|
152
|
-
- `references/avatars.md`: HeyGen avatars and
|
|
168
|
+
- `references/avatars.md`: HeyGen avatars, looks, voices and avatar videos.
|
|
153
169
|
- `references/sharing.md`: hosting on AnimaGuru (`submit`, `videos`) and uploading to YouTube. Making or exporting a film never authorizes sharing it.
|
|
154
170
|
- `references/cloud.md`: cloud sync, versions and cloning.
|
|
@@ -4,7 +4,7 @@ Read from the `animaguru` skill only when the user wants a HeyGen avatar.
|
|
|
4
4
|
|
|
5
5
|
## HeyGen avatars
|
|
6
6
|
|
|
7
|
-
CLI 0.13.0 adds `avatars`. Check `animaguru avatars --help` before using it with an installed CLI. A group is a character, its looks are outfits, poses or styles, and a look ID is what HeyGen renders with. `avatars list PROJECT_ID` browses HeyGen's public catalog from any project; `--ownership private` lists the avatars
|
|
7
|
+
CLI 0.13.0 adds `avatars`, and 0.37.0 adds `avatars video` and `avatars voices`. Check `animaguru avatars --help` before using it with an installed CLI. A group is a character, its looks are outfits, poses or styles, and a look ID is what HeyGen renders with. `avatars list PROJECT_ID` browses HeyGen's public catalog from any project; `--ownership private` lists the avatars of the project's workspace. Every project in that workspace can use them, and no other workspace can see, change or render them. `avatars looks PROJECT_ID --group GROUP_ID` lists a character's looks, and `avatars templates` lists Look Pack and look template IDs.
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
10
|
animaguru avatars create PROJECT_ID --type prompt --name "Ada" \
|
|
@@ -19,4 +19,17 @@ animaguru avatars wait PROJECT_ID LOOK_ID
|
|
|
19
19
|
|
|
20
20
|
`--file` and `--reference-images` take a project file SHA, an HTTPS URL (up to 32 MB) or a local file (up to 8 MB). Photos and footage show a real person: pass `--subject-consent` only after the user confirms that person agreed to become an avatar, and do not make avatars of people the user has no permission to depict. A `digital_twin` trains on about two minutes of footage and also needs the person's own consent: run `avatars consent PROJECT_ID GROUP_ID`, give them the 24-hour link, and check `consentStatus` with `avatars get PROJECT_ID --group GROUP_ID`.
|
|
21
21
|
|
|
22
|
-
Avatars and looks are charged when HeyGen accepts them and need `--yes`; get the estimate with `--dry-run` first. New looks start `processing`: use `avatars wait` rather than creating them again. `avatars rename`, `avatars voice` (default voice) and `avatars delete --yes` change only the
|
|
22
|
+
Avatars and looks are charged when HeyGen accepts them and need `--yes`; get the estimate with `--dry-run` first. New looks start `processing`: use `avatars wait` rather than creating them again. `avatars rename`, `avatars voice` (default voice) and `avatars delete --yes` change only the workspace's own avatars; deletion is permanent and also deletes the voice cloned for a digital twin, so run it only when the user asks to delete that avatar.
|
|
23
|
+
|
|
24
|
+
## Avatar videos
|
|
25
|
+
|
|
26
|
+
`avatars video` makes a video of one completed look (the workspace's or a public one) and saves it to the project as a video asset. Give `--script` (or `--script-file`, up to 1,500 characters) for the avatar to speak, or `--audio SHA` for saved speech or music to lip-sync, up to 120 seconds. Without `--voice` a script uses the look's own voice; `avatars voices PROJECT_ID --language Turkish` lists public voices, and `--ownership private` the voices cloned from the workspace's digital twins. Voices cloned for another workspace are refused. `--model` picks the engine (`heygen/avatar-iv` by default, `heygen/avatar-v`, `heygen/avatar-iii`) and must be in the look's `supportedEngines`. A digital twin renders only once its subject's consent is accepted.
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
animaguru avatars video PROJECT_ID --look LOOK_ID --name "Welcome" \
|
|
30
|
+
--script "Hi, I'm Ada. Here is what we shipped this week." --dry-run
|
|
31
|
+
animaguru avatars video PROJECT_ID --look LOOK_ID --name "Voice-over cut" --audio SPEECH_SHA --yes
|
|
32
|
+
animaguru jobs wait PROJECT_ID JOB_ID
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The dry run asks the server, which checks the look, voice and audio and measures the audio's length. The video is charged for the seconds HeyGen makes; wait for the returned job with `jobs wait` and find the video with `assets list`.
|
|
@@ -4,7 +4,7 @@ Read from the `animaguru` skill only when the user asks for cloud sync, versions
|
|
|
4
4
|
|
|
5
5
|
## Cloud sync and versions
|
|
6
6
|
|
|
7
|
-
CLI 0.11.0 adds `animaguru cloud` for users on Individual Pro or Team. Discover it in `animaguru schema`. Commands run from anywhere inside a video workspace; `--dir PATH` selects another folder.
|
|
7
|
+
CLI 0.11.0 adds `animaguru cloud` for users on Individual Starter (including its 7-day trial), Individual Pro or Team. Discover it in `animaguru schema`. Commands run from anywhere inside a video workspace; `--dir PATH` selects another folder.
|
|
8
8
|
|
|
9
9
|
Only link a folder when the user asks for cloud sync. A folder syncs with one AnimaGuru project's animations, shown on that project's Animations tab in the studio. `cloud link --project PROJECT_ID` syncs with an existing project (`prj_…`); without it, `cloud link` creates a new project named after the folder (or `--name`) in the selected AnimaGuru workspace (`workspaces use` picks a team). In a linked folder:
|
|
10
10
|
|
|
@@ -16,4 +16,4 @@ Only link a folder when the user asks for cloud sync. A folder syncs with one An
|
|
|
16
16
|
|
|
17
17
|
`cloud versions` lists history. `cloud restore VERSION [--path P]` brings back an earlier version without rewriting history; then push to save it as the newest version. Restore refuses to replace unsaved changes unless `--yes`, and needs the user's go-ahead. `cloud clone PROJECT_ID DIR` downloads a project; run `npm install` there. `cloud list` lists projects with synced animations. `cloud delete PROJECT_ID --yes` permanently removes the project's animations: every version, Animator draft and stored file, while the project and its assets stay. Run it only when the user asks to delete those animations.
|
|
18
18
|
|
|
19
|
-
Sync never uploads node_modules, exports, frames, `.env` files, credentials, keys, links or `.gitignore`/`.animaguruignore` matches. Add bulky regenerable files to `.animaguruignore` rather than deleting them. Images, video, audio and ZIP files are stored once in cloud storage at any size and count toward the plan's media storage (20 GB Pro, 100 GB per Team). Every other file is versioned in Git. A work file over 32 MB stops the push: tell the user, and ignore or move it only with their agreement. If the plan ended, pushing is refused, but pulling and cloning still work. Never read or print `.animaguru/sync/` tokens; the CLI requests short-lived Git credentials itself.
|
|
19
|
+
Sync never uploads node_modules, exports, frames, `.env` files, credentials, keys, links or `.gitignore`/`.animaguruignore` matches. Add bulky regenerable files to `.animaguruignore` rather than deleting them. Images, video, audio and ZIP files are stored once in cloud storage at any size and count toward the plan's media storage (5 GB Starter, 20 GB Pro, 100 GB per Team). Every other file is versioned in Git. A work file over 32 MB stops the push: tell the user, and ignore or move it only with their agreement. If the workspace's plan ended, pushing is refused, but pulling and cloning still work while the account itself has a plan; on `plan_required`, tell the person to choose a plan at https://animaguru.com/app/billing, and that the studio's Animations tab still downloads the films. Never read or print `.animaguru/sync/` tokens; the CLI requests short-lived Git credentials itself.
|
|
@@ -81,6 +81,7 @@ Build on the shared kit instead of re-implementing helpers: `src/kit/` in a stan
|
|
|
81
81
|
- Motion: `win`, `inOut`, `easeOut`/`easeIn`/`easeInOut`/`easeBack`, `bump`, `lerp`, `mixColor`, `hex`, seeded `rng`, `show`, `setText`.
|
|
82
82
|
- Text and fonts: `txt(value, size, { family: "heading" | "body" | "mono", weight, fill, … })`, `useBrandFonts(branding, monoFamily?)`, `loadFonts([{ family, url }])` (variable fonts get their weight range), `gradientFill(colors)`.
|
|
83
83
|
- Drawing: `panel`, `partialLine`, `bezier`, `pointAt`, `check`, `cross`, `person`, `glowTexture`, `vignetteTexture`, `rasterSvg` (exact-width logo textures), `Badge`, `Pill`.
|
|
84
|
+
- GIFs: `gifClip(url, { loop, speed, scaleMode })` from `kit/gif` (kept out of the index), an animated GIF as a sprite on the film clock. See [GIFs](#gifs).
|
|
84
85
|
- Layout: `safeArea(config)` and `stack(nodes, { x, y, gap })`. Set `"safeArea": "reels"` (or `{ top, right, bottom, left }` pixels) in `film.config.json` for vertical social films; review checks text against it.
|
|
85
86
|
|
|
86
87
|
Keep `src/film.ts` to setup and the scene list, and put each scene in `src/scenes/NAME.ts` as `export function hook(film: FilmBase, cue: CueSheet) { … }` that adds to `film.world` and calls `film.on`. Write and fix one scene file at a time with targeted edits rather than rewriting the whole film. Claude Code's Write tool refuses to replace a file that has not been opened with Read in this session (`cat` does not count), so Read the starter `src/film.ts` before replacing it.
|
|
@@ -95,7 +96,24 @@ Pro and Team accounts can take ready-made music, sound effects, voice-overs, cli
|
|
|
95
96
|
|
|
96
97
|
## Vectors
|
|
97
98
|
|
|
98
|
-
Logos, icons and flat mascots can be generated as SVG (`animaguru assets generate PROJECT_ID --type vector …`, see the `animaguru` skill) or traced from a saved image (`--workflow image-to-vector`), then saved into the film with `--download public/assets/`. Draw one with the kit's `rasterSvg(url, width)` at the width it appears on screen, so it stays sharp; for shapes that scale or move separately, load it as geometry with `Assets.load({ src, data: { parseAsGraphicsContext: true } })` and `new Graphics(context)` (see `pixijs-assets`). Ask for `--shapes simple` or `--quality low` when the art will be small or animated part by part.
|
|
99
|
+
Logos, icons and flat mascots can be generated as SVG (`animaguru assets generate PROJECT_ID --type vector …`, see the `animaguru` skill) or traced from a saved image (`--workflow image-to-vector`), then saved into the film with `--download public/assets/`. Ideogram (the default) can follow reference images; `--model fal/gpt-image-2.6-vector` draws from the prompt alone and takes `--transparent`, so the art comes without a background to place over a scene. Draw one with the kit's `rasterSvg(url, width)` at the width it appears on screen, so it stays sharp; for shapes that scale or move separately, load it as geometry with `Assets.load({ src, data: { parseAsGraphicsContext: true } })` and `new Graphics(context)` (see `pixijs-assets`). Ask for `--shapes simple` or `--quality low` when the art will be small or animated part by part.
|
|
100
|
+
|
|
101
|
+
## GIFs
|
|
102
|
+
|
|
103
|
+
A GIF asset (`animaguru assets generate PROJECT_ID --type gif …`, see the `animaguru` skill) is a short looping animation drawn by GPT Image 2.6: a character's walk or idle cycle, a waving mascot, a spinning coin, a blinking icon. Pass a saved image or sprite art as `--references` to animate that exact character, and `--transparent` for frames without a background to place over a scene. Save it into the film with `--download public/assets/`.
|
|
104
|
+
|
|
105
|
+
Never play a GIF with an `<img>` or a GifSprite that runs on its own: it would follow the wall clock, so seeking, review frames and the MP4 export would show other frames than the preview. Load it with the kit's `gifClip` and drive it from the scene's update:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { gifClip } from "../kit/gif"; // workspace: "../../../../runtime/kit/gif" from src/scenes/
|
|
109
|
+
|
|
110
|
+
const fox = await gifClip(publicAsset("assets/fox-wave.gif"), { scaleMode: "nearest" }); // nearest keeps pixel art crisp
|
|
111
|
+
fox.sprite.anchor.set(0.5, 1); fox.sprite.position.set(960, 900);
|
|
112
|
+
film.world.addChild(fox.sprite);
|
|
113
|
+
film.on((t) => { fox.at(t - 4.2); fox.sprite.visible = t >= 4.2; });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`at(seconds)` shows the frame for that moment of the GIF from its own frame timings, looping unless `{ loop: false }` (then it holds the last frame); `speed` plays it faster or slower, and `frames`/`duration` give its length. Move, scale and fade the sprite with the usual motion helpers while it plays. Each frame is a separate texture, so keep a film to a few GIFs; for a long or many-frame cycle use a sprite sheet with `AnimatedSprite` instead. A GIF can also open an AI clip: its file SHA works as `--reference` for `assets generate --type video` (the server uses its first frame).
|
|
99
117
|
|
|
100
118
|
## Voiceover, music and captions
|
|
101
119
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Assets } from "pixi.js";
|
|
2
|
+
import { GifSprite, type GifSource } from "pixi.js/gif";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
Animated GIFs on the film's clock. Import from "./kit/gif" (standalone) or "../../../runtime/kit/gif"
|
|
6
|
+
(workspace animation); it is kept out of the kit's index so films without a GIF don't load the
|
|
7
|
+
GIF decoder.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type GifClip = {
|
|
11
|
+
/** A Sprite showing the frame `at` chose; position, scale and anchor it like any sprite. */
|
|
12
|
+
sprite: GifSprite;
|
|
13
|
+
/** How many frames the GIF has, and how long one loop plays in seconds. */
|
|
14
|
+
frames: number;
|
|
15
|
+
duration: number;
|
|
16
|
+
/** Shows the frame for `seconds` into the GIF (pass `t - start` from the scene's update). */
|
|
17
|
+
at: (seconds: number) => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
Loads an animated GIF, such as an AnimaGuru GIF asset (a sprite's walk cycle, a moving icon), as a
|
|
22
|
+
sprite that never plays by itself: each update calls `at`, which picks the frame from the GIF's own
|
|
23
|
+
frame timings. Preview, seeking, review frames and MP4 export then show the same frame at the same
|
|
24
|
+
moment. It loops unless `loop` is false, when it holds its last frame; `speed` scales its timing.
|
|
25
|
+
Pixel-art GIFs stay crisp with `scaleMode: "nearest"`.
|
|
26
|
+
*/
|
|
27
|
+
export async function gifClip(url: string, { loop = true, speed = 1, scaleMode }: { loop?: boolean; speed?: number; scaleMode?: "linear" | "nearest" } = {}): Promise<GifClip> {
|
|
28
|
+
const source = await Assets.load<GifSource>(scaleMode ? { src: url, data: { scaleMode } } : url);
|
|
29
|
+
const sprite = new GifSprite({ source, autoPlay: false, autoUpdate: false, loop });
|
|
30
|
+
const last = source.totalFrames - 1;
|
|
31
|
+
const at = (seconds: number) => {
|
|
32
|
+
const ms = Math.max(0, seconds * speed * 1000);
|
|
33
|
+
if (!loop && ms >= source.duration) { sprite.currentFrame = last; return; }
|
|
34
|
+
const time = ms % source.duration;
|
|
35
|
+
const index = source.frames.findIndex((frame) => time >= frame.start && time < frame.end);
|
|
36
|
+
sprite.currentFrame = index === -1 ? last : index;
|
|
37
|
+
};
|
|
38
|
+
at(0);
|
|
39
|
+
return { sprite, frames: source.totalFrames, duration: source.duration / 1000, at };
|
|
40
|
+
}
|