@topy-ai/maggie 0.8.11 → 0.8.12
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 +2 -2
- package/bundled-references/captions-transcription.md +41 -0
- package/bundled-references/generative-visuals.md +90 -0
- package/bundled-references/image-recipes.md +89 -0
- package/bundled-references/web-animation-patterns.md +364 -0
- package/bundled-skills/catalog.json +4 -0
- package/bundled-skills/maggie-design/SKILL.md +7 -2
- package/bundled-skills/maggie-design-motion/SKILL.md +4 -1
- package/bundled-skills/maggie-image/SKILL.md +100 -0
- package/bundled-skills/maggie-landing-page/SKILL.md +5 -1
- package/bundled-skills/maggie-spirit/SKILL.md +4 -2
- package/bundled-skills/maggie-video/SKILL.md +3 -2
- package/bundled-tools/clis/maggie_image.py +221 -0
- package/package.json +1 -1
- package/references/captions-transcription.md +41 -0
- package/references/generative-visuals.md +90 -0
- package/references/image-recipes.md +89 -0
- package/references/web-animation-patterns.md +364 -0
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.11
|
|
146
|
+
目前 npm 版本為 `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
|
@@ -87,9 +87,9 @@ Then invoke the installed skills from your coding agent, for example:
|
|
|
87
87
|
|
|
88
88
|
Maggie keeps the existing project foundation and asks for decisions before
|
|
89
89
|
shared routes, analytics, or publishing boundaries change. The current
|
|
90
|
-
package ships
|
|
90
|
+
package ships 38 installable skills and a local-first MaggieDash foundation.
|
|
91
91
|
|
|
92
|
-
This package is `0.8.
|
|
92
|
+
This package is `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
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Captions and transcription
|
|
2
|
+
|
|
3
|
+
Local, offline speech-to-text for video captions and transcripts, used by
|
|
4
|
+
`maggie-video`'s `captions` subcommand. All engines run on the user's machine - **no
|
|
5
|
+
paid API** - so transcription has no per-minute cost, only local CPU/GPU time.
|
|
6
|
+
Distilled from the reference library's R-category projects.
|
|
7
|
+
|
|
8
|
+
## Engines
|
|
9
|
+
|
|
10
|
+
| Engine | What / how | License | Reach for it when |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| openai-whisper | The reference Python CLI: `whisper IN --model base --output_format srt --output_dir DIR` | MIT | the default; simplest install (`pip install openai-whisper`) |
|
|
13
|
+
| whisper.cpp | C/C++ port, fast on CPU, GGML models: `whisper-cli -m model.bin -f IN -osrt -of OUTBASE` | MIT | no GPU / fastest CPU / embedding in a pipeline |
|
|
14
|
+
| whisperX | whisper + forced alignment for **word-level timestamps** and diarization: `whisperx IN --model large-v3 --output_format srt --output_dir DIR` | BSD-4 | word-accurate caption timing or speaker labels |
|
|
15
|
+
|
|
16
|
+
Model size trades speed for accuracy: `tiny` / `base` (fast, rough) -> `small` /
|
|
17
|
+
`medium` -> `large-v3` (slow, best). Use `--lang` to skip auto-detect when known.
|
|
18
|
+
|
|
19
|
+
## Workflow (voiceover -> captions -> on-screen)
|
|
20
|
+
|
|
21
|
+
1. **Transcribe** the voiceover or the video's audio to SRT with a local engine
|
|
22
|
+
(`maggie_video.py captions --input vo.mp3 --output vo.srt --engine whisper
|
|
23
|
+
--model base`). A larger model is slower but more accurate.
|
|
24
|
+
2. **Review** the SRT - never ship an unreviewed transcript; whisper mishears names,
|
|
25
|
+
numbers, and brand terms. A human edits it.
|
|
26
|
+
3. **Put it on screen**, one of:
|
|
27
|
+
- burn in (`maggie_video.py subtitle --input video.mp4 --srt vo.srt --output out.mp4`),
|
|
28
|
+
- soft-mux a toggleable track (`subtitle --soft`), or
|
|
29
|
+
- a `captions` layer in a `maggie_video.py compile` timeline (see
|
|
30
|
+
[video timeline model](video-timeline-model.md)).
|
|
31
|
+
|
|
32
|
+
## Rules
|
|
33
|
+
|
|
34
|
+
- Captions lift watch time and serve sound-off viewing - caption every social video.
|
|
35
|
+
- **Never fabricate a transcript**; generate it from the real audio and have a human
|
|
36
|
+
review before publishing (accuracy, names, and brand terms).
|
|
37
|
+
- Local/offline: no audio leaves the machine, no paid API. If a hosted transcription
|
|
38
|
+
API is ever wired in instead, the global spend-first rule applies - state the cost.
|
|
39
|
+
- Keep caption text inside the safe area (see `maggie-video` channel presets).
|
|
40
|
+
|
|
41
|
+
See `maggie-video` for the subcommands and the burn-in / soft-mux / compile options.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Generative visuals (creative coding)
|
|
2
|
+
|
|
3
|
+
Patterns for generating marketing visuals in code - hero backgrounds, textures, 3D
|
|
4
|
+
product shots, data-viz, and stylized images - distilled from the leading creative-
|
|
5
|
+
coding libraries. We adopt **patterns, not code**. Output becomes a deliverable as a
|
|
6
|
+
**still** (canvas/SVG export) or a **loop** (captured via
|
|
7
|
+
[design-motion production](design-motion-production.md) Part C or
|
|
8
|
+
[ffmpeg recipes](ffmpeg-recipes.md), then assembled in `maggie-video`). Determinism
|
|
9
|
+
by seeding matches `maggie-spirit`'s philosophy: same seed -> same pixels.
|
|
10
|
+
|
|
11
|
+
## Libraries
|
|
12
|
+
|
|
13
|
+
| Library | What / model | Lang | License | Marketing fit |
|
|
14
|
+
|---|---|---|---|---|
|
|
15
|
+
| three.js | WebGL 3D: Scene + Camera + WebGLRenderer; `renderer.render(scene,camera)` in a loop | JS | MIT | 3D product spins, logo stings, depth-y hero backgrounds |
|
|
16
|
+
| Babylon.js | Higher-level 3D engine (PBR, asset pipeline); heavier | JS/TS | Apache-2.0 | 3D product config; alt to three when its pipeline earns the weight |
|
|
17
|
+
| react-three-fiber | three.js as React JSX (`<mesh><boxGeometry/>…`), `useFrame` | JS/TS | MIT | 3D on a React site |
|
|
18
|
+
| p5.js | Canvas sketch: `setup()` once + `draw()` per frame; `random()/noise()` with `randomSeed()/noiseSeed()` | JS | **LGPL-2.1** | generative hero backgrounds, flow fields, noise art |
|
|
19
|
+
| paper.js | Vector scene graph (Path/Group), boolean ops, hit-testing | JS | MIT | editable vector hero art, print-quality SVG |
|
|
20
|
+
| two.js | One 2D API across SVG/Canvas/WebGL renderers | JS | MIT | vector art you want to export as SVG or capture from canvas |
|
|
21
|
+
| rough.js | Hand-drawn/sketchy shapes; `{seed}` = reproducible | JS/TS | MIT | approachable hand-made brand style, doodle accents |
|
|
22
|
+
| zdog | Pseudo-3D round/flat vector, designer-friendly | JS | MIT | cute 3D-ish icons, mascot/logo spins |
|
|
23
|
+
| pts | Computational geometry (Space + Form + Pt) | TS/JS | Apache-2.0 | geometric/particle hero art |
|
|
24
|
+
| hydra | Live-coded video synth (chained GLSL ops) | JS | **AGPL-3.0** | trippy animated backgrounds - **pattern only, do not ship its code** |
|
|
25
|
+
| regl | Functional WebGL (stateless draw commands) | JS | MIT | custom shader backgrounds/gradients when three is overkill |
|
|
26
|
+
| d3 | Data-driven SVG (scales + selections) | JS | ISC | bespoke infographics - but defer standard charts to the `dataviz` skill |
|
|
27
|
+
| fogleman/primitive | Reproduce an image with N geometric primitives (CLI) | Go | MIT | stylize a product photo into abstract art (still or GIF) |
|
|
28
|
+
| svg.js | Lightweight SVG DOM manipulation | JS | MIT | programmatic SVG icons/badges/dividers |
|
|
29
|
+
| nannou | Rust creative framework (desktop) | Rust | MIT/Apache | note only - high-perf generative art in Rust |
|
|
30
|
+
|
|
31
|
+
**License flags:** hydra is **AGPL-3.0**, p5 is **LGPL-2.1**, processing (non-core)
|
|
32
|
+
is GPL - fine as *idea* sources, but do not vendor their code into shipped product;
|
|
33
|
+
reimplement the pattern or use an MIT equivalent (two.js / pts / regl / svg.js).
|
|
34
|
+
|
|
35
|
+
## Patterns and the deliverable path
|
|
36
|
+
|
|
37
|
+
- **2D generative** (p5 / paper / two / rough / zdog / pts / svg.js): `setup()` once +
|
|
38
|
+
`draw()`/`update()` per frame. Use for brand-tinted hero/section backgrounds,
|
|
39
|
+
textures, doodle accents, geometric motifs. **Still:** SVG-capable libs serialize
|
|
40
|
+
their `<svg>` (crisp, editable, print-ready); canvas libs use `canvas.toDataURL()`
|
|
41
|
+
-> PNG. **Loop:** run the sketch headless and capture via design-motion Part C, or
|
|
42
|
+
in-browser with CCapture.js (MIT), then hand to `maggie-video`.
|
|
43
|
+
- **3D** (three / babylon / r3f): Scene + Camera + Renderer; animate by frame index.
|
|
44
|
+
Product spins, 3D logo stings, depth-y backgrounds. **Still:**
|
|
45
|
+
`renderer.domElement.toDataURL()` (set `preserveDrawingBuffer:true`); **loop:** drive
|
|
46
|
+
by frame, capture as above. Prefer three/r3f (MIT); babylon only when needed.
|
|
47
|
+
- **Data-viz** (d3): `d3-scale` + `d3-selection`; SVG is the native output. For
|
|
48
|
+
standard charts, **defer to the `dataviz` skill** (its palette/spec); pull in d3
|
|
49
|
+
only for bespoke marks (arc diagrams, force layouts, custom infographics).
|
|
50
|
+
- **Live visuals** (hydra): chained feedback-graph ops -> animated GLSL. Renders to a
|
|
51
|
+
canvas -> capture -> `maggie-video`. **AGPL: idea only**; for an MIT shader
|
|
52
|
+
background use regl.
|
|
53
|
+
- **Image -> primitives** (fogleman/primitive, MIT, Go CLI): stylize a photo into
|
|
54
|
+
abstract geometry.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
primitive -i input.png -o output.svg -n 100 -m 1
|
|
58
|
+
# -n shapes (50-200); -m mode (1 triangle,2 rect,3 ellipse,4 circle,6 beziers,8 polygon);
|
|
59
|
+
# output type by extension: PNG/JPG (raster), SVG (vector), GIF (animated, needs ImageMagick)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Still:** PNG/SVG directly; **loop:** `.gif` or `%d`-numbered PNG frames ->
|
|
63
|
+
`maggie-video`. It is randomized (no seed): generate once and **store the artifact**;
|
|
64
|
+
do not regenerate on every build.
|
|
65
|
+
|
|
66
|
+
## Determinism
|
|
67
|
+
|
|
68
|
+
p5 `randomSeed()/noiseSeed()`, rough.js `{seed}`, and a seeded PRNG in place of
|
|
69
|
+
`Math.random` give byte-reproducible stills; the frame-index/virtual-clock rule from
|
|
70
|
+
[programmatic video](programmatic-video.md) gives reproducible motion. `primitive`
|
|
71
|
+
and `hydra` are non-deterministic - capture and store their output as a fixed asset.
|
|
72
|
+
|
|
73
|
+
## Placement
|
|
74
|
+
|
|
75
|
+
- **maggie-spirit** owns seeded brand marks/characters; borrow the 2D-canvas sketch
|
|
76
|
+
model and seed discipline for flat-vector mark construction (zdog/two.js/rough).
|
|
77
|
+
Generative *backgrounds/scenes* do not live here.
|
|
78
|
+
- **maggie-design** owns generative hero backgrounds, section textures, 3D product
|
|
79
|
+
shots and image stylization as page/brand visuals; it points at this reference and
|
|
80
|
+
cross-links design-motion / `maggie-video` for capture-to-deliverable.
|
|
81
|
+
- **Reference-only:** d3 (defer to `dataviz`), hydra (AGPL, idea only), regl, babylon,
|
|
82
|
+
nannou/processing/openFrameworks (desktop notes), svg.js.
|
|
83
|
+
|
|
84
|
+
## Credits
|
|
85
|
+
|
|
86
|
+
Patterns adapted (not code) from three.js, p5.js, d3, paper.js, two.js, rough.js,
|
|
87
|
+
zdog, pts, hydra, regl, Babylon.js, react-three-fiber, fogleman/primitive, svg.js,
|
|
88
|
+
nannou - licenses in the table above. Capture pipeline: see
|
|
89
|
+
[programmatic video](programmatic-video.md), [design-motion production](design-motion-production.md),
|
|
90
|
+
[ffmpeg recipes](ffmpeg-recipes.md).
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Image recipes
|
|
2
|
+
|
|
3
|
+
The distilled, correct image-processing command layer for marketing assets, used by
|
|
4
|
+
`maggie-image`. These are the commands `maggie_image.py` generates. Distilled from
|
|
5
|
+
ImageMagick, sharp, svgo, resvg, squoosh and imagemin (reference library category P).
|
|
6
|
+
We **invoke binaries at arm's length** (adopt defaults, not code).
|
|
7
|
+
|
|
8
|
+
**Tool posture.** ImageMagick (`magick` on IM7, else `convert`) is almost always
|
|
9
|
+
present and covers nearly every raster op, so it is the **primary** path; dedicated
|
|
10
|
+
tools (svgo, resvg, cwebp, avifenc, pngquant) are the **better-quality alternative
|
|
11
|
+
used automatically when installed**. Web-delivery quality defaults follow sharp/
|
|
12
|
+
squoosh: JPEG/WebP ~80, AVIF ~50. OG/social are **cover-cropped**; logos **pad**.
|
|
13
|
+
Strip metadata on anything public (privacy + bytes).
|
|
14
|
+
|
|
15
|
+
## Resize + fit (the most-used op)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# cover / crop to exactly WxH (fills the frame, center-crop)
|
|
19
|
+
convert in.jpg -strip -resize 1200x630^ -gravity center -extent 1200x630 -quality 82 out.jpg
|
|
20
|
+
# contain / letterbox with a pad color
|
|
21
|
+
convert in.jpg -strip -resize 1200x630 -background '#ffffff' -gravity center -extent 1200x630 out.jpg
|
|
22
|
+
# downscale-only (never enlarge): -resize 1200x630>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
sharp's smart crop (`fit:'cover', position:attention`) avoids cutting off a face;
|
|
26
|
+
ImageMagick has no equal, so for portraits prefer sharp when available.
|
|
27
|
+
|
|
28
|
+
## WebP / AVIF (file-size wins)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
convert in.png -strip -quality 80 -define webp:method=6 out.webp # or: cwebp -q 80 -m 6 in.png -o out.webp
|
|
32
|
+
convert in.png -strip -quality 50 out.avif # or: avifenc -s 6 --min 20 --max 40 in.png out.avif
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Channel / OG presets
|
|
36
|
+
|
|
37
|
+
Cover-crop to the target: OG 1200x630, Twitter 1600x900, square 1080x1080, story/reel
|
|
38
|
+
1080x1920, landscape 1920x1080, LinkedIn 1200x627, Pinterest 1000x1500. Same command
|
|
39
|
+
as cover resize with the preset size, `-strip -quality 82`.
|
|
40
|
+
|
|
41
|
+
## Favicon + OG set
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
convert in.png -define icon:auto-resize=64,48,32,16 favicon.ico # multi-res .ico
|
|
45
|
+
convert in.png -strip -resize 180x180 apple-touch-icon.png # + 16/32/48/192/512 PNGs
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Strip metadata / compress
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
convert in.jpg -strip out.jpg # drop EXIF/GPS/ICC
|
|
52
|
+
convert in.jpg -strip -interlace Plane -quality 82 out.jpg # progressive JPEG
|
|
53
|
+
pngquant --quality 60-82 --strip --output out.png in.png # lossy PNG (best); IM fallback: -colors 256 -define png:compression-level=9
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## SVG optimize / render
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
svgo --multipass -i in.svg -o out.svg # keeps viewBox + title (responsive + a11y). If svgo absent, leave the SVG alone - never rasterize as a substitute.
|
|
60
|
+
resvg -w 512 in.svg out.png # best-fidelity SVG -> PNG (or rsvg-convert -w 512); IM fallback (-background none -density 384) is lower fidelity
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Montage / contact sheet (carousels, screenshot grids)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
montage a.png b.png c.png -tile 3x -geometry 400x400+10+10 -background '#ffffff' sheet.jpg
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## The CLI
|
|
70
|
+
|
|
71
|
+
`maggie_image.py` generates each command above (and runs it with `--run` when the
|
|
72
|
+
tool is on PATH; `--force-im` forces the ImageMagick path). It detects IM6 `convert`
|
|
73
|
+
vs IM7 `magick`:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
maggie tool maggie_image.py social --input hero.png --output og.jpg --preset og
|
|
77
|
+
maggie tool maggie_image.py --run webp --input hero.png --output hero.webp --quality 80
|
|
78
|
+
maggie tool maggie_image.py --run favicon --input logo.png --out-dir public/
|
|
79
|
+
maggie tool maggie_image.py svg2png --input logo.svg --output logo.png --width 512
|
|
80
|
+
maggie tool maggie_image.py presets
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Licenses
|
|
84
|
+
|
|
85
|
+
Invoked at arm's length: ImageMagick (permissive), SVGO (MIT), resvg (MIT/Apache),
|
|
86
|
+
sharp (Apache-2.0), squoosh codecs (Apache-2.0), imagemin (MIT), cwebp/avifenc
|
|
87
|
+
(BSD). **Avoid vendoring code from** Upscayl (AGPL-3.0) - for AI upscaling invoke the
|
|
88
|
+
separate `realesrgan-ncnn-vulkan` binary instead. sharp/squoosh quality defaults are
|
|
89
|
+
adopted as the preset numbers.
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Web / UI animation patterns
|
|
2
|
+
|
|
3
|
+
Engine-neutral motion vocabulary for marketing web pages, distilled from the leading
|
|
4
|
+
open-source animation libraries. We adopt **patterns and per-library guidance, not
|
|
5
|
+
code** — we rarely ship these libraries; we copy the technique (the eases, the
|
|
6
|
+
IntersectionObserver reveal, the spring config, the Lottie workflow). Feeds
|
|
7
|
+
`maggie-landing-page` (B7 motion + the mandatory tagline reveal) and
|
|
8
|
+
`maggie-design-motion` (its *website* context).
|
|
9
|
+
|
|
10
|
+
Rule of thumb: a marketing page needs **CSS transitions + IntersectionObserver +
|
|
11
|
+
one tiny helper** far more often than a 30KB animation engine. Reach for a library
|
|
12
|
+
only when the pattern below says so. Default is zero-dependency.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. The libraries
|
|
17
|
+
|
|
18
|
+
Each entry: what it is · core API shape (real snippet) · license · when to reach for it.
|
|
19
|
+
|
|
20
|
+
### GSAP (greensock/GSAP) — v3.15
|
|
21
|
+
Framework-agnostic JS animation engine: tweens, timelines, eases, plugins
|
|
22
|
+
(ScrollTrigger, SplitText, MorphSVG, Flip, MotionPath). The gold standard for
|
|
23
|
+
sequenced, scroll-driven work.
|
|
24
|
+
```js
|
|
25
|
+
gsap.registerPlugin(ScrollTrigger);
|
|
26
|
+
const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.6 } });
|
|
27
|
+
tl.from(".hero h1", { y: 40, opacity: 0 })
|
|
28
|
+
.from(".hero p", { y: 24, opacity: 0 }, "-=0.3"); // overlap previous by 0.3s
|
|
29
|
+
gsap.from(".card", {
|
|
30
|
+
scrollTrigger: { trigger: ".card", start: "top 80%", once: true },
|
|
31
|
+
y: 32, opacity: 0, stagger: 0.08,
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
**License: custom "Standard no-charge license" (NOT MIT/OSI).** As of 2024 (Webflow)
|
|
35
|
+
GSAP including all former Club plugins is 100% free for commercial use, but it is a
|
|
36
|
+
proprietary license, not open source — flag it before bundling. CDN:
|
|
37
|
+
`cdn.jsdelivr.net/npm/gsap@3.15/dist/gsap.min.js`.
|
|
38
|
+
**Reach for it when:** a page needs a real timeline (chained, overlapping steps) or
|
|
39
|
+
scroll-scrubbed sequencing beyond a one-shot reveal. Overkill for simple fades.
|
|
40
|
+
|
|
41
|
+
### Motion / framer-motion (motiondivision/motion)
|
|
42
|
+
Hybrid engine: a tiny imperative `animate()` for vanilla JS plus declarative
|
|
43
|
+
`<motion.div>` for React/Vue. Uses the native WAAPI where possible (GPU, 120fps),
|
|
44
|
+
springs, `scroll()`, `inView()`, layout transitions.
|
|
45
|
+
```js
|
|
46
|
+
import { animate, inView, scroll, stagger } from "motion";
|
|
47
|
+
animate("#box", { x: 100, opacity: 1 }, { type: "spring", stiffness: 300, damping: 30 });
|
|
48
|
+
inView(".card", (el) => { animate(el, { opacity: 1, y: 0 }); }, { amount: 0.3 });
|
|
49
|
+
// React: <motion.div initial={{opacity:0,y:24}} whileInView={{opacity:1,y:0}} viewport={{once:true}}/>
|
|
50
|
+
```
|
|
51
|
+
**License: MIT** (core; a paid "Motion+" add-on exists but isn't required).
|
|
52
|
+
**Reach for it when:** the project is already React/Vue, or you want springs +
|
|
53
|
+
scroll + inView from one small MIT lib. `inView` is a clean IntersectionObserver
|
|
54
|
+
wrapper — our preferred engine when a dependency is acceptable.
|
|
55
|
+
|
|
56
|
+
### anime.js (juliangarnier/anime) — v4
|
|
57
|
+
Small, elegant timeline/stagger/easing lib. V4 is ESM tree-shakable.
|
|
58
|
+
```js
|
|
59
|
+
import { animate, stagger } from "animejs";
|
|
60
|
+
animate(".square", {
|
|
61
|
+
x: 320, rotate: { from: -180 }, duration: 1250,
|
|
62
|
+
delay: stagger(65, { from: "center" }), ease: "inOutQuint",
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
**License: MIT.** **Reach for it when:** you want expressive staggers/keyframes
|
|
66
|
+
lighter than GSAP and don't need ScrollTrigger-grade scroll control.
|
|
67
|
+
|
|
68
|
+
### lottie-web (airbnb/lottie-web)
|
|
69
|
+
Plays **Lottie JSON** (vector animations exported from After Effects via Bodymovin)
|
|
70
|
+
in the browser as SVG/canvas/HTML.
|
|
71
|
+
```js
|
|
72
|
+
const anim = lottie.loadAnimation({
|
|
73
|
+
container: el, renderer: "svg", loop: true, autoplay: true,
|
|
74
|
+
path: "hero.json", // or animationData: <obj>
|
|
75
|
+
});
|
|
76
|
+
anim.playSegments([0, 60], true); // play part of the timeline
|
|
77
|
+
anim.setSpeed(1); anim.pause();
|
|
78
|
+
```
|
|
79
|
+
**License: MIT.** **Reach for it when:** a designer delivers an AE/Lottie file and
|
|
80
|
+
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.
|
|
82
|
+
|
|
83
|
+
### rlottie (Samsung/rlottie)
|
|
84
|
+
Native (C++) Lottie renderer — the runtime behind Lottie on native/embedded (not a
|
|
85
|
+
web lib). Category O. **License: MIT** (mostly; some vendored parts differ, see
|
|
86
|
+
COPYING). **Reach for it when:** the same Lottie JSON must also play in a native app
|
|
87
|
+
(our Expo/RN surfaces) — same asset, native renderer. On web it's lottie-web.
|
|
88
|
+
|
|
89
|
+
### theatre.js (theatre-js/theatre)
|
|
90
|
+
In-browser motion-design **editor**: scrub a timeline, keyframe any JS object's
|
|
91
|
+
props, then play the saved sequence at runtime via `@theatre/core`.
|
|
92
|
+
```js
|
|
93
|
+
import { getProject } from "@theatre/core";
|
|
94
|
+
const sheet = getProject("Hero").sheet("Intro");
|
|
95
|
+
const obj = sheet.object("Logo", { x: 0, opacity: 0 });
|
|
96
|
+
obj.onValuesChange((v) => { el.style.transform = `translateX(${v.x}px)`; el.style.opacity = v.opacity; });
|
|
97
|
+
sheet.sequence.play({ iterationCount: 1 });
|
|
98
|
+
```
|
|
99
|
+
**License: Apache-2.0.** **Reach for it when:** a complex bespoke sequence is easier
|
|
100
|
+
to hand-author on a timeline than in code. Niche for marketing pages; mostly a
|
|
101
|
+
design-time tool. Note for `maggie-design-motion`, not landing pages.
|
|
102
|
+
|
|
103
|
+
### auto-animate (formkit/auto-animate)
|
|
104
|
+
Zero-config: one call and children added/removed/moved animate automatically.
|
|
105
|
+
```js
|
|
106
|
+
import autoAnimate from "@formkit/auto-animate";
|
|
107
|
+
autoAnimate(document.getElementById("list")); // React: const [ref] = useAutoAnimate()
|
|
108
|
+
```
|
|
109
|
+
**License: MIT.** **Reach for it when:** lists, filters, accordions, or reordering UI
|
|
110
|
+
need smooth transitions with no keyframes. Great low-effort polish for interactive
|
|
111
|
+
sections (pricing toggles, FAQ, filtered galleries).
|
|
112
|
+
|
|
113
|
+
### AOS (michalsnik/aos)
|
|
114
|
+
Animate-on-scroll via HTML data-attributes + a prebuilt CSS set.
|
|
115
|
+
```html
|
|
116
|
+
<div data-aos="fade-up" data-aos-delay="50" data-aos-duration="800"
|
|
117
|
+
data-aos-once="true" data-aos-anchor-placement="top-center"></div>
|
|
118
|
+
<script>AOS.init({ once: true, duration: 800, easing: "ease-out-cubic" });</script>
|
|
119
|
+
```
|
|
120
|
+
**License: MIT.** Uses IntersectionObserver internally. **Reach for it when:** a
|
|
121
|
+
no-JS-authoring team wants declarative scroll reveals fast. For our output we
|
|
122
|
+
usually hand-roll the same effect (§2) rather than ship AOS, but its attribute
|
|
123
|
+
vocabulary (`fade-up`, `once`, per-element delay/offset) is the pattern to copy.
|
|
124
|
+
|
|
125
|
+
### typed.js (mattboldt/typed.js)
|
|
126
|
+
Typewriter effect.
|
|
127
|
+
```js
|
|
128
|
+
const typed = new Typed("#el", { strings: ["First.", "& second."], typeSpeed: 50, backSpeed: 30, loop: true });
|
|
129
|
+
```
|
|
130
|
+
**License: GPL — flag it.** GNU GPL, not MIT. Do **not** bundle into proprietary
|
|
131
|
+
output; reimplement the ~20-line effect yourself (or use a permissive alt) if you
|
|
132
|
+
need typing. **Reach for the pattern when:** a hero rotates through phrases. Keep it
|
|
133
|
+
short, respect reduced-motion (render the final string statically).
|
|
134
|
+
|
|
135
|
+
### tsparticles (tsparticles/tsparticles)
|
|
136
|
+
Config-driven particle backgrounds/confetti.
|
|
137
|
+
```js
|
|
138
|
+
await tsParticles.load({ id: "tsparticles", options: {
|
|
139
|
+
background: { color: "#0d1117" },
|
|
140
|
+
particles: { number: { value: 60 }, move: { enable: true } },
|
|
141
|
+
}});
|
|
142
|
+
```
|
|
143
|
+
**License: MIT.** **Reach for it when:** a hero wants a subtle particle/constellation
|
|
144
|
+
backdrop or a celebratory confetti burst. Use sparingly — it's a performance and
|
|
145
|
+
taste liability; cap particle count, pause offscreen, disable on reduced-motion.
|
|
146
|
+
|
|
147
|
+
### rive (rive-app/rive-runtime)
|
|
148
|
+
Interactive vector animations driven by **state machines** (inputs → states), not
|
|
149
|
+
just linear playback. `rive-runtime` is the C++ core; on web you use `@rive-app/canvas`.
|
|
150
|
+
```js
|
|
151
|
+
import { Rive } from "@rive-app/canvas";
|
|
152
|
+
const r = new Rive({ src: "button.riv", canvas, autoplay: true,
|
|
153
|
+
stateMachines: "State Machine 1", onLoad: () => r.resizeDrawingSurfaceToCanvas() });
|
|
154
|
+
r.stateMachineInputs("State Machine 1").find(i => i.name === "hover").value = true;
|
|
155
|
+
```
|
|
156
|
+
**License: MIT.** **Reach for it when:** an element must *react* (hover/click/scroll
|
|
157
|
+
drives animation state) — interactive mascots, animated toggles. Heavier workflow
|
|
158
|
+
(needs the Rive editor); overkill for passive decoration — prefer Lottie for that.
|
|
159
|
+
|
|
160
|
+
### vivus (maxwellito/vivus)
|
|
161
|
+
Animates SVG stroke draw-on ("self-drawing" line art).
|
|
162
|
+
```js
|
|
163
|
+
new Vivus("my-svg", { type: "oneByOne", duration: 200, start: "inViewport" }, cb);
|
|
164
|
+
// type: delayed | sync | oneByOne | scenario ; start: inViewport | manual | autostart
|
|
165
|
+
```
|
|
166
|
+
**License: MIT.** **Reach for it when:** a logo/icon/diagram should draw itself in.
|
|
167
|
+
The same effect is achievable with CSS `stroke-dasharray`/`stroke-dashoffset` — use
|
|
168
|
+
that for one element, Vivus when orchestrating many paths.
|
|
169
|
+
|
|
170
|
+
### lenis (darkroomengineering/lenis)
|
|
171
|
+
Smooth-scroll normalizer (momentum/eased scrolling). Already referenced by
|
|
172
|
+
`maggie-clone`.
|
|
173
|
+
```js
|
|
174
|
+
const lenis = new Lenis({ autoRaf: true }); // or drive lenis.raf(t) in your own rAF
|
|
175
|
+
lenis.on("scroll", (e) => {/* sync scroll-linked effects */});
|
|
176
|
+
```
|
|
177
|
+
**License: MIT.** **Reach for it when:** the design calls for premium eased scrolling
|
|
178
|
+
and you pair it with scroll-triggered motion (commonly `lenis.raf` + GSAP
|
|
179
|
+
ScrollTrigger). Accessibility caveat: disable/reduce under `prefers-reduced-motion`;
|
|
180
|
+
never trap or override scroll in a way that breaks keyboard/anchor jumps.
|
|
181
|
+
|
|
182
|
+
### barba.js (barbajs/barba)
|
|
183
|
+
SPA-style page transitions over MPAs: intercepts navigation, animates the old
|
|
184
|
+
container out and the new one in (no full reload).
|
|
185
|
+
```js
|
|
186
|
+
barba.init({ transitions: [{
|
|
187
|
+
name: "fade",
|
|
188
|
+
leave: ({ current }) => gsap.to(current.container, { opacity: 0 }),
|
|
189
|
+
enter: ({ next }) => gsap.from(next.container, { opacity: 0 }),
|
|
190
|
+
}]});
|
|
191
|
+
// markup: <main data-barba="wrapper"><section data-barba="container" data-barba-namespace="home">
|
|
192
|
+
```
|
|
193
|
+
**License: MIT.** **Reach for it when:** a multi-page marketing site wants seamless
|
|
194
|
+
cross-page transitions. Needs care for SEO/analytics/scroll-restore; often more than
|
|
195
|
+
a landing page needs.
|
|
196
|
+
|
|
197
|
+
### react-spring (pmndrs/react-spring)
|
|
198
|
+
Spring-physics animation for React (hooks).
|
|
199
|
+
```js
|
|
200
|
+
import { animated, useSpring } from "@react-spring/web";
|
|
201
|
+
const styles = useSpring({ from: { opacity: 0, y: 24 }, to: { opacity: 1, y: 0 } });
|
|
202
|
+
return <animated.div style={styles}>…</animated.div>;
|
|
203
|
+
```
|
|
204
|
+
**License: MIT.** **Reach for it when:** a React project wants physics-based
|
|
205
|
+
(not duration-based) motion. For non-React, Motion's `spring` covers the same need.
|
|
206
|
+
|
|
207
|
+
### animate.css (animate-css/animate.css)
|
|
208
|
+
Prebuilt CSS keyframe classes (`animate__animated animate__fadeInUp`).
|
|
209
|
+
```html
|
|
210
|
+
<h1 class="animate__animated animate__fadeInUp">Hi</h1>
|
|
211
|
+
```
|
|
212
|
+
**License: Hippocratic License 2.1 — flag it (NOT MIT).** An ethical-source license
|
|
213
|
+
with use restrictions; not OSI-approved. Treat as a caution for commercial bundling;
|
|
214
|
+
the keyframe recipes (`fadeInUp`, durations, timing) are fine to **reimplement**
|
|
215
|
+
yourself. **Reach for the patterns when:** you want a quick named-entrance
|
|
216
|
+
vocabulary — but author your own keyframes to stay license-clean.
|
|
217
|
+
|
|
218
|
+
### Category O (offline / desktop, NOT web)
|
|
219
|
+
- **synfig** (synfig/synfig) — desktop 2D vector animation studio. **GPL-3.0.**
|
|
220
|
+
- **friction** (friction2d/friction) — desktop motion-graphics/vector animator.
|
|
221
|
+
**GPL-3.0.** Sparse docs.
|
|
222
|
+
Both are authoring tools, not runtimes. Note as offline/GPL; they can *produce*
|
|
223
|
+
assets (e.g. exported video/sequences) but nothing here ships to the web.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 2. Engine-neutral pattern set (what we actually adopt)
|
|
228
|
+
|
|
229
|
+
For each pattern: the technique, which libs embody it, and where it belongs
|
|
230
|
+
(**LP** = `maggie-landing-page`, **DM** = `maggie-design-motion` website context).
|
|
231
|
+
|
|
232
|
+
### Eased entrances — the good cubic-beziers
|
|
233
|
+
Default to expressive ease-out curves, never browser defaults (`ease`, `linear`,
|
|
234
|
+
`ease-in-out`). House base curve: `cubic-bezier(0.22, 1, 0.36, 1)` ("ease-out-quint",
|
|
235
|
+
~500ms for layout/position; GSAP's `power3/power4.out` equivalent). Hover
|
|
236
|
+
color/opacity 300ms (never < 200ms). Other good ones: `cubic-bezier(0.16,1,0.3,1)`
|
|
237
|
+
(ease-out-expo), `cubic-bezier(0.34,1.56,0.64,1)` (gentle back/overshoot).
|
|
238
|
+
Libs: GSAP eases, anime `inOut*`, Motion. **LP + DM.**
|
|
239
|
+
|
|
240
|
+
### Spring physics
|
|
241
|
+
Duration-less, physics-based motion — natural for interactive/hover and anything
|
|
242
|
+
that should feel tactile. Config shape is universal: `{ stiffness, damping, mass }`
|
|
243
|
+
(Motion: `type:"spring", stiffness:300, damping:30`; react-spring: `config.gentle`).
|
|
244
|
+
Libs: Motion `spring`, react-spring, GSAP (via plugins). **DM;** light touch on LP
|
|
245
|
+
(mostly micro-interactions).
|
|
246
|
+
|
|
247
|
+
### Scroll-reveal via IntersectionObserver — never scroll listeners
|
|
248
|
+
Elements rise ~32px and fade over 600–800ms, **once**, when they cross into view.
|
|
249
|
+
Always IntersectionObserver (or a lib that wraps it); never an unthrottled `scroll`
|
|
250
|
+
listener. Engine-neutral baseline (no dependency):
|
|
251
|
+
```js
|
|
252
|
+
const io = new IntersectionObserver((entries) => {
|
|
253
|
+
for (const e of entries) if (e.isIntersecting) {
|
|
254
|
+
e.target.classList.add("in"); // CSS transitions transform+opacity
|
|
255
|
+
io.unobserve(e.target); // once
|
|
256
|
+
}
|
|
257
|
+
}, { threshold: 0.2, rootMargin: "0px 0px -10% 0px" });
|
|
258
|
+
document.querySelectorAll("[data-reveal]").forEach((el) => io.observe(el));
|
|
259
|
+
```
|
|
260
|
+
Libs that embody it: Motion `inView`, AOS (`data-aos` + `once`), GSAP ScrollTrigger
|
|
261
|
+
(`once:true`). **LP (core) + DM.**
|
|
262
|
+
|
|
263
|
+
### Stagger
|
|
264
|
+
Sequence a group so items arrive one after another (reading order), stepped
|
|
265
|
+
~60–80ms, capped (~400ms total for menus). Libs: GSAP `stagger`, anime
|
|
266
|
+
`stagger(65,{from:"center"})`, Motion `stagger`. Hand-rolled: per-item
|
|
267
|
+
`transition-delay: calc(var(--i) * 60ms)`. **LP (menu entrance, card grids) + DM.**
|
|
268
|
+
|
|
269
|
+
### SVG draw-on
|
|
270
|
+
Line art draws itself via `stroke-dasharray`/`stroke-dashoffset` animated to 0.
|
|
271
|
+
Libs: Vivus (`type:"oneByOne"`), or pure CSS for a single path. **DM (logos,
|
|
272
|
+
diagrams);** occasional LP hero accent.
|
|
273
|
+
|
|
274
|
+
### Typing
|
|
275
|
+
Rotate/type phrases in a hero. Pattern: type → pause → delete → next, respect
|
|
276
|
+
reduced-motion by rendering the final string. Lib: typed.js (**GPL — reimplement**,
|
|
277
|
+
don't bundle). **LP (hero headline variants) + DM.**
|
|
278
|
+
|
|
279
|
+
### Page transitions + smooth scroll
|
|
280
|
+
Cross-page: animate container out/in instead of a hard reload (barba.js, or a
|
|
281
|
+
framework's view-transitions). Smooth scroll: eased momentum scrolling (lenis),
|
|
282
|
+
commonly paired with scroll-triggered motion (`lenis.raf` → GSAP ScrollTrigger).
|
|
283
|
+
**DM / full-site builds;** a single landing page rarely needs barba. Lenis already
|
|
284
|
+
used by `maggie-clone`.
|
|
285
|
+
|
|
286
|
+
### Particles
|
|
287
|
+
Subtle generative backdrop or confetti. Lib: tsparticles (config: `particles.number`,
|
|
288
|
+
`move`, `background`). Use sparingly; cap count, pause offscreen, kill on
|
|
289
|
+
reduced-motion. **LP hero (optional accent) + DM.**
|
|
290
|
+
|
|
291
|
+
### The Lottie workflow
|
|
292
|
+
Pipeline: **design in After Effects → export with Bodymovin → `.json` →** play with
|
|
293
|
+
**lottie-web** on web / **rlottie** on native (same JSON asset, two renderers).
|
|
294
|
+
```js
|
|
295
|
+
lottie.loadAnimation({ container: el, renderer: "svg", loop: true, autoplay: true, path: "hero.json" });
|
|
296
|
+
```
|
|
297
|
+
**When to use Lottie vs code vs looped video:**
|
|
298
|
+
- **Lottie** — designer-authored vector illustration/icon motion; scalable, crisp,
|
|
299
|
+
small, loopable, recolorable, interactive (segments/speed). The default for
|
|
300
|
+
"animated illustration." Prefer `renderer:"svg"`; use `canvas` for heavy files.
|
|
301
|
+
- **Code (CSS/GSAP/Motion)** — UI motion tied to the DOM: entrances, hovers,
|
|
302
|
+
scroll reveals, state changes. Anything that must respond to layout/interaction.
|
|
303
|
+
- **Looped video (mp4/webm)** — photographic/complex/3D content that isn't vector
|
|
304
|
+
and doesn't need interaction or recolor. Heaviest payload; provide a poster and
|
|
305
|
+
`prefers-reduced-motion` fallback. (See `references/programmatic-video.md`.)
|
|
306
|
+
Libs: lottie-web (web), rlottie (native). **DM (primary);** LP for a hero/spot
|
|
307
|
+
illustration when a designer supplies the JSON.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 3. Performance & accessibility rules (shared by all of them)
|
|
312
|
+
|
|
313
|
+
- **Animate only `transform` and `opacity`.** Never `top`/`left`/`width`/`height`/
|
|
314
|
+
`margin` (they trigger layout/paint and jank). Use `transform: translate/scale`
|
|
315
|
+
for position and size. Prefer the compositor; add `will-change` only on the
|
|
316
|
+
element about to animate, and remove it after.
|
|
317
|
+
- **No scroll/resize listeners for reveal.** Use IntersectionObserver for visibility
|
|
318
|
+
and `requestAnimationFrame` for any per-frame work; throttle/debounce the rest.
|
|
319
|
+
Never run animation logic directly in a `scroll` handler.
|
|
320
|
+
- **Respect `prefers-reduced-motion`.** Replace movement with a plain opacity change
|
|
321
|
+
(or show the final state instantly). Gate every nontrivial effect:
|
|
322
|
+
```css
|
|
323
|
+
@media (prefers-reduced-motion: reduce) {
|
|
324
|
+
*, *::before, *::after { animation-duration:.01ms!important;
|
|
325
|
+
animation-iteration-count:1!important; transition-duration:.01ms!important; }
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
In JS, branch on `matchMedia("(prefers-reduced-motion: reduce)").matches` before
|
|
329
|
+
typing, particles, smooth-scroll, or autoplay loops.
|
|
330
|
+
- **Reveal once; don't re-fire** on scroll-back (`once:true` / `unobserve`).
|
|
331
|
+
- **Pause offscreen / on hidden tab** (Lottie, particles, video): check
|
|
332
|
+
`document.hidden` / IntersectionObserver and stop rAF to save battery/CPU.
|
|
333
|
+
- **Keep durations honest:** entrances 300–800ms; hovers 200–300ms; never block
|
|
334
|
+
interaction or delay content paint behind an animation. Don't animate above the
|
|
335
|
+
fold in a way that hides LCP text.
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## License quick-reference
|
|
340
|
+
|
|
341
|
+
| Library | License | Note |
|
|
342
|
+
|---|---|---|
|
|
343
|
+
| GSAP | Custom "no-charge" | **Not OSI/MIT.** Free (incl. all plugins) but proprietary — flag before bundling. |
|
|
344
|
+
| Motion / framer-motion | MIT | Paid Motion+ add-on optional, not required. |
|
|
345
|
+
| anime.js | MIT | |
|
|
346
|
+
| lottie-web | MIT | |
|
|
347
|
+
| rlottie | MIT | Some vendored parts differ (see COPYING). |
|
|
348
|
+
| theatre.js | Apache-2.0 | |
|
|
349
|
+
| auto-animate | MIT | |
|
|
350
|
+
| AOS | MIT | |
|
|
351
|
+
| typed.js | **GPL** | **Flag — don't bundle in proprietary output; reimplement.** |
|
|
352
|
+
| tsparticles | MIT | |
|
|
353
|
+
| rive-runtime | MIT | Web runtime is `@rive-app/canvas`. |
|
|
354
|
+
| vivus | MIT | |
|
|
355
|
+
| lenis | MIT | |
|
|
356
|
+
| barba.js | MIT | |
|
|
357
|
+
| react-spring | MIT | |
|
|
358
|
+
| animate.css | **Hippocratic 2.1** | **Flag — ethical-source, not OSI. Reimplement keyframes.** |
|
|
359
|
+
| synfig / friction | GPL-3.0 | Desktop authoring tools (category O), not web runtimes. |
|
|
360
|
+
|
|
361
|
+
Most are MIT and safe to reference/learn from freely. The four to flag: **GSAP**
|
|
362
|
+
(proprietary no-charge), **typed.js** (GPL), **animate.css** (Hippocratic 2.1), and
|
|
363
|
+
**synfig/friction** (GPL desktop tools). For the flagged ones we adopt the *pattern*
|
|
364
|
+
and author our own code.
|