pa_encoder 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -135
  3. package/package.json +2 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yongpa Han
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,191 +1,139 @@
1
- # pa_encoder
1
+ HTML canvas frame encoder made for personal use (ツ)
2
2
 
3
- pa_encoder는 브라우저에서 실행되는 canvas 기반 스케치/애니메이션을 **프레임 이미지(PNG)로 추출**하는 인코더입니다.
4
-
5
- Live(실시간) 캡처와 Frame(결정적/정밀) 캡처를 모두 지원하며, **DOM에 `<canvas>`가 존재하는 모든 웹 프로젝트**에서 사용할 수 있습니다.
6
-
7
- ---
8
-
9
- pa_encoder is an encoder that **extracts browser-based canvas sketches and animations into image frames (PNG)**.
10
-
11
- It supports both **Live (realtime) capture** and **Frame (deterministic) capture**, and can be used with **any web project that renders to a DOM `<canvas>`**.
12
-
13
- ---
14
-
15
- ### 핵심 개념
16
-
17
- - **Live mode (realtime)**
18
- 실제 브라우저 렌더 루프를 그대로 기록합니다. 마우스/키보드 등 **실시간 인터랙션**이 결과에 반영됩니다.
19
- 성능 저하나 프레임 드랍도 “있는 그대로” 기록됩니다.
20
-
21
- - **Frame mode (deterministic)**
22
- 가상 시간(virtual time)을 사용해 `fps`와 `frames`에 맞춰 **프레임을 정확히 step**합니다.
23
- `Date.now`, `performance.now`, `requestAnimationFrame`, timer를 훅하여 `deltaTime` 기반 애니메이션을 **정밀하게 재현**합니다.
24
- 동일한 설정/초기 상태에서 **항상 동일한 결과**를 목표로 합니다.
25
-
26
- ### 설치
3
+ # Installation
27
4
 
28
5
  ```bash
29
6
  npm install pa_encoder
30
7
  ```
31
8
 
32
- 또는
33
-
34
- ```bash
35
- pnpm add pa_encoder
36
- ```
37
-
38
- ### 빠른 시작
9
+ Provides:
39
10
 
40
- 프로젝트 루트에서 실행:
11
+ - JavaScript API (ES module)
12
+ - CLI tool (`pa_encoder`)
41
13
 
42
- ```bash
43
- npx pa_encoder
44
- ```
45
-
46
- 기본 가정:
14
+ ---
47
15
 
48
- - dev 서버: http://localhost:5173
49
- - entry 파일: /src/main.js
16
+ # Usage
50
17
 
51
- 브라우저가 열리며 encoder UI가 표시됩니다.
18
+ ## CLI (recommended)
52
19
 
53
- ### CLI 옵션
20
+ Starts a local proxy server and opens a browser UI.
54
21
 
55
22
  ```bash
56
- npx pa_encoder --url <dev_server_url> --entry <entry_path> --port <ui_port>
23
+ pa_encoder --url http://localhost:5173 --entry /src/main.js
57
24
  ```
58
25
 
59
- 예시:
26
+ ### Options
60
27
 
61
- ```bash
62
- npx pa_encoder --url http://localhost:3000 --entry /src/sketch.js
63
- ```
28
+ - `--url` Target site URL
29
+ - `--entry` Entry script imported in preview iframe
30
+ - `--port` UI server port (default: `8787`)
64
31
 
65
- ### UI 사용 방법
32
+ The UI shows a live preview, capture controls, and progress logs.
66
33
 
67
- 1. **Entry**에 스케치 엔트리 파일 경로를 입력합니다(예: `/src/main.js`).
68
- 2. **Mode**를 선택합니다.
69
- - Live: 실시간 인터랙션 포함 캡처
70
- - Frame: fps/frames 기반 정밀 캡처
71
- 3. **Canvas**에서 캡처할 캔버스를 선택합니다(기본: auto).
72
- 4. **Start**로 시작, **Stop**으로 종료합니다.
34
+ ---
73
35
 
74
- #### 키보드 인터랙션과 단축키 동작
36
+ ## JavaScript API
75
37
 
76
- - 녹화 **시작 (Idle)** 에는 UI 단축키가 동작합니다.
77
- - `H`: UI 숨김
78
- - `P`: Passthrough 토글
79
- - `C`: Compact 토글
80
- - `D`: Dock 위치 변경
81
- - `Space`: Start
82
- - 녹화 **진행 중(Running)** 에는 UI가 키보드를 가로채지 않습니다.
83
- 즉, 키 입력이 스케치(캔버스) 쪽으로 들어가도록 설계되어 있습니다.
84
- 필요 시 `Focus Sketch` 버튼을 누른 뒤 캔버스를 한 번 클릭하면 포커스가 확실해집니다(브라우저 정책에 따라 자동 포커스가 제한될 수 있음).
38
+ ### Live capture (real-time)
85
39
 
86
- ### Exporter
40
+ ```js
41
+ import { startLiveCapture, createZipExporter } from "pa_encoder";
87
42
 
88
- - **ZIP (download)**: 프레임 PNG를 ZIP으로 묶어 다운로드
89
- - **FS (directory)**: File System Access API로 디렉토리에 저장
90
- - **Best (auto)**: 환경에 맞춰 ZIP 또는 FS 자동 선택
43
+ const canvas = document.querySelector("canvas");
44
+ const exporter = await createZipExporter({ zipName: "frames.zip" });
91
45
 
92
- ### 지원 범위 / 제한 사항
46
+ const { stop } = await startLiveCapture({
47
+ canvas,
48
+ exporter,
49
+ fps: 30,
50
+ });
93
51
 
94
- - DOM에 붙어 있는 `<canvas>`만 캡처합니다.
95
- - WebGL FBO/render target 텍스처를 “직접 선택”해 인코딩하는 기능은 없습니다.
96
- 오프스크린 결과를 화면 canvas로 출력하면 캡처 가능합니다.
97
- - OffscreenCanvas + Worker 렌더링은 Live에서는 동작할 수 있으나, Frame에서 결정성을 보장하지 않습니다.
98
- - cross-origin 이미지/비디오 등을 CORS 설정 없이 텍스처로 사용하면 canvas가 tainted 되어 `toBlob()` 캡처가 실패할 수 있습니다.
52
+ await stop();
53
+ ```
99
54
 
100
55
  ---
101
56
 
102
- ### Core Ideas
57
+ ### Deterministic frame capture (virtual time)
103
58
 
104
- - **Live mode (realtime)**
105
- Records the canvas as it is rendered in real time, including **mouse/keyboard interaction**.
106
- Performance drops and frame skips are captured as-is.
59
+ ```js
60
+ import { virtualTimeCaptureFromStart, createZipExporter } from "pa_encoder";
107
61
 
108
- - **Frame mode (deterministic)**
109
- Uses virtual time and advances frames in fixed steps according to `fps` and `frames`.
110
- Hooks `Date.now`, `performance.now`, `requestAnimationFrame`, and timers to reproduce **deltaTime-based animation** precisely.
111
- With the same code/settings/initial state, it aims to produce **reproducible output**.
62
+ const exporter = await createZipExporter({ zipName: "frames.zip" });
112
63
 
113
- ### Installation
64
+ await virtualTimeCaptureFromStart({
65
+ fps: 60,
66
+ frameCount: 300,
67
+ start: async () => {
68
+ await import("/src/main.js");
69
+ },
70
+ onFrame: async (canvas, i) => {
71
+ const blob = await new Promise((r) => canvas.toBlob(r, "image/png"));
72
+ await exporter.write(i, blob);
73
+ },
74
+ });
114
75
 
115
- ```bash
116
- npm install pa_encoder
76
+ await exporter.finalize();
117
77
  ```
118
78
 
119
- Or:
79
+ Hooks `requestAnimationFrame`, time APIs, and timers to ensure deterministic output.
120
80
 
121
- ```bash
122
- pnpm add pa_encoder
123
- ```
81
+ ---
124
82
 
125
- ### Quick Start
83
+ ## Exporters
126
84
 
127
- Run from your project root:
85
+ All exporters share the same interface:
128
86
 
129
- ```bash
130
- npx pa_encoder
87
+ ```ts
88
+ {
89
+ write(frameIndex, blob);
90
+ finalize();
91
+ }
131
92
  ```
132
93
 
133
- Default assumptions:
134
-
135
- - dev server: http://localhost:5173
136
- - entry file: /src/main.js
94
+ ### ZIP exporter
137
95
 
138
- The encoder UI opens in your browser.
96
+ ```js
97
+ import { createZipExporter } from "pa_encoder";
98
+ await createZipExporter({ zipName: "frames.zip" });
99
+ ```
139
100
 
140
- ### CLI Options
101
+ Downloads a ZIP of PNG frames.
141
102
 
142
- ```bash
143
- npx pa_encoder --url <dev_server_url> --entry <entry_path> --port <ui_port>
144
- ```
103
+ ---
145
104
 
146
- Example:
105
+ ### File System exporter (Chromium)
147
106
 
148
- ```bash
149
- npx pa_encoder --url http://localhost:3000 --entry /src/sketch.js
107
+ ```js
108
+ import { createFsExporter } from "pa_encoder";
109
+ await createFsExporter({ dirNameHint: "frames" });
150
110
  ```
151
111
 
152
- ### UI Usage
112
+ Writes directly to a directory (secure context required).
153
113
 
154
- 1. Set **Entry** (e.g. `/src/main.js`).
155
- 2. Choose **Mode**:
156
- - Live: realtime capture with interaction
157
- - Frame: deterministic capture by fps/frames
158
- 3. Select **Canvas** (default: auto).
159
- 4. Click **Start** to begin and **Stop** to finish.
114
+ ---
160
115
 
161
- #### Keyboard interaction vs hotkeys
116
+ ### Best exporter
162
117
 
163
- - When **Idle (not recording)**, UI hotkeys work:
164
- - `H`: hide UI
165
- - `P`: toggle passthrough
166
- - `C`: toggle compact
167
- - `D`: change dock position
168
- - `Space`: start
169
- - When **Running (recording)**, the UI does not consume keyboard events.
170
- This is intended to keep keyboard input going to the sketch/canvas.
171
- If focus is not acquired automatically (browser-dependent), click `Focus Sketch` and then click the canvas once.
118
+ ```js
119
+ import { createBestExporter } from "pa_encoder";
120
+ await createBestExporter({ prefer: "fs" });
121
+ ```
172
122
 
173
- ### Exporters
123
+ Uses File System export when available, otherwise ZIP.
174
124
 
175
- - **ZIP (download)**: bundles PNG frames into a ZIP file
176
- - **FS (directory)**: writes files via the File System Access API
177
- - **Best (auto)**: chooses ZIP or FS depending on the environment
125
+ ---
178
126
 
179
- ### Notes and Limitations
127
+ ## Supported Environments
180
128
 
181
- - Only DOM-attached `<canvas>` elements can be captured.
182
- - Direct selection/encoding of WebGL FBO/render-target textures is not supported.
183
- If the result is drawn to a visible canvas, it can be captured.
184
- - OffscreenCanvas + Worker rendering may work in Live mode, but deterministic behavior is not guaranteed in Frame mode.
185
- - Cross-origin media without proper CORS headers can taint the canvas and make `toBlob()` fail.
129
+ - Modern Chromium-based browsers recommended
130
+ - Requires:
131
+ - ES module Web Workers
132
+ - `OffscreenCanvas`
133
+ - `createImageBitmap`
134
+ - ZIP export works in most modern browsers
135
+ - File System export requires Chromium + secure context
186
136
 
187
137
  ---
188
138
 
189
- ## License
190
-
191
- MIT
139
+ (ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)(ツ)
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "pa_encoder",
3
- "version": "0.2.1",
3
+ "license": "MIT",
4
+ "version": "0.2.3",
4
5
  "type": "module",
5
6
  "sideEffects": false,
6
7
  "files": [