@topy-ai/maggie 0.8.16 → 0.8.17
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-zh-TW.md +1 -1
- package/README.md +1 -1
- package/bundled-references/image-recipes.md +30 -0
- package/bundled-references/web-animation-patterns.md +124 -29
- package/bundled-skills/maggie-image/SKILL.md +6 -2
- package/bundled-tools/clis/maggie_image.py +28 -1
- package/package.json +1 -1
- package/references/image-recipes.md +30 -0
- package/references/web-animation-patterns.md +124 -29
package/README-zh-TW.md
CHANGED
|
@@ -143,7 +143,7 @@ structure drift 或重複 treatment product 時 fail closed。
|
|
|
143
143
|
deployment、memory、feedback 和 MaggieDash。內容先 draft/review,外部寫入、
|
|
144
144
|
publish 與 production deployment 需要明確確認。
|
|
145
145
|
|
|
146
|
-
目前 npm 版本為 `0.8.16
|
|
146
|
+
目前 npm 版本為 `0.8.17`,收尾最後兩個完整源碼覆蓋缺口:`inkscape/inkscape`(GitHub 鏡像僅 2 檔 stub,改從 GitLab clone 7053 檔逐一代碼級研究)與 L 類 web 動效庫(先前僅 README/API 層,現讀完整源碼)。net-new(借鑑邏輯非程式碼):`maggie_image.py` 新增 `svg-export --actions`(一次 Inkscape 呼叫完成清理+展平+匯出)與 `svg-query`(元素 id + 邊界框);`web-animation-patterns` 補上源碼級更正(AOS 其實是 scroll+throttle 而非 IntersectionObserver;lenis `autoRaf` 預設 false 且有 `respectReducedMotion`;typed.js 為 GPL-3.0 且無減動支援)與新點子(設計師友善的彈簧詞彙、mojs `Burst` 微互動條目、anime v4 網格 stagger、pixijs 超出範圍邊界註記)。`0.8.16` 把先前僅 README 的 repo 解稀疏為完整源碼並逐一代碼級研究(驗證所有 reference 並補 net-new:Remotion delayRender gate、opentoonz BSD 可移植的 xsheet 時間線、綠幕/LUT/卡拉OK 濾鏡、whisper turbo + 字幕旗標、Babylon NullEngine 無頭),並新增 maggie_image.py trim/auto-orient 與更豐富的 captions 旗標。先前 0.8.15 補齊除 Q 外所有設計類的覆蓋:maggie_image.py 新增 svg-export(Inkscape)/composite/look,新增 design-editor-patterns reference,並擴充 web-animation/generative-visuals/video-timeline;docs/design-coverage-audit.md 逐 repo 確認。先前 0.8.14 新增 `maggie-ai-media`(去背/放大/arm's-length ComfyUI 的命令生成器,自身不下載模型、不用 GPU),讓 Q 類達到同級;重型執行仍受成本把關。先前 0.8.13 新增 AI 媒體生成規劃 reference(Q 類:自託管模型概覽、程式碼授權≠權重授權規則、商用安全子集 rembg/Real-ESRGAN、成本/BYOK 守則;實際建置待明確許可)。先前 0.8.12 收尾其餘設計類:新增 `maggie-image`(影像處理 CLI:尺寸/OG/favicon/WebP-AVIF/svg/montage)與 web 動效、生成式視覺、圖像配方、字幕四個 reference。先前 0.8.11 收尾 N 類影片功能:`maggie_video.py compile` 再補上視頻 clip ken-burns、sidechain ducking、以及非透明度 overlay 效果(move/slide、圖片 zoom),並新增 `autocut` 子命令(silencedetect 去靜音)。先前 0.8.10 新增圖片 ken-burns + 文字透明度關鍵幀與 `captions`(whisper)子命令。先前 0.8.9 新增 `compile`(宣告式 timeline JSON→單一 ffmpeg 命令)。先前 0.8.8 新增 `maggie-video`(製作與處理行銷影片:剪輯、字幕、裁切成各渠道比例、浮水印、轉碼、響度正規化、clip 組裝、程式化動畫),附一個實測可用的 ffmpeg 配方 CLI(`maggie_video.py`),從參考庫的影片專案(moviepy/editly/ffmpeg 命令層、Revideo/Motion Canvas/CCapture 程式化渲染、MLT/OpenShot/Olive 的 timeline 資料形狀)提煉而來;另加 `ffmpeg-recipes`、`programmatic-video`、`video-timeline-model` 三個 reference。先前 0.8.7 把 redesign 稽核併入 `maggie-design`(改編自 MIT 的 `elayadesign/redesign-skill`):掃描 + 診斷 AI 通病/缺失狀態/雜亂程式碼,再經 in-place/verify 流程就地修正,因此「稽核/打磨/升級既有站點」會路由到 maggie-design。先前 0.8.6 補齊兩個設計技能:加入完整的生產 reference,並把設計來源明確為 Figma 非必需(實時 URL、既有程式碼、Figma、或純截圖)。先前 0.8.5 採納兩個設計技能(改編自 MIT 的 `elayadesign/ai-design-skills`):maggie-landing-page(轉化策略 + 視覺系統紀律,具體數值為可被專案 DESIGN.md 覆蓋的預設值;由 maggie-design 生產與驗證)與 maggie-design-motion(靜態設計→像素級動畫 HTML 複刻→匯出 MP4 + GIF)。先前 0.8.4 將技能庫擴展成完整的「一人用 AI 跑一家公司」C-suite,新增八條職能線:maggie-sales(CRM 中立的銷售管線)、maggie-finance(只解釋的 CFO 指標,含確定性 maggie_finance.py 計算器)、maggie-support(面向客戶的客戶成功)、maggie-product(路線圖 + 預註冊實驗)、maggie-fundraising(pitch deck、data room、投資人更新)、maggie-legal(ToS/隱私/DPA/SOC2 readiness)、maggie-monetization(定價/paywall/dunning,金錢操作需人工批准)、maggie-orchestrator(CEO 編排層:將目標拆成帶審批門的 mission 分派到各職能線,含 maggie_orchestrator.py 規劃器)。先前 0.8.3 將 cmo.so/www 開發經驗沉澱進技能庫:新增兩個技能 maggie-skill-authoring(依 catalog 與 MCP 工具白名單撰寫/校驗社區營銷 playbook 技能)與 maggie-feedback-triage(反饋的團隊接收端:決策/定級/分派、PRD + issue 流程、24/7 隊列守護);新增多個 reference(OAuth PKCE 登入、Expo 約定與 Router 骨架、MCP evals 測試框架、conversation cards、WordPress→Firebase 認證遷移手冊);並增補 maggie-assistant-tools(tool≤user 每輪工具過濾、agent loop 安全不變量、preview-only 橋接代理、MCP resources/prompts、注解加固、CLI 與 ChatGPT 插件打包)、maggie-auth-reference(自清理登入測試套件、自簽單次令牌)、maggie-mobile-app(OTA 開機拉取、live==built 部署守衛)、maggie-deployment(pm2 單包發布、live-hash 校驗)與 maggie-ops(template-as-code 郵件同步)。先前 0.8.2 新增 maggie-spirit(為 AI 品牌生成平面像素 spirit/sprite 系統)與 goal-led AI agent 設計參考;0.8.0 為安全優化 roadmap(scan、image-patch、標頭評分、SSVC、GDPR 日誌規則、新 MCP 工具)。先前 0.8.0 為安全優化 roadmap(scan、image-patch、標頭評分、SSVC、GDPR 日誌規則、新 MCP 工具),含 fix-plan 修補風險分級 T1–T4(判斷補丁是否安全套用)與 host-impact 補丁影響面量測(哪些服務需重啟、是否需重開機)、public-check、Maggie Security、batch 31 排程 agent routines、報告收件匣與無人值守 agent 限制、PHP runtime 盤點與主機鎖、pull 網站改寫、query 點子與社群佇列檢查,batch 30 MaggieDash 先裝核心、release privacy gate、feedback 備援、社群連結與圖片檢查、大量頁面產生與 app 檢查,batch 29 預約規則、部署、app QA、助理與社群功能,以及 batch 28 產品 app、assistant tools、mobile、product release、skills catalog 與 bridge host 功能、batch 26、27 feedback 修正與 idempotent `maggie update`與 Booking email-template 合約/CLI validator 同步。本版完成 2026-09-24 booking feedback batch:Calendar grid/free-slot entry 與 host modal focus-restoration evidence。本版新增 Starter marketplace provisioning plan;本版完成 feedback batches 22、23:加入 declarative browser interaction evidence、design markup/style/content-key gate、compiler source anchoring、entity double-escape protection、`update --help` read-only、noindex hypothetical indexability、可過期 baseline acknowledgement、DOM-only link extraction regression,以及 MaggieDash 0.2.10 的 content override、短期 browser session、CDN-safe public-session cache contracts。authentication 和 isolated dev server 仍由 host 負責。`maggie-booking` workflow、傳統 email/password、Stripe、Resend、public booking flow 及既有安全邊界維持不變;provider-bound video generation 與 transactional delivery 仍記錄在 issue #39,前一批延後功能仍在 issue #38,不會直接成為 active memory。0.7.33 記錄並審查一筆更正回饋;確認 0.7.32 已正確處理 batch index,沒有修改已驗證的 shared behavior。0.7.32 加入 feedback 一基索引支援、MaggieDash panel 的 source/freshness/error evidence、Consent Mode 與實際 write/no-op reconciliation、SEO baseline recapture、sitemap origin rebasing、content-diff scope、migration ledger reconciliation、deployment credential preflight、release provenance/runtime preflight、icon release gate、opt-in blog auto-publish gate,以及 least-privilege VPS deployer。也修復 top-level `maggie feedback` dispatcher parity。0.7.31 加入 update 差異摘要、atomic installer copy、subset install manifest merge,以及 inventory drift 時 doctor non-zero。0.7.30 補上 feedback tracking issue closeout gate 與 batch 14/15 audit ledger。0.7.29 修正 npm package landing page 使用英文 README;0.7.28 加入 versioned Gemini model policy、明確 fallback 與 provenance、bundled-first CLI
|
|
147
147
|
dispatch、`maggie --version`、feedback batch review 聚合與重複偵測、marketplace enrichment evidence、booking
|
|
148
148
|
worker/resolver evidence,以及 read-only migration preflight。它也包含 host-owned mobile app surface contract、signed-in
|
|
149
149
|
camera-state QA、直接 Astro route resolution、correlated feedback batch,以及
|
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ Maggie keeps the existing project foundation and asks for decisions before
|
|
|
89
89
|
shared routes, analytics, or publishing boundaries change. The current
|
|
90
90
|
package ships 39 installable skills and a local-first MaggieDash foundation.
|
|
91
91
|
|
|
92
|
-
This package is `0.8.16` — de-sparses the earlier README-only repos to full source and studies them at code level (confirm + net-new: Remotion delayRender gate, opentoonz BSD port target, green-screen/LUT/karaoke filters, whisper turbo + caption flags, Babylon NullEngine), plus maggie_image.py trim/auto-orient and richer captions flags. `0.8.15` closed the non-Q design coverage gap: `maggie_image.py` gains svg-export/composite/look, a new design-editor-patterns reference, and growth in web-animation/generative-visuals/video-timeline references. `0.8.14` adds `maggie-ai-media` (bg removal / upscaling / arm's-length ComfyUI as a command generator; no model downloads or GPU itself). `0.8.13` adds the AI-media-generation planning reference (category Q: licensing + safe subset + cost guardrails; build gated on go-ahead). `0.8.12` adds `maggie-image` (process images via an ImageMagick recipe CLI) + references for web animation, generative visuals, image recipes, and captions. `0.8.11` - `maggie_video.py compile` now also does video-clip ken-burns, sidechain ducking, and non-opacity overlay effects (move/slide, image zoom), and a new `autocut` subcommand removes silent gaps. `0.8.10` added image ken-burns + text opacity keyframes and the `captions` (whisper) subcommand. `0.8.9` added `compile` (declarative timeline JSON -> one ffmpeg command). `0.8.8` added `maggie-video` (produce and process marketing video: cut, caption, resize to channel aspects, watermark, transcode, normalize loudness, assemble clips, render code-drawn animation) with a tested ffmpeg-recipe CLI, distilled from the reference library's video projects; plus references `ffmpeg-recipes`, `programmatic-video`, `video-timeline-model`. `0.8.7` folded a redesign audit into `maggie-design` (from the MIT `elayadesign/redesign-skill`): scan + diagnose generic AI-design patterns/weak states/sloppy code, then fix in place via the in-place/verify flow, so "audit/polish/upgrade an existing site" routes to maggie-design. `0.8.6` completed the two adopted design skills with full production references and made the design source Figma-optional (live URL, existing code, Figma, or a screenshot). `0.8.5` adopted the two design skills (adapted, MIT, from `elayadesign/ai-design-skills`): `maggie-landing-page` (conversion strategy + a visual-system discipline whose values defer to the project's DESIGN.md) and `maggie-design-motion` (static design → pixel-exact animated HTML replica → MP4 + GIF export). `0.8.4` expanded the library into a full "one person runs a company with AI" C-suite with eight new function lanes: `maggie-sales` (CRM-neutral pipeline), `maggie-finance` (explain-only CFO metrics + a deterministic `maggie_finance.py` calculator), `maggie-support` (customer success), `maggie-product` (roadmap + pre-registered experiments), `maggie-fundraising` (deck, data room, investor updates), `maggie-legal` (ToS/privacy/DPA/SOC2 readiness), `maggie-monetization` (pricing/paywalls/dunning; money actions human-approved), and `maggie-orchestrator` (the CEO layer that decomposes a goal into gated missions across the lanes, with a `maggie_orchestrator.py` planner). `0.8.3` folded cmo.so/www development learnings in (maggie-skill-authoring, maggie-feedback-triage, and mobile/MCP/auth references); `0.8.2` added `maggie-spirit`; `0.8.0` was the security optimization roadmap.
|
|
92
|
+
This package is `0.8.17` — closes the last two full-source coverage gaps: `inkscape/inkscape` (GitHub is a 2-file stub; studied from GitLab, 7053 files) and the L web-animation libraries (now read at source). `maggie_image.py` gains `svg-export --actions` (clean+flatten+export in one Inkscape call) + `svg-query` (element ids + bounding boxes); `web-animation-patterns` gets source corrections (AOS is scroll+throttle not IntersectionObserver; lenis `autoRaf` default false; typed.js GPL-3.0) and new ideas (designer-spring vocabulary, mojs `Burst` entry, anime v4 grid-stagger, pixijs out-of-scope note). `0.8.16` — de-sparses the earlier README-only repos to full source and studies them at code level (confirm + net-new: Remotion delayRender gate, opentoonz BSD port target, green-screen/LUT/karaoke filters, whisper turbo + caption flags, Babylon NullEngine), plus maggie_image.py trim/auto-orient and richer captions flags. `0.8.15` closed the non-Q design coverage gap: `maggie_image.py` gains svg-export/composite/look, a new design-editor-patterns reference, and growth in web-animation/generative-visuals/video-timeline references. `0.8.14` adds `maggie-ai-media` (bg removal / upscaling / arm's-length ComfyUI as a command generator; no model downloads or GPU itself). `0.8.13` adds the AI-media-generation planning reference (category Q: licensing + safe subset + cost guardrails; build gated on go-ahead). `0.8.12` adds `maggie-image` (process images via an ImageMagick recipe CLI) + references for web animation, generative visuals, image recipes, and captions. `0.8.11` - `maggie_video.py compile` now also does video-clip ken-burns, sidechain ducking, and non-opacity overlay effects (move/slide, image zoom), and a new `autocut` subcommand removes silent gaps. `0.8.10` added image ken-burns + text opacity keyframes and the `captions` (whisper) subcommand. `0.8.9` added `compile` (declarative timeline JSON -> one ffmpeg command). `0.8.8` added `maggie-video` (produce and process marketing video: cut, caption, resize to channel aspects, watermark, transcode, normalize loudness, assemble clips, render code-drawn animation) with a tested ffmpeg-recipe CLI, distilled from the reference library's video projects; plus references `ffmpeg-recipes`, `programmatic-video`, `video-timeline-model`. `0.8.7` folded a redesign audit into `maggie-design` (from the MIT `elayadesign/redesign-skill`): scan + diagnose generic AI-design patterns/weak states/sloppy code, then fix in place via the in-place/verify flow, so "audit/polish/upgrade an existing site" routes to maggie-design. `0.8.6` completed the two adopted design skills with full production references and made the design source Figma-optional (live URL, existing code, Figma, or a screenshot). `0.8.5` adopted the two design skills (adapted, MIT, from `elayadesign/ai-design-skills`): `maggie-landing-page` (conversion strategy + a visual-system discipline whose values defer to the project's DESIGN.md) and `maggie-design-motion` (static design → pixel-exact animated HTML replica → MP4 + GIF export). `0.8.4` expanded the library into a full "one person runs a company with AI" C-suite with eight new function lanes: `maggie-sales` (CRM-neutral pipeline), `maggie-finance` (explain-only CFO metrics + a deterministic `maggie_finance.py` calculator), `maggie-support` (customer success), `maggie-product` (roadmap + pre-registered experiments), `maggie-fundraising` (deck, data room, investor updates), `maggie-legal` (ToS/privacy/DPA/SOC2 readiness), `maggie-monetization` (pricing/paywalls/dunning; money actions human-approved), and `maggie-orchestrator` (the CEO layer that decomposes a goal into gated missions across the lanes, with a `maggie_orchestrator.py` planner). `0.8.3` folded cmo.so/www development learnings in (maggie-skill-authoring, maggie-feedback-triage, and mobile/MCP/auth references); `0.8.2` added `maggie-spirit`; `0.8.0` was the security optimization roadmap.
|
|
93
93
|
|
|
94
94
|
The 0.7.59 release made `maggie security host-audit` (the deep
|
|
95
95
|
lynis audit over SSH) robust on hosts where a storage test can stall: lynis runs
|
|
@@ -103,6 +103,36 @@ inkscape in.svg --export-id=badge --export-id-only --export-type=png --export-fi
|
|
|
103
103
|
inkscape in.svg --export-type=png --export-dpi=300 --export-area-page --export-filename=print.png
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
**From the real source (GitLab `inkscape/inkscape`, 1.5-dev — the GitHub mirror is a
|
|
107
|
+
stub; CLI flags above all confirmed current against `man/inkscape.pod.in`).** Three
|
|
108
|
+
net-new capabilities worth adopting, all still arm's-length (no GPL vendored):
|
|
109
|
+
|
|
110
|
+
- **Actions pipeline + batch (`--actions` / `--shell`).** One invocation can run an
|
|
111
|
+
ordered list of verbs, so a cleanup+flatten+export is a single call instead of a
|
|
112
|
+
chain. `maggie_image.py svg-export` can emit this for a "clean then export" job:
|
|
113
|
+
```bash
|
|
114
|
+
inkscape in.svg \
|
|
115
|
+
--actions="select-all;object-to-path;vacuum-defs;export-plain-svg;export-filename:flat.svg;export-do"
|
|
116
|
+
# batch many files through one long-lived process (no per-file startup cost):
|
|
117
|
+
inkscape --shell < actions.txt # one actions line per file, ending in export-do
|
|
118
|
+
```
|
|
119
|
+
Useful actions: `object-to-path` / `all-objects-to-paths` (outline shapes+text),
|
|
120
|
+
`path-simplify`, boolean `path-union` / `path-difference` / `path-intersection`,
|
|
121
|
+
`vacuum-defs` (drop unused defs — shrinks file), and the `export-*` action family.
|
|
122
|
+
`inkscape --action-list` prints every verb.
|
|
123
|
+
- **Geometry query (`--query-all` / `--query-id`).** Discover element ids and their
|
|
124
|
+
bounding boxes *before* `--export-id` slicing, so a generated slice list is correct:
|
|
125
|
+
```bash
|
|
126
|
+
inkscape in.svg --query-all # id,x,y,w,h per object (CSV) — feed --export-id
|
|
127
|
+
inkscape in.svg --query-id=badge --query-x --query-y --query-width --query-height
|
|
128
|
+
```
|
|
129
|
+
`maggie_image.py svg-query` emits this (pairs with the per-id export above).
|
|
130
|
+
- **Extra export flags:** `--export-page=all|N` + `--export-margin` (multi-page PDF/
|
|
131
|
+
SVG slicing), `--export-overwrite`, `--export-png-color-mode=Gray_8|RGBA_16` and
|
|
132
|
+
`--export-png-use-dithering`, `--export-pdf-version=1.5` / `--export-ps-level=3`,
|
|
133
|
+
`--export-latex` (PDF+LaTeX overlay for papers), `--export-plain-svg` (strip
|
|
134
|
+
Inkscape namespaces for clean handoff).
|
|
135
|
+
|
|
106
136
|
## Layered composite + named looks (Pinta vocabulary)
|
|
107
137
|
|
|
108
138
|
Blend modes map from a raster editor's layer stack onto ImageMagick `-compose`:
|
|
@@ -25,7 +25,8 @@ sequenced, scroll-driven work.
|
|
|
25
25
|
gsap.registerPlugin(ScrollTrigger);
|
|
26
26
|
const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.6 } });
|
|
27
27
|
tl.from(".hero h1", { y: 40, opacity: 0 })
|
|
28
|
-
.from(".hero p", { y: 24, opacity: 0 }, "-=0.3")
|
|
28
|
+
.from(".hero p", { y: 24, opacity: 0 }, "-=0.3") // overlap previous by 0.3s
|
|
29
|
+
.from(".hero a", { opacity: 0 }, "<"); // "<"/">" = start/end of prev tween
|
|
29
30
|
gsap.from(".card", {
|
|
30
31
|
scrollTrigger: { trigger: ".card", start: "top 80%", once: true },
|
|
31
32
|
y: 32, opacity: 0, stagger: 0.08,
|
|
@@ -35,6 +36,10 @@ gsap.from(".card", {
|
|
|
35
36
|
GSAP including all former Club plugins is 100% free for commercial use, but it is a
|
|
36
37
|
proprietary license, not open source — flag it before bundling. CDN:
|
|
37
38
|
`cdn.jsdelivr.net/npm/gsap@3.15/dist/gsap.min.js`.
|
|
39
|
+
*Source note:* the `0.6`/`power3.out` above are our **house** defaults, not GSAP's
|
|
40
|
+
(its own tween defaults are `0.5`/`power1.out` = quad); don't attribute them to GSAP.
|
|
41
|
+
Parameterized ease strings — `"elastic.out(1,0.5)"`, `"back.out(1.7)"`,
|
|
42
|
+
`"steps(12)"` — author a bespoke curve as a string.
|
|
38
43
|
**Reach for it when:** a page needs a real timeline (chained, overlapping steps) or
|
|
39
44
|
scroll-scrubbed sequencing beyond a one-shot reveal. Overkill for simple fades.
|
|
40
45
|
|
|
@@ -45,13 +50,17 @@ springs, `scroll()`, `inView()`, layout transitions.
|
|
|
45
50
|
```js
|
|
46
51
|
import { animate, inView, scroll, stagger } from "motion";
|
|
47
52
|
animate("#box", { x: 100, opacity: 1 }, { type: "spring", stiffness: 300, damping: 30 });
|
|
48
|
-
inView(".card", (el) => { animate(el, { opacity: 1, y: 0 }); }, { amount:
|
|
53
|
+
inView(".card", (el) => { animate(el, { opacity: 1, y: 0 }); }, { amount: "some" });
|
|
54
|
+
// inView idiom is amount:"some"|"all" (a number works too) + margin (→ rootMargin)
|
|
49
55
|
// React: <motion.div initial={{opacity:0,y:24}} whileInView={{opacity:1,y:0}} viewport={{once:true}}/>
|
|
50
56
|
```
|
|
51
57
|
**License: MIT** (core; a paid "Motion+" add-on exists but isn't required).
|
|
52
58
|
**Reach for it when:** the project is already React/Vue, or you want springs +
|
|
53
59
|
scroll + inView from one small MIT lib. `inView` is a clean IntersectionObserver
|
|
54
|
-
wrapper — our preferred engine when a dependency is acceptable.
|
|
60
|
+
wrapper — our preferred engine when a dependency is acceptable. `motion/mini` is a
|
|
61
|
+
WAAPI-only subset for the smallest payload. Spring also takes a **designer mode**
|
|
62
|
+
`{ visualDuration, bounce }` (settle-time + bounciness, SwiftUI-style) instead of raw
|
|
63
|
+
`stiffness/damping` — expose that to non-engineers (see the Spring pattern below).
|
|
55
64
|
|
|
56
65
|
### anime.js (juliangarnier/anime) — v4
|
|
57
66
|
Small, elegant timeline/stagger/easing lib. V4 is ESM tree-shakable.
|
|
@@ -61,9 +70,14 @@ animate(".square", {
|
|
|
61
70
|
x: 320, rotate: { from: -180 }, duration: 1250,
|
|
62
71
|
delay: stagger(65, { from: "center" }), ease: "inOutQuint",
|
|
63
72
|
});
|
|
73
|
+
// 2D ripple from a grid cell (v4): delay: stagger(60, { grid: [cols, rows], from: "center" })
|
|
64
74
|
```
|
|
65
|
-
**License: MIT
|
|
66
|
-
|
|
75
|
+
**License: MIT** (v4: ESM, per-feature export subpaths — `animejs`, `animejs/stagger`,
|
|
76
|
+
…; exports `animate, stagger, createTimeline, createTimer, createSpring, onScroll`,
|
|
77
|
+
`eases/utils/svg/text`). **Reach for it when:** you want expressive staggers/keyframes
|
|
78
|
+
lighter than GSAP and don't need ScrollTrigger-grade scroll control. Stagger vocabulary
|
|
79
|
+
is rich: `from:'first'|'center'|'last'|'random'|index`, `grid:[x,y]`, `axis`,
|
|
80
|
+
`reversed`, and an `ease` (even a spring) across the stagger.
|
|
67
81
|
|
|
68
82
|
### lottie-web (airbnb/lottie-web)
|
|
69
83
|
Plays **Lottie JSON** (vector animations exported from After Effects via Bodymovin)
|
|
@@ -75,10 +89,16 @@ const anim = lottie.loadAnimation({
|
|
|
75
89
|
});
|
|
76
90
|
anim.playSegments([0, 60], true); // play part of the timeline
|
|
77
91
|
anim.setSpeed(1); anim.pause();
|
|
92
|
+
lottie.freeze(); // GLOBAL pause of every instance (tab hidden)
|
|
78
93
|
```
|
|
79
94
|
**License: MIT.** **Reach for it when:** a designer delivers an AE/Lottie file and
|
|
80
95
|
you need a crisp, scalable, small looped illustration (see §2 Lottie workflow).
|
|
81
|
-
Default to `renderer: "svg"`; switch to `canvas` for heavy/many-layer files.
|
|
96
|
+
Default to `renderer: "svg"`; switch to `canvas` for heavy/many-layer files. For a
|
|
97
|
+
small payload load the **`lottie_light`** build (SVG-only, no expressions). Perf/sync
|
|
98
|
+
hooks worth using: `progressiveLoad`, `setSubframe(false)`, and the fine-grained events
|
|
99
|
+
`enterFrame`/`loopComplete`/`segmentStart`. `freeze()/unfreeze()` are **global**
|
|
100
|
+
(all instances); per-instance use `pause`/`goToAndStop`. No built-in reduced-motion —
|
|
101
|
+
gate it yourself.
|
|
82
102
|
|
|
83
103
|
### rlottie (Samsung/rlottie)
|
|
84
104
|
Native (C++) Lottie renderer — the runtime behind Lottie on native/embedded (not a
|
|
@@ -117,20 +137,26 @@ Animate-on-scroll via HTML data-attributes + a prebuilt CSS set.
|
|
|
117
137
|
data-aos-once="true" data-aos-anchor-placement="top-center"></div>
|
|
118
138
|
<script>AOS.init({ once: true, duration: 800, easing: "ease-out-cubic" });</script>
|
|
119
139
|
```
|
|
120
|
-
**License: MIT.**
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
vocabulary (`fade-up`, `once`, per-element
|
|
140
|
+
**License: MIT.** **Correction (source-verified, v3.0.0-beta.6):** this release does
|
|
141
|
+
**not** use IntersectionObserver — it is classic **scroll + `lodash.throttle`**
|
|
142
|
+
(`throttleDelay:99`); the only observer is a MutationObserver for auto-refresh on DOM
|
|
143
|
+
injection. So copy its attribute *vocabulary* (`fade-up`, `once`, per-element
|
|
144
|
+
delay/offset/anchor-placement), but do **not** credit it for observer efficiency — our
|
|
145
|
+
hand-rolled reveal (§2) with a real IntersectionObserver is the better engine.
|
|
146
|
+
**Reach for it when:** a no-JS-authoring team wants declarative scroll reveals fast.
|
|
124
147
|
|
|
125
148
|
### typed.js (mattboldt/typed.js)
|
|
126
149
|
Typewriter effect.
|
|
127
150
|
```js
|
|
128
151
|
const typed = new Typed("#el", { strings: ["First.", "& second."], typeSpeed: 50, backSpeed: 30, loop: true });
|
|
129
152
|
```
|
|
130
|
-
**License: GPL — flag it
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
153
|
+
**License: GPL-3.0 — flag it** (source-verified; the repo also ships paid
|
|
154
|
+
`LIMITED`/`UNLIMITED_COMMERCIAL_LICENSE.md` with a Stripe link — a paid escape from
|
|
155
|
+
copyleft). Do **not** bundle into proprietary/client output; reimplement the ~20-line
|
|
156
|
+
effect yourself (or buy the commercial license). It also has **zero** reduced-motion
|
|
157
|
+
handling (grep-confirmed) — you must gate it. **Reach for the pattern when:** a hero
|
|
158
|
+
rotates through phrases. Keep it short, respect reduced-motion (render the final string
|
|
159
|
+
statically).
|
|
134
160
|
|
|
135
161
|
### tsparticles (tsparticles/tsparticles)
|
|
136
162
|
Config-driven particle backgrounds/confetti.
|
|
@@ -143,6 +169,27 @@ await tsParticles.load({ id: "tsparticles", options: {
|
|
|
143
169
|
**License: MIT.** **Reach for it when:** a hero wants a subtle particle/constellation
|
|
144
170
|
backdrop or a celebratory confetti burst. Use sparingly — it's a performance and
|
|
145
171
|
taste liability; cap particle count, pause offscreen, disable on reduced-motion.
|
|
172
|
+
Source notes: v3+ `load()` takes **one object** `{ id, element?, options?, url? }`
|
|
173
|
+
(positional form gone); 22 presets (`confetti`/`fireworks`/`snow`/`stars`/`links`/…)
|
|
174
|
+
are one-line `preset:` strings; ship the **slim** bundle + only the `@tsparticles/*`
|
|
175
|
+
feature packages you use. It also ships CLI scaffolders (`npm create tsparticles@latest`,
|
|
176
|
+
`create-confetti`) and an **MCP server** — precedent for an agent-driven particle config.
|
|
177
|
+
(Legacy origin: `particles.js` v2 — single-file, unmaintained, snake_case schema; use
|
|
178
|
+
tsparticles instead, which bundles a `pjs` compat shim.)
|
|
179
|
+
|
|
180
|
+
### mojs (@mojs/core)
|
|
181
|
+
Motion-graphics toolbelt for the web — the one lib here built for **celebratory point
|
|
182
|
+
bursts / success micro-interactions** (likes, add-to-cart, CTA confirm), a genuine gap
|
|
183
|
+
the others don't fill. Actively maintained.
|
|
184
|
+
```js
|
|
185
|
+
import { Burst, Shape } from "@mojs/core";
|
|
186
|
+
new Burst({ left: x, top: y, count: 8, radius: { 0: 60 },
|
|
187
|
+
children: { shape: "circle", fill: "#e94560", duration: 700 } }).play();
|
|
188
|
+
```
|
|
189
|
+
**License: MIT.** Also `ShapeSwirl`, `Html` (tween real DOM), `Timeline`, `stagger`,
|
|
190
|
+
custom eases via `easing.path("M0,100 ...")` / `easing.bezier()`. **Reach for it when:**
|
|
191
|
+
a discrete interaction deserves a tactile burst — keep it to a single gesture, gate on
|
|
192
|
+
reduced-motion.
|
|
146
193
|
|
|
147
194
|
### rive (rive-app/rive-runtime)
|
|
148
195
|
Interactive vector animations driven by **state machines** (inputs → states), not
|
|
@@ -161,23 +208,32 @@ drives animation state) — interactive mascots, animated toggles. Heavier workf
|
|
|
161
208
|
Animates SVG stroke draw-on ("self-drawing" line art).
|
|
162
209
|
```js
|
|
163
210
|
new Vivus("my-svg", { type: "oneByOne", duration: 200, start: "inViewport" }, cb);
|
|
164
|
-
// type: delayed
|
|
211
|
+
// type: delayed|sync|async|nsync|oneByOne|scenario|scenario-sync ; start: inViewport|manual|autostart
|
|
212
|
+
v.setFrameProgress(0.5); // scrub draw 0..1 (drive from scroll); play(-1) rewinds
|
|
165
213
|
```
|
|
166
|
-
**License: MIT.**
|
|
167
|
-
|
|
214
|
+
**License: MIT.** Timing fns are statics (`Vivus.EASE_OUT`, custom `function(x)`), set
|
|
215
|
+
whole (`animTimingFunction`) or per-path (`pathTimingFunction`); per-path
|
|
216
|
+
`data-delay/duration`, `data-vivus-ignore`; bundles `pathformer` (primitives → path).
|
|
217
|
+
**Reach for it when:** a logo/icon/diagram should draw itself in — and, via
|
|
218
|
+
`setFrameProgress(0..1)`, a **scroll-linked** draw-on (extends §2's one-shot draw). The
|
|
219
|
+
same effect is achievable with CSS `stroke-dasharray`/`stroke-dashoffset` — use
|
|
168
220
|
that for one element, Vivus when orchestrating many paths.
|
|
169
221
|
|
|
170
222
|
### lenis (darkroomengineering/lenis)
|
|
171
223
|
Smooth-scroll normalizer (momentum/eased scrolling). Already referenced by
|
|
172
224
|
`maggie-clone`.
|
|
173
225
|
```js
|
|
174
|
-
const lenis = new Lenis({ autoRaf: true }); //
|
|
175
|
-
lenis.on("scroll", (e) => {/*
|
|
226
|
+
const lenis = new Lenis({ autoRaf: true }); // DEFAULT is autoRaf:false → drive lenis.raf(t) yourself
|
|
227
|
+
lenis.on("scroll", (e) => {/* e is the whole Lenis instance: e.scroll/.velocity/.progress/.direction */});
|
|
176
228
|
```
|
|
177
229
|
**License: MIT.** **Reach for it when:** the design calls for premium eased scrolling
|
|
178
230
|
and you pair it with scroll-triggered motion (commonly `lenis.raf` + GSAP
|
|
179
|
-
ScrollTrigger).
|
|
180
|
-
|
|
231
|
+
ScrollTrigger). **Source-verified defaults:** `lerp` is `0.1` (not 0.075 — that's
|
|
232
|
+
`syncTouchLerp`), `autoRaf` defaults **false**, and `respectReducedMotion` is a
|
|
233
|
+
first-class option (defaults true, falls back to native scroll via matchMedia).
|
|
234
|
+
Attribute opt-outs: `data-lenis-prevent[-vertical|-horizontal]`. Accessibility caveat:
|
|
235
|
+
keep `respectReducedMotion` on; never trap scroll in a way that breaks keyboard/anchor
|
|
236
|
+
jumps.
|
|
181
237
|
|
|
182
238
|
### barba.js (barbajs/barba)
|
|
183
239
|
SPA-style page transitions over MPAs: intercepts navigation, animates the old
|
|
@@ -203,6 +259,11 @@ return <animated.div style={styles}>…</animated.div>;
|
|
|
203
259
|
```
|
|
204
260
|
**License: MIT.** **Reach for it when:** a React project wants physics-based
|
|
205
261
|
(not duration-based) motion. For non-React, Motion's `spring` covers the same need.
|
|
262
|
+
**Source-verified presets** (`tension`/`friction`[/`mass`]): default `{170,26}`,
|
|
263
|
+
`gentle {120,14}`, `wobbly {180,12}`, `stiff {210,20}`, `slow {280,60}`,
|
|
264
|
+
`molasses {280,120}`. The `AnimationConfig` also exposes a **designer-friendly**
|
|
265
|
+
vocabulary — `frequency` + `damping(ratio)` (tension/friction derived from them),
|
|
266
|
+
plus `clamp`, `bounce`, `decay` — prefer these when writing a config for non-engineers.
|
|
206
267
|
|
|
207
268
|
### animate.css (animate-css/animate.css)
|
|
208
269
|
Prebuilt CSS keyframe classes (`animate__animated animate__fadeInUp`).
|
|
@@ -211,9 +272,20 @@ Prebuilt CSS keyframe classes (`animate__animated animate__fadeInUp`).
|
|
|
211
272
|
```
|
|
212
273
|
**License: Hippocratic License 2.1 — flag it (NOT MIT).** An ethical-source license
|
|
213
274
|
with use restrictions; not OSI-approved. Treat as a caution for commercial bundling;
|
|
214
|
-
the keyframe recipes (`fadeInUp`, durations, timing)
|
|
215
|
-
|
|
216
|
-
|
|
275
|
+
the keyframe recipes (`fadeInUp`, the `back_*` entrance/exit family, durations, timing)
|
|
276
|
+
are fine to **reimplement** yourself. Two patterns worth copying wholesale: its
|
|
277
|
+
**3-custom-prop timing system** (`--animate-duration` / `--animate-delay` /
|
|
278
|
+
`--animate-repeat` + `calc()` utility multipliers) and its built-in **reduced-motion /
|
|
279
|
+
print kill-switch** (collapses to 1ms and forces `*Out` animations to opacity 0 so
|
|
280
|
+
content never sticks hidden). **Reach for the patterns when:** you want a quick
|
|
281
|
+
named-entrance vocabulary — but author your own keyframes to stay license-clean.
|
|
282
|
+
|
|
283
|
+
### Out of scope — pixijs (pixijs/pixijs)
|
|
284
|
+
A WebGL/WebGPU **2D renderer**, not an animation engine: it ships no tween/easing (its
|
|
285
|
+
`Ticker` gives only `deltaTime`). The particle/shader libs build *on* it; for standard
|
|
286
|
+
DOM/CSS marketing motion it's out of scope — reach for it only for a heavy custom
|
|
287
|
+
canvas scene, and bring your own tween (GSAP/Motion). (Notable: it ships 26 first-party
|
|
288
|
+
`SKILL.md` agent skills — precedent for a library shipping its own skills.)
|
|
217
289
|
|
|
218
290
|
### Category O (offline / desktop, NOT web)
|
|
219
291
|
- **synfig** (synfig/synfig) — desktop 2D vector animation studio. **GPL-3.0.**
|
|
@@ -236,14 +308,28 @@ Default to expressive ease-out curves, never browser defaults (`ease`, `linear`,
|
|
|
236
308
|
color/opacity 300ms (never < 200ms). Other good ones: `cubic-bezier(0.16,1,0.3,1)`
|
|
237
309
|
(ease-out-expo), `cubic-bezier(0.34,1.56,0.64,1)` (gentle back/overshoot).
|
|
238
310
|
Libs: GSAP eases, anime `inOut*`, Motion. **LP + DM.**
|
|
311
|
+
*Custom eases as data:* when a bespoke curve is needed, author it as data rather than
|
|
312
|
+
code — GSAP parameterized strings (`"back.out(1.7)"`), mojs `easing.path()`/`bezier()`,
|
|
313
|
+
vivus custom `function(x)`, or a popmotion-style `mirror/reverse` of a base ease. Store
|
|
314
|
+
the curve with the motion spec (see Theatre.js data model below).
|
|
239
315
|
|
|
240
316
|
### Spring physics
|
|
241
317
|
Duration-less, physics-based motion — natural for interactive/hover and anything
|
|
242
318
|
that should feel tactile. Config shape is universal: `{ stiffness, damping, mass }`
|
|
243
319
|
(Motion: `type:"spring", stiffness:300, damping:30`; react-spring: `config.gentle`).
|
|
320
|
+
For configs a non-engineer will touch, prefer the **designer vocabulary** both engines
|
|
321
|
+
expose — Motion `{ visualDuration, bounce }`, react-spring `frequency` +
|
|
322
|
+
`damping(ratio)` (settle-time + bounciness), rather than raw stiffness/damping.
|
|
244
323
|
Libs: Motion `spring`, react-spring, GSAP (via plugins). **DM;** light touch on LP
|
|
245
324
|
(mostly micro-interactions).
|
|
246
325
|
|
|
326
|
+
### Burst / success micro-interaction
|
|
327
|
+
A discrete gesture (like, add-to-cart, CTA confirm) earns a one-shot radial burst from
|
|
328
|
+
the click point — one shape stamped into N transformed copies with an opacity ramp.
|
|
329
|
+
Lib: mojs `Burst` (or a hand-rolled radial-stamp, same idea as the Lottie Repeater in
|
|
330
|
+
[generative visuals](generative-visuals.md)). One gesture only; gate on reduced-motion.
|
|
331
|
+
**LP (primary CTA) + DM.**
|
|
332
|
+
|
|
247
333
|
### Scroll-reveal via IntersectionObserver — never scroll listeners
|
|
248
334
|
Elements rise ~32px and fade over 600–800ms, **once**, when they cross into view.
|
|
249
335
|
Always IntersectionObserver (or a lib that wraps it); never an unthrottled `scroll`
|
|
@@ -349,7 +435,10 @@ illustration when a designer supplies the JSON.
|
|
|
349
435
|
| auto-animate | MIT | |
|
|
350
436
|
| AOS | MIT | |
|
|
351
437
|
| typed.js | **GPL** | **Flag — don't bundle in proprietary output; reimplement.** |
|
|
352
|
-
| tsparticles | MIT | |
|
|
438
|
+
| tsparticles | MIT | v3+ single-object `load()`; ships CLI scaffolders + an MCP server. |
|
|
439
|
+
| particles.js | MIT | Legacy v2, unmaintained — use tsparticles (`pjs` compat). |
|
|
440
|
+
| mojs (@mojs/core) | MIT | Celebratory point bursts / success micro-interactions. |
|
|
441
|
+
| pixijs | MIT | WebGL 2D **renderer**, no tween — out of scope for DOM motion. |
|
|
353
442
|
| rive-runtime | MIT | Web runtime is `@rive-app/canvas`. |
|
|
354
443
|
| vivus | MIT | |
|
|
355
444
|
| lenis | MIT | |
|
|
@@ -371,9 +460,10 @@ state**, replayed by a tiny headless runtime (`@theatre/core`) against three.js,
|
|
|
371
460
|
HTML/SVG, or any JS variable. The borrowable pattern is the **declarative keyframe
|
|
372
461
|
document**, not the editor: store motion as JSON - a `sequence` with `length` +
|
|
373
462
|
`subUnitsPerUnit` (an fps snap-grid) -> **tracks keyed by property path** ->
|
|
374
|
-
**keyframes** each carrying `{ position, value, handles:[lx,ly,rx,ry],
|
|
375
|
-
type
|
|
376
|
-
data; `
|
|
463
|
+
**keyframes** each carrying `{ id, position, value, handles:[lx,ly,rx,ry],
|
|
464
|
+
connectedRight:boolean, type?:'bezier'|'hold' }` (per-keyframe bezier handles =
|
|
465
|
+
per-segment easing baked into data; `type` is optional, defaults bezier; `value` may be
|
|
466
|
+
non-numeric). Playback mirrors CSS: `play({ iterationCount,
|
|
377
467
|
range, rate, direction:'alternateReverse' })`. Author a brand motion once, commit the
|
|
378
468
|
JSON as a reusable asset, replay it deterministically with no editor shipped - the
|
|
379
469
|
authoring story for `maggie-design-motion` (keep the motion *spec* as data, not
|
|
@@ -395,4 +485,9 @@ hero as `inputs -> conditions -> states` - declare inputs (`hovered:bool`,
|
|
|
395
485
|
`scroll:0..1`, `clicked:trigger`), bind DOM events to them, and switch CSS/WAAPI/GSAP
|
|
396
486
|
timelines by state rather than scripting each handler; a number input + interpolation
|
|
397
487
|
gives scroll-linked response, random-picked idle transitions give a "living" element.
|
|
398
|
-
(Rive's own MIT player is also a legitimate option.)
|
|
488
|
+
(Rive's own MIT player is also a legitimate option.) Source-verified, the model is
|
|
489
|
+
richer than the sketch above: any input source maps onto one **unified listener bus**
|
|
490
|
+
(pointer/scroll/keyboard/gamepad/text/focus), transitions can be guarded by **app data**
|
|
491
|
+
via **ViewModel data-binding conditions** (not just events), comparator ops are a full
|
|
492
|
+
enum (`eq/neq/lt/gt/lte/gte`), and nested state machines compose — so "driven by data,
|
|
493
|
+
not handlers" is the portable lesson for a browser reimplementation.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: maggie-image
|
|
3
3
|
description: Process marketing images - resize and fit to channel/OG sizes, convert to WebP/AVIF, make favicon and OG-image sets, strip metadata, compress, optimize and render SVG, and build contact-sheet montages. A recipe generator over ImageMagick (primary) with dedicated tools (svgo/resvg/cwebp/avifenc/pngquant) used when installed. Use when the user wants to resize, convert, optimize, favicon, watermark, or batch-process images for a site or social post.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 0.1.
|
|
5
|
+
version: 0.1.4
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Maggie Image
|
|
@@ -53,12 +53,16 @@ maggie tool maggie_image.py --run strip --input photo.jpg --output photo.jpg
|
|
|
53
53
|
maggie tool maggie_image.py --run compress --input big.jpg --output small.jpg --quality 82
|
|
54
54
|
maggie tool maggie_image.py svgo --input logo.svg --output logo.min.svg --multipass
|
|
55
55
|
maggie tool maggie_image.py svg2png --input logo.svg --output logo.png --width 512
|
|
56
|
+
maggie tool maggie_image.py svg-query --input logo.svg # ids+bounds before --id slicing
|
|
57
|
+
maggie tool maggie_image.py svg-export --input in.svg --output flat.svg --type svg \
|
|
58
|
+
--actions "select-all;object-to-path;vacuum-defs" # clean+flatten in one call
|
|
56
59
|
maggie tool maggie_image.py --run montage --inputs a.png b.png c.png --output sheet.jpg --tile 3x
|
|
57
60
|
maggie tool maggie_image.py presets
|
|
58
61
|
```
|
|
59
62
|
|
|
60
63
|
Subcommands: `resize`, `social`, `webp`, `avif`, `favicon`, `strip`, `compress`,
|
|
61
|
-
`svgo`, `svg2png`, `svg-export` (Inkscape: PDF/EPS, text-to-path, per-id slicing
|
|
64
|
+
`svgo`, `svg2png`, `svg-export` (Inkscape: PDF/EPS, text-to-path, per-id slicing, or
|
|
65
|
+
`--actions` verb pipeline), `svg-query` (element ids + bounding boxes),
|
|
62
66
|
`composite` (blend-mode layering), `look` (named style presets: sepia/duotone/
|
|
63
67
|
posterize/vignette/...), `montage`, `presets`. `--run` (before the subcommand)
|
|
64
68
|
executes when the tool is present; otherwise the command is printed for review.
|
|
@@ -10,7 +10,7 @@ and are generate-only until it is installed. Web-delivery quality defaults follo
|
|
|
10
10
|
sharp/squoosh (JPEG/WebP ~80, AVIF ~50); OG/social are cover-cropped, logos pad.
|
|
11
11
|
|
|
12
12
|
Subcommands: resize, social, webp, avif, favicon, strip, compress, svgo, svg2png,
|
|
13
|
-
svg-export, composite, look, montage, presets.
|
|
13
|
+
svg-export, svg-query, composite, look, montage, presets.
|
|
14
14
|
"""
|
|
15
15
|
import argparse
|
|
16
16
|
import shlex
|
|
@@ -163,6 +163,14 @@ def c_svg_export(a):
|
|
|
163
163
|
"""Inkscape headless export - fills the gaps resvg/ImageMagick can't: text-to-path
|
|
164
164
|
font outlining, PDF/EPS for print, and per-id slicing. GPL app, invoked at arm's
|
|
165
165
|
length (like ImageMagick)."""
|
|
166
|
+
# Actions pipeline: run an ordered verb list in one invocation (clean+flatten+export
|
|
167
|
+
# as a single call). `inkscape --action-list` prints every verb. Arm's-length (GPL).
|
|
168
|
+
if a.actions:
|
|
169
|
+
verbs = a.actions
|
|
170
|
+
if "export-filename" not in verbs and "export-do" not in verbs:
|
|
171
|
+
verbs = f"{verbs};export-filename:{a.output};export-type:{a.type};export-do"
|
|
172
|
+
print("# Inkscape actions pipeline: run an ordered verb list in one process.")
|
|
173
|
+
return emit(["inkscape", a.input, f"--actions={verbs}"], a.run, "inkscape")
|
|
166
174
|
args = ["inkscape", a.input, f"--export-type={a.type}", f"--export-filename={a.output}"]
|
|
167
175
|
if a.width:
|
|
168
176
|
args.append(f"--export-width={a.width}")
|
|
@@ -182,6 +190,18 @@ def c_svg_export(a):
|
|
|
182
190
|
return emit(args, a.run, "inkscape")
|
|
183
191
|
|
|
184
192
|
|
|
193
|
+
def c_svg_query(a):
|
|
194
|
+
"""Query an SVG's element ids and bounding boxes (Inkscape, arm's-length). Use the
|
|
195
|
+
output to build a correct --export-id slice list before slicing."""
|
|
196
|
+
if a.id:
|
|
197
|
+
args = ["inkscape", a.input, f"--query-id={a.id}",
|
|
198
|
+
"--query-x", "--query-y", "--query-width", "--query-height"]
|
|
199
|
+
else:
|
|
200
|
+
args = ["inkscape", a.input, "--query-all"] # id,x,y,w,h per object (CSV)
|
|
201
|
+
print("# Inkscape geometry query: discover ids/bounds before --export-id slicing.")
|
|
202
|
+
return emit(args, a.run, "inkscape")
|
|
203
|
+
|
|
204
|
+
|
|
185
205
|
def c_composite(a):
|
|
186
206
|
"""Layer an overlay onto a base with a blend mode (Pinta/Natron vocabulary ->
|
|
187
207
|
ImageMagick -compose). Modes: Over, Multiply, Screen, Overlay, Darken, Lighten,
|
|
@@ -285,8 +305,15 @@ def main(argv=None):
|
|
|
285
305
|
se.add_argument("--area", choices=["drawing", "page"], default="drawing")
|
|
286
306
|
se.add_argument("--id", help="export only this element/layer id")
|
|
287
307
|
se.add_argument("--text-to-path", dest="text_to_path", action="store_true", help="outline fonts")
|
|
308
|
+
se.add_argument("--actions", help="run an ordered verb pipeline instead (e.g. "
|
|
309
|
+
"'select-all;object-to-path;vacuum-defs'); auto-appends export verbs")
|
|
288
310
|
se.add_argument("--background"); se.set_defaults(fn=c_svg_export)
|
|
289
311
|
|
|
312
|
+
sq = sub.add_parser("svg-query", help="query SVG element ids + bounding boxes (Inkscape)")
|
|
313
|
+
sq.add_argument("--input", required=True)
|
|
314
|
+
sq.add_argument("--id", help="query one id's x/y/w/h (default: --query-all for every object)")
|
|
315
|
+
sq.set_defaults(fn=c_svg_query)
|
|
316
|
+
|
|
290
317
|
cp = sub.add_parser("composite", help="layer an overlay on a base with a blend mode")
|
|
291
318
|
cp.add_argument("--base", required=True); cp.add_argument("--overlay", required=True)
|
|
292
319
|
cp.add_argument("--output", required=True); cp.add_argument("--mode", default="Over")
|
package/package.json
CHANGED
|
@@ -103,6 +103,36 @@ inkscape in.svg --export-id=badge --export-id-only --export-type=png --export-fi
|
|
|
103
103
|
inkscape in.svg --export-type=png --export-dpi=300 --export-area-page --export-filename=print.png
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
**From the real source (GitLab `inkscape/inkscape`, 1.5-dev — the GitHub mirror is a
|
|
107
|
+
stub; CLI flags above all confirmed current against `man/inkscape.pod.in`).** Three
|
|
108
|
+
net-new capabilities worth adopting, all still arm's-length (no GPL vendored):
|
|
109
|
+
|
|
110
|
+
- **Actions pipeline + batch (`--actions` / `--shell`).** One invocation can run an
|
|
111
|
+
ordered list of verbs, so a cleanup+flatten+export is a single call instead of a
|
|
112
|
+
chain. `maggie_image.py svg-export` can emit this for a "clean then export" job:
|
|
113
|
+
```bash
|
|
114
|
+
inkscape in.svg \
|
|
115
|
+
--actions="select-all;object-to-path;vacuum-defs;export-plain-svg;export-filename:flat.svg;export-do"
|
|
116
|
+
# batch many files through one long-lived process (no per-file startup cost):
|
|
117
|
+
inkscape --shell < actions.txt # one actions line per file, ending in export-do
|
|
118
|
+
```
|
|
119
|
+
Useful actions: `object-to-path` / `all-objects-to-paths` (outline shapes+text),
|
|
120
|
+
`path-simplify`, boolean `path-union` / `path-difference` / `path-intersection`,
|
|
121
|
+
`vacuum-defs` (drop unused defs — shrinks file), and the `export-*` action family.
|
|
122
|
+
`inkscape --action-list` prints every verb.
|
|
123
|
+
- **Geometry query (`--query-all` / `--query-id`).** Discover element ids and their
|
|
124
|
+
bounding boxes *before* `--export-id` slicing, so a generated slice list is correct:
|
|
125
|
+
```bash
|
|
126
|
+
inkscape in.svg --query-all # id,x,y,w,h per object (CSV) — feed --export-id
|
|
127
|
+
inkscape in.svg --query-id=badge --query-x --query-y --query-width --query-height
|
|
128
|
+
```
|
|
129
|
+
`maggie_image.py svg-query` emits this (pairs with the per-id export above).
|
|
130
|
+
- **Extra export flags:** `--export-page=all|N` + `--export-margin` (multi-page PDF/
|
|
131
|
+
SVG slicing), `--export-overwrite`, `--export-png-color-mode=Gray_8|RGBA_16` and
|
|
132
|
+
`--export-png-use-dithering`, `--export-pdf-version=1.5` / `--export-ps-level=3`,
|
|
133
|
+
`--export-latex` (PDF+LaTeX overlay for papers), `--export-plain-svg` (strip
|
|
134
|
+
Inkscape namespaces for clean handoff).
|
|
135
|
+
|
|
106
136
|
## Layered composite + named looks (Pinta vocabulary)
|
|
107
137
|
|
|
108
138
|
Blend modes map from a raster editor's layer stack onto ImageMagick `-compose`:
|
|
@@ -25,7 +25,8 @@ sequenced, scroll-driven work.
|
|
|
25
25
|
gsap.registerPlugin(ScrollTrigger);
|
|
26
26
|
const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.6 } });
|
|
27
27
|
tl.from(".hero h1", { y: 40, opacity: 0 })
|
|
28
|
-
.from(".hero p", { y: 24, opacity: 0 }, "-=0.3")
|
|
28
|
+
.from(".hero p", { y: 24, opacity: 0 }, "-=0.3") // overlap previous by 0.3s
|
|
29
|
+
.from(".hero a", { opacity: 0 }, "<"); // "<"/">" = start/end of prev tween
|
|
29
30
|
gsap.from(".card", {
|
|
30
31
|
scrollTrigger: { trigger: ".card", start: "top 80%", once: true },
|
|
31
32
|
y: 32, opacity: 0, stagger: 0.08,
|
|
@@ -35,6 +36,10 @@ gsap.from(".card", {
|
|
|
35
36
|
GSAP including all former Club plugins is 100% free for commercial use, but it is a
|
|
36
37
|
proprietary license, not open source — flag it before bundling. CDN:
|
|
37
38
|
`cdn.jsdelivr.net/npm/gsap@3.15/dist/gsap.min.js`.
|
|
39
|
+
*Source note:* the `0.6`/`power3.out` above are our **house** defaults, not GSAP's
|
|
40
|
+
(its own tween defaults are `0.5`/`power1.out` = quad); don't attribute them to GSAP.
|
|
41
|
+
Parameterized ease strings — `"elastic.out(1,0.5)"`, `"back.out(1.7)"`,
|
|
42
|
+
`"steps(12)"` — author a bespoke curve as a string.
|
|
38
43
|
**Reach for it when:** a page needs a real timeline (chained, overlapping steps) or
|
|
39
44
|
scroll-scrubbed sequencing beyond a one-shot reveal. Overkill for simple fades.
|
|
40
45
|
|
|
@@ -45,13 +50,17 @@ springs, `scroll()`, `inView()`, layout transitions.
|
|
|
45
50
|
```js
|
|
46
51
|
import { animate, inView, scroll, stagger } from "motion";
|
|
47
52
|
animate("#box", { x: 100, opacity: 1 }, { type: "spring", stiffness: 300, damping: 30 });
|
|
48
|
-
inView(".card", (el) => { animate(el, { opacity: 1, y: 0 }); }, { amount:
|
|
53
|
+
inView(".card", (el) => { animate(el, { opacity: 1, y: 0 }); }, { amount: "some" });
|
|
54
|
+
// inView idiom is amount:"some"|"all" (a number works too) + margin (→ rootMargin)
|
|
49
55
|
// React: <motion.div initial={{opacity:0,y:24}} whileInView={{opacity:1,y:0}} viewport={{once:true}}/>
|
|
50
56
|
```
|
|
51
57
|
**License: MIT** (core; a paid "Motion+" add-on exists but isn't required).
|
|
52
58
|
**Reach for it when:** the project is already React/Vue, or you want springs +
|
|
53
59
|
scroll + inView from one small MIT lib. `inView` is a clean IntersectionObserver
|
|
54
|
-
wrapper — our preferred engine when a dependency is acceptable.
|
|
60
|
+
wrapper — our preferred engine when a dependency is acceptable. `motion/mini` is a
|
|
61
|
+
WAAPI-only subset for the smallest payload. Spring also takes a **designer mode**
|
|
62
|
+
`{ visualDuration, bounce }` (settle-time + bounciness, SwiftUI-style) instead of raw
|
|
63
|
+
`stiffness/damping` — expose that to non-engineers (see the Spring pattern below).
|
|
55
64
|
|
|
56
65
|
### anime.js (juliangarnier/anime) — v4
|
|
57
66
|
Small, elegant timeline/stagger/easing lib. V4 is ESM tree-shakable.
|
|
@@ -61,9 +70,14 @@ animate(".square", {
|
|
|
61
70
|
x: 320, rotate: { from: -180 }, duration: 1250,
|
|
62
71
|
delay: stagger(65, { from: "center" }), ease: "inOutQuint",
|
|
63
72
|
});
|
|
73
|
+
// 2D ripple from a grid cell (v4): delay: stagger(60, { grid: [cols, rows], from: "center" })
|
|
64
74
|
```
|
|
65
|
-
**License: MIT
|
|
66
|
-
|
|
75
|
+
**License: MIT** (v4: ESM, per-feature export subpaths — `animejs`, `animejs/stagger`,
|
|
76
|
+
…; exports `animate, stagger, createTimeline, createTimer, createSpring, onScroll`,
|
|
77
|
+
`eases/utils/svg/text`). **Reach for it when:** you want expressive staggers/keyframes
|
|
78
|
+
lighter than GSAP and don't need ScrollTrigger-grade scroll control. Stagger vocabulary
|
|
79
|
+
is rich: `from:'first'|'center'|'last'|'random'|index`, `grid:[x,y]`, `axis`,
|
|
80
|
+
`reversed`, and an `ease` (even a spring) across the stagger.
|
|
67
81
|
|
|
68
82
|
### lottie-web (airbnb/lottie-web)
|
|
69
83
|
Plays **Lottie JSON** (vector animations exported from After Effects via Bodymovin)
|
|
@@ -75,10 +89,16 @@ const anim = lottie.loadAnimation({
|
|
|
75
89
|
});
|
|
76
90
|
anim.playSegments([0, 60], true); // play part of the timeline
|
|
77
91
|
anim.setSpeed(1); anim.pause();
|
|
92
|
+
lottie.freeze(); // GLOBAL pause of every instance (tab hidden)
|
|
78
93
|
```
|
|
79
94
|
**License: MIT.** **Reach for it when:** a designer delivers an AE/Lottie file and
|
|
80
95
|
you need a crisp, scalable, small looped illustration (see §2 Lottie workflow).
|
|
81
|
-
Default to `renderer: "svg"`; switch to `canvas` for heavy/many-layer files.
|
|
96
|
+
Default to `renderer: "svg"`; switch to `canvas` for heavy/many-layer files. For a
|
|
97
|
+
small payload load the **`lottie_light`** build (SVG-only, no expressions). Perf/sync
|
|
98
|
+
hooks worth using: `progressiveLoad`, `setSubframe(false)`, and the fine-grained events
|
|
99
|
+
`enterFrame`/`loopComplete`/`segmentStart`. `freeze()/unfreeze()` are **global**
|
|
100
|
+
(all instances); per-instance use `pause`/`goToAndStop`. No built-in reduced-motion —
|
|
101
|
+
gate it yourself.
|
|
82
102
|
|
|
83
103
|
### rlottie (Samsung/rlottie)
|
|
84
104
|
Native (C++) Lottie renderer — the runtime behind Lottie on native/embedded (not a
|
|
@@ -117,20 +137,26 @@ Animate-on-scroll via HTML data-attributes + a prebuilt CSS set.
|
|
|
117
137
|
data-aos-once="true" data-aos-anchor-placement="top-center"></div>
|
|
118
138
|
<script>AOS.init({ once: true, duration: 800, easing: "ease-out-cubic" });</script>
|
|
119
139
|
```
|
|
120
|
-
**License: MIT.**
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
vocabulary (`fade-up`, `once`, per-element
|
|
140
|
+
**License: MIT.** **Correction (source-verified, v3.0.0-beta.6):** this release does
|
|
141
|
+
**not** use IntersectionObserver — it is classic **scroll + `lodash.throttle`**
|
|
142
|
+
(`throttleDelay:99`); the only observer is a MutationObserver for auto-refresh on DOM
|
|
143
|
+
injection. So copy its attribute *vocabulary* (`fade-up`, `once`, per-element
|
|
144
|
+
delay/offset/anchor-placement), but do **not** credit it for observer efficiency — our
|
|
145
|
+
hand-rolled reveal (§2) with a real IntersectionObserver is the better engine.
|
|
146
|
+
**Reach for it when:** a no-JS-authoring team wants declarative scroll reveals fast.
|
|
124
147
|
|
|
125
148
|
### typed.js (mattboldt/typed.js)
|
|
126
149
|
Typewriter effect.
|
|
127
150
|
```js
|
|
128
151
|
const typed = new Typed("#el", { strings: ["First.", "& second."], typeSpeed: 50, backSpeed: 30, loop: true });
|
|
129
152
|
```
|
|
130
|
-
**License: GPL — flag it
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
153
|
+
**License: GPL-3.0 — flag it** (source-verified; the repo also ships paid
|
|
154
|
+
`LIMITED`/`UNLIMITED_COMMERCIAL_LICENSE.md` with a Stripe link — a paid escape from
|
|
155
|
+
copyleft). Do **not** bundle into proprietary/client output; reimplement the ~20-line
|
|
156
|
+
effect yourself (or buy the commercial license). It also has **zero** reduced-motion
|
|
157
|
+
handling (grep-confirmed) — you must gate it. **Reach for the pattern when:** a hero
|
|
158
|
+
rotates through phrases. Keep it short, respect reduced-motion (render the final string
|
|
159
|
+
statically).
|
|
134
160
|
|
|
135
161
|
### tsparticles (tsparticles/tsparticles)
|
|
136
162
|
Config-driven particle backgrounds/confetti.
|
|
@@ -143,6 +169,27 @@ await tsParticles.load({ id: "tsparticles", options: {
|
|
|
143
169
|
**License: MIT.** **Reach for it when:** a hero wants a subtle particle/constellation
|
|
144
170
|
backdrop or a celebratory confetti burst. Use sparingly — it's a performance and
|
|
145
171
|
taste liability; cap particle count, pause offscreen, disable on reduced-motion.
|
|
172
|
+
Source notes: v3+ `load()` takes **one object** `{ id, element?, options?, url? }`
|
|
173
|
+
(positional form gone); 22 presets (`confetti`/`fireworks`/`snow`/`stars`/`links`/…)
|
|
174
|
+
are one-line `preset:` strings; ship the **slim** bundle + only the `@tsparticles/*`
|
|
175
|
+
feature packages you use. It also ships CLI scaffolders (`npm create tsparticles@latest`,
|
|
176
|
+
`create-confetti`) and an **MCP server** — precedent for an agent-driven particle config.
|
|
177
|
+
(Legacy origin: `particles.js` v2 — single-file, unmaintained, snake_case schema; use
|
|
178
|
+
tsparticles instead, which bundles a `pjs` compat shim.)
|
|
179
|
+
|
|
180
|
+
### mojs (@mojs/core)
|
|
181
|
+
Motion-graphics toolbelt for the web — the one lib here built for **celebratory point
|
|
182
|
+
bursts / success micro-interactions** (likes, add-to-cart, CTA confirm), a genuine gap
|
|
183
|
+
the others don't fill. Actively maintained.
|
|
184
|
+
```js
|
|
185
|
+
import { Burst, Shape } from "@mojs/core";
|
|
186
|
+
new Burst({ left: x, top: y, count: 8, radius: { 0: 60 },
|
|
187
|
+
children: { shape: "circle", fill: "#e94560", duration: 700 } }).play();
|
|
188
|
+
```
|
|
189
|
+
**License: MIT.** Also `ShapeSwirl`, `Html` (tween real DOM), `Timeline`, `stagger`,
|
|
190
|
+
custom eases via `easing.path("M0,100 ...")` / `easing.bezier()`. **Reach for it when:**
|
|
191
|
+
a discrete interaction deserves a tactile burst — keep it to a single gesture, gate on
|
|
192
|
+
reduced-motion.
|
|
146
193
|
|
|
147
194
|
### rive (rive-app/rive-runtime)
|
|
148
195
|
Interactive vector animations driven by **state machines** (inputs → states), not
|
|
@@ -161,23 +208,32 @@ drives animation state) — interactive mascots, animated toggles. Heavier workf
|
|
|
161
208
|
Animates SVG stroke draw-on ("self-drawing" line art).
|
|
162
209
|
```js
|
|
163
210
|
new Vivus("my-svg", { type: "oneByOne", duration: 200, start: "inViewport" }, cb);
|
|
164
|
-
// type: delayed
|
|
211
|
+
// type: delayed|sync|async|nsync|oneByOne|scenario|scenario-sync ; start: inViewport|manual|autostart
|
|
212
|
+
v.setFrameProgress(0.5); // scrub draw 0..1 (drive from scroll); play(-1) rewinds
|
|
165
213
|
```
|
|
166
|
-
**License: MIT.**
|
|
167
|
-
|
|
214
|
+
**License: MIT.** Timing fns are statics (`Vivus.EASE_OUT`, custom `function(x)`), set
|
|
215
|
+
whole (`animTimingFunction`) or per-path (`pathTimingFunction`); per-path
|
|
216
|
+
`data-delay/duration`, `data-vivus-ignore`; bundles `pathformer` (primitives → path).
|
|
217
|
+
**Reach for it when:** a logo/icon/diagram should draw itself in — and, via
|
|
218
|
+
`setFrameProgress(0..1)`, a **scroll-linked** draw-on (extends §2's one-shot draw). The
|
|
219
|
+
same effect is achievable with CSS `stroke-dasharray`/`stroke-dashoffset` — use
|
|
168
220
|
that for one element, Vivus when orchestrating many paths.
|
|
169
221
|
|
|
170
222
|
### lenis (darkroomengineering/lenis)
|
|
171
223
|
Smooth-scroll normalizer (momentum/eased scrolling). Already referenced by
|
|
172
224
|
`maggie-clone`.
|
|
173
225
|
```js
|
|
174
|
-
const lenis = new Lenis({ autoRaf: true }); //
|
|
175
|
-
lenis.on("scroll", (e) => {/*
|
|
226
|
+
const lenis = new Lenis({ autoRaf: true }); // DEFAULT is autoRaf:false → drive lenis.raf(t) yourself
|
|
227
|
+
lenis.on("scroll", (e) => {/* e is the whole Lenis instance: e.scroll/.velocity/.progress/.direction */});
|
|
176
228
|
```
|
|
177
229
|
**License: MIT.** **Reach for it when:** the design calls for premium eased scrolling
|
|
178
230
|
and you pair it with scroll-triggered motion (commonly `lenis.raf` + GSAP
|
|
179
|
-
ScrollTrigger).
|
|
180
|
-
|
|
231
|
+
ScrollTrigger). **Source-verified defaults:** `lerp` is `0.1` (not 0.075 — that's
|
|
232
|
+
`syncTouchLerp`), `autoRaf` defaults **false**, and `respectReducedMotion` is a
|
|
233
|
+
first-class option (defaults true, falls back to native scroll via matchMedia).
|
|
234
|
+
Attribute opt-outs: `data-lenis-prevent[-vertical|-horizontal]`. Accessibility caveat:
|
|
235
|
+
keep `respectReducedMotion` on; never trap scroll in a way that breaks keyboard/anchor
|
|
236
|
+
jumps.
|
|
181
237
|
|
|
182
238
|
### barba.js (barbajs/barba)
|
|
183
239
|
SPA-style page transitions over MPAs: intercepts navigation, animates the old
|
|
@@ -203,6 +259,11 @@ return <animated.div style={styles}>…</animated.div>;
|
|
|
203
259
|
```
|
|
204
260
|
**License: MIT.** **Reach for it when:** a React project wants physics-based
|
|
205
261
|
(not duration-based) motion. For non-React, Motion's `spring` covers the same need.
|
|
262
|
+
**Source-verified presets** (`tension`/`friction`[/`mass`]): default `{170,26}`,
|
|
263
|
+
`gentle {120,14}`, `wobbly {180,12}`, `stiff {210,20}`, `slow {280,60}`,
|
|
264
|
+
`molasses {280,120}`. The `AnimationConfig` also exposes a **designer-friendly**
|
|
265
|
+
vocabulary — `frequency` + `damping(ratio)` (tension/friction derived from them),
|
|
266
|
+
plus `clamp`, `bounce`, `decay` — prefer these when writing a config for non-engineers.
|
|
206
267
|
|
|
207
268
|
### animate.css (animate-css/animate.css)
|
|
208
269
|
Prebuilt CSS keyframe classes (`animate__animated animate__fadeInUp`).
|
|
@@ -211,9 +272,20 @@ Prebuilt CSS keyframe classes (`animate__animated animate__fadeInUp`).
|
|
|
211
272
|
```
|
|
212
273
|
**License: Hippocratic License 2.1 — flag it (NOT MIT).** An ethical-source license
|
|
213
274
|
with use restrictions; not OSI-approved. Treat as a caution for commercial bundling;
|
|
214
|
-
the keyframe recipes (`fadeInUp`, durations, timing)
|
|
215
|
-
|
|
216
|
-
|
|
275
|
+
the keyframe recipes (`fadeInUp`, the `back_*` entrance/exit family, durations, timing)
|
|
276
|
+
are fine to **reimplement** yourself. Two patterns worth copying wholesale: its
|
|
277
|
+
**3-custom-prop timing system** (`--animate-duration` / `--animate-delay` /
|
|
278
|
+
`--animate-repeat` + `calc()` utility multipliers) and its built-in **reduced-motion /
|
|
279
|
+
print kill-switch** (collapses to 1ms and forces `*Out` animations to opacity 0 so
|
|
280
|
+
content never sticks hidden). **Reach for the patterns when:** you want a quick
|
|
281
|
+
named-entrance vocabulary — but author your own keyframes to stay license-clean.
|
|
282
|
+
|
|
283
|
+
### Out of scope — pixijs (pixijs/pixijs)
|
|
284
|
+
A WebGL/WebGPU **2D renderer**, not an animation engine: it ships no tween/easing (its
|
|
285
|
+
`Ticker` gives only `deltaTime`). The particle/shader libs build *on* it; for standard
|
|
286
|
+
DOM/CSS marketing motion it's out of scope — reach for it only for a heavy custom
|
|
287
|
+
canvas scene, and bring your own tween (GSAP/Motion). (Notable: it ships 26 first-party
|
|
288
|
+
`SKILL.md` agent skills — precedent for a library shipping its own skills.)
|
|
217
289
|
|
|
218
290
|
### Category O (offline / desktop, NOT web)
|
|
219
291
|
- **synfig** (synfig/synfig) — desktop 2D vector animation studio. **GPL-3.0.**
|
|
@@ -236,14 +308,28 @@ Default to expressive ease-out curves, never browser defaults (`ease`, `linear`,
|
|
|
236
308
|
color/opacity 300ms (never < 200ms). Other good ones: `cubic-bezier(0.16,1,0.3,1)`
|
|
237
309
|
(ease-out-expo), `cubic-bezier(0.34,1.56,0.64,1)` (gentle back/overshoot).
|
|
238
310
|
Libs: GSAP eases, anime `inOut*`, Motion. **LP + DM.**
|
|
311
|
+
*Custom eases as data:* when a bespoke curve is needed, author it as data rather than
|
|
312
|
+
code — GSAP parameterized strings (`"back.out(1.7)"`), mojs `easing.path()`/`bezier()`,
|
|
313
|
+
vivus custom `function(x)`, or a popmotion-style `mirror/reverse` of a base ease. Store
|
|
314
|
+
the curve with the motion spec (see Theatre.js data model below).
|
|
239
315
|
|
|
240
316
|
### Spring physics
|
|
241
317
|
Duration-less, physics-based motion — natural for interactive/hover and anything
|
|
242
318
|
that should feel tactile. Config shape is universal: `{ stiffness, damping, mass }`
|
|
243
319
|
(Motion: `type:"spring", stiffness:300, damping:30`; react-spring: `config.gentle`).
|
|
320
|
+
For configs a non-engineer will touch, prefer the **designer vocabulary** both engines
|
|
321
|
+
expose — Motion `{ visualDuration, bounce }`, react-spring `frequency` +
|
|
322
|
+
`damping(ratio)` (settle-time + bounciness), rather than raw stiffness/damping.
|
|
244
323
|
Libs: Motion `spring`, react-spring, GSAP (via plugins). **DM;** light touch on LP
|
|
245
324
|
(mostly micro-interactions).
|
|
246
325
|
|
|
326
|
+
### Burst / success micro-interaction
|
|
327
|
+
A discrete gesture (like, add-to-cart, CTA confirm) earns a one-shot radial burst from
|
|
328
|
+
the click point — one shape stamped into N transformed copies with an opacity ramp.
|
|
329
|
+
Lib: mojs `Burst` (or a hand-rolled radial-stamp, same idea as the Lottie Repeater in
|
|
330
|
+
[generative visuals](generative-visuals.md)). One gesture only; gate on reduced-motion.
|
|
331
|
+
**LP (primary CTA) + DM.**
|
|
332
|
+
|
|
247
333
|
### Scroll-reveal via IntersectionObserver — never scroll listeners
|
|
248
334
|
Elements rise ~32px and fade over 600–800ms, **once**, when they cross into view.
|
|
249
335
|
Always IntersectionObserver (or a lib that wraps it); never an unthrottled `scroll`
|
|
@@ -349,7 +435,10 @@ illustration when a designer supplies the JSON.
|
|
|
349
435
|
| auto-animate | MIT | |
|
|
350
436
|
| AOS | MIT | |
|
|
351
437
|
| typed.js | **GPL** | **Flag — don't bundle in proprietary output; reimplement.** |
|
|
352
|
-
| tsparticles | MIT | |
|
|
438
|
+
| tsparticles | MIT | v3+ single-object `load()`; ships CLI scaffolders + an MCP server. |
|
|
439
|
+
| particles.js | MIT | Legacy v2, unmaintained — use tsparticles (`pjs` compat). |
|
|
440
|
+
| mojs (@mojs/core) | MIT | Celebratory point bursts / success micro-interactions. |
|
|
441
|
+
| pixijs | MIT | WebGL 2D **renderer**, no tween — out of scope for DOM motion. |
|
|
353
442
|
| rive-runtime | MIT | Web runtime is `@rive-app/canvas`. |
|
|
354
443
|
| vivus | MIT | |
|
|
355
444
|
| lenis | MIT | |
|
|
@@ -371,9 +460,10 @@ state**, replayed by a tiny headless runtime (`@theatre/core`) against three.js,
|
|
|
371
460
|
HTML/SVG, or any JS variable. The borrowable pattern is the **declarative keyframe
|
|
372
461
|
document**, not the editor: store motion as JSON - a `sequence` with `length` +
|
|
373
462
|
`subUnitsPerUnit` (an fps snap-grid) -> **tracks keyed by property path** ->
|
|
374
|
-
**keyframes** each carrying `{ position, value, handles:[lx,ly,rx,ry],
|
|
375
|
-
type
|
|
376
|
-
data; `
|
|
463
|
+
**keyframes** each carrying `{ id, position, value, handles:[lx,ly,rx,ry],
|
|
464
|
+
connectedRight:boolean, type?:'bezier'|'hold' }` (per-keyframe bezier handles =
|
|
465
|
+
per-segment easing baked into data; `type` is optional, defaults bezier; `value` may be
|
|
466
|
+
non-numeric). Playback mirrors CSS: `play({ iterationCount,
|
|
377
467
|
range, rate, direction:'alternateReverse' })`. Author a brand motion once, commit the
|
|
378
468
|
JSON as a reusable asset, replay it deterministically with no editor shipped - the
|
|
379
469
|
authoring story for `maggie-design-motion` (keep the motion *spec* as data, not
|
|
@@ -395,4 +485,9 @@ hero as `inputs -> conditions -> states` - declare inputs (`hovered:bool`,
|
|
|
395
485
|
`scroll:0..1`, `clicked:trigger`), bind DOM events to them, and switch CSS/WAAPI/GSAP
|
|
396
486
|
timelines by state rather than scripting each handler; a number input + interpolation
|
|
397
487
|
gives scroll-linked response, random-picked idle transitions give a "living" element.
|
|
398
|
-
(Rive's own MIT player is also a legitimate option.)
|
|
488
|
+
(Rive's own MIT player is also a legitimate option.) Source-verified, the model is
|
|
489
|
+
richer than the sketch above: any input source maps onto one **unified listener bus**
|
|
490
|
+
(pointer/scroll/keyboard/gamepad/text/focus), transitions can be guarded by **app data**
|
|
491
|
+
via **ViewModel data-binding conditions** (not just events), comparator ops are a full
|
|
492
|
+
enum (`eq/neq/lt/gt/lte/gte`), and nested state machines compose — so "driven by data,
|
|
493
|
+
not handlers" is the portable lesson for a browser reimplementation.
|