unicode-animations 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,405 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/braille.ts
21
+ var braille_exports = {};
22
+ __export(braille_exports, {
23
+ default: () => braille_default,
24
+ gridToBraille: () => gridToBraille,
25
+ makeGrid: () => makeGrid,
26
+ spinners: () => spinners
27
+ });
28
+ module.exports = __toCommonJS(braille_exports);
29
+ var BRAILLE_DOT_MAP = [
30
+ [1, 8],
31
+ // row 0
32
+ [2, 16],
33
+ // row 1
34
+ [4, 32],
35
+ // row 2
36
+ [64, 128]
37
+ // row 3
38
+ ];
39
+ function gridToBraille(grid) {
40
+ const rows = grid.length;
41
+ const cols = grid[0] ? grid[0].length : 0;
42
+ const charCount = Math.ceil(cols / 2);
43
+ let result = "";
44
+ for (let c = 0; c < charCount; c++) {
45
+ let code = 10240;
46
+ for (let r = 0; r < 4 && r < rows; r++) {
47
+ for (let d = 0; d < 2; d++) {
48
+ const col = c * 2 + d;
49
+ if (col < cols && grid[r] && grid[r][col]) {
50
+ code |= BRAILLE_DOT_MAP[r][d];
51
+ }
52
+ }
53
+ }
54
+ result += String.fromCodePoint(code);
55
+ }
56
+ return result;
57
+ }
58
+ function makeGrid(rows, cols) {
59
+ return Array.from({ length: rows }, () => Array(cols).fill(false));
60
+ }
61
+ function genScan() {
62
+ const W = 8, H = 4, frames = [];
63
+ for (let pos = -1; pos < W + 1; pos++) {
64
+ const g = makeGrid(H, W);
65
+ for (let r = 0; r < H; r++) {
66
+ for (let c = 0; c < W; c++) {
67
+ if (c === pos || c === pos - 1) g[r][c] = true;
68
+ }
69
+ }
70
+ frames.push(gridToBraille(g));
71
+ }
72
+ return frames;
73
+ }
74
+ function genRain() {
75
+ const W = 8, H = 4, totalFrames = 12, frames = [];
76
+ const offsets = [0, 3, 1, 5, 2, 7, 4, 6];
77
+ for (let f = 0; f < totalFrames; f++) {
78
+ const g = makeGrid(H, W);
79
+ for (let c = 0; c < W; c++) {
80
+ const row = (f + offsets[c]) % (H + 2);
81
+ if (row < H) g[row][c] = true;
82
+ }
83
+ frames.push(gridToBraille(g));
84
+ }
85
+ return frames;
86
+ }
87
+ function genScanLine() {
88
+ const W = 6, H = 4, frames = [];
89
+ const positions = [0, 1, 2, 3, 2, 1];
90
+ for (const row of positions) {
91
+ const g = makeGrid(H, W);
92
+ for (let c = 0; c < W; c++) {
93
+ g[row][c] = true;
94
+ if (row > 0) g[row - 1][c] = c % 2 === 0;
95
+ }
96
+ frames.push(gridToBraille(g));
97
+ }
98
+ return frames;
99
+ }
100
+ function genPulse() {
101
+ const W = 6, H = 4, frames = [];
102
+ const cx = W / 2 - 0.5, cy = H / 2 - 0.5;
103
+ const radii = [0.5, 1.2, 2, 3, 3.5];
104
+ for (const r of radii) {
105
+ const g = makeGrid(H, W);
106
+ for (let row = 0; row < H; row++) {
107
+ for (let col = 0; col < W; col++) {
108
+ const dist = Math.sqrt((col - cx) ** 2 + (row - cy) ** 2);
109
+ if (Math.abs(dist - r) < 0.9) g[row][col] = true;
110
+ }
111
+ }
112
+ frames.push(gridToBraille(g));
113
+ }
114
+ return frames;
115
+ }
116
+ function genSnake() {
117
+ const W = 4, H = 4;
118
+ const path = [];
119
+ for (let r = 0; r < H; r++) {
120
+ if (r % 2 === 0) {
121
+ for (let c = 0; c < W; c++) path.push([r, c]);
122
+ } else {
123
+ for (let c = W - 1; c >= 0; c--) path.push([r, c]);
124
+ }
125
+ }
126
+ const frames = [];
127
+ for (let i = 0; i < path.length; i++) {
128
+ const g = makeGrid(H, W);
129
+ for (let t = 0; t < 4; t++) {
130
+ const idx = (i - t + path.length) % path.length;
131
+ g[path[idx][0]][path[idx][1]] = true;
132
+ }
133
+ frames.push(gridToBraille(g));
134
+ }
135
+ return frames;
136
+ }
137
+ function genSparkle() {
138
+ const patterns = [
139
+ [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0],
140
+ [0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0],
141
+ [0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1],
142
+ [1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0],
143
+ [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
144
+ [0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0]
145
+ ];
146
+ const W = 8, H = 4, frames = [];
147
+ for (const pat of patterns) {
148
+ const g = makeGrid(H, W);
149
+ for (let r = 0; r < H; r++) {
150
+ for (let c = 0; c < W; c++) {
151
+ g[r][c] = !!pat[r * W + c];
152
+ }
153
+ }
154
+ frames.push(gridToBraille(g));
155
+ }
156
+ return frames;
157
+ }
158
+ function genCascade() {
159
+ const W = 8, H = 4, frames = [];
160
+ for (let offset = -2; offset < W + H; offset++) {
161
+ const g = makeGrid(H, W);
162
+ for (let r = 0; r < H; r++) {
163
+ for (let c = 0; c < W; c++) {
164
+ const diag = c + r;
165
+ if (diag === offset || diag === offset - 1) g[r][c] = true;
166
+ }
167
+ }
168
+ frames.push(gridToBraille(g));
169
+ }
170
+ return frames;
171
+ }
172
+ function genColumns() {
173
+ const W = 6, H = 4, frames = [];
174
+ for (let col = 0; col < W; col++) {
175
+ for (let fillTo = H - 1; fillTo >= 0; fillTo--) {
176
+ const g = makeGrid(H, W);
177
+ for (let pc = 0; pc < col; pc++) {
178
+ for (let r = 0; r < H; r++) g[r][pc] = true;
179
+ }
180
+ for (let r = fillTo; r < H; r++) g[r][col] = true;
181
+ frames.push(gridToBraille(g));
182
+ }
183
+ }
184
+ const full = makeGrid(H, W);
185
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
186
+ frames.push(gridToBraille(full));
187
+ frames.push(gridToBraille(makeGrid(H, W)));
188
+ return frames;
189
+ }
190
+ function genOrbit() {
191
+ const W = 2, H = 4;
192
+ const path = [
193
+ [0, 0],
194
+ [0, 1],
195
+ [1, 1],
196
+ [2, 1],
197
+ [3, 1],
198
+ [3, 0],
199
+ [2, 0],
200
+ [1, 0]
201
+ ];
202
+ const frames = [];
203
+ for (let i = 0; i < path.length; i++) {
204
+ const g = makeGrid(H, W);
205
+ g[path[i][0]][path[i][1]] = true;
206
+ const t1 = (i - 1 + path.length) % path.length;
207
+ g[path[t1][0]][path[t1][1]] = true;
208
+ frames.push(gridToBraille(g));
209
+ }
210
+ return frames;
211
+ }
212
+ function genBreathe() {
213
+ const stages = [
214
+ [],
215
+ [[1, 0]],
216
+ [[0, 1], [2, 0]],
217
+ [[0, 0], [1, 1], [3, 0]],
218
+ [[0, 0], [1, 1], [2, 0], [3, 1]],
219
+ [[0, 0], [0, 1], [1, 1], [2, 0], [3, 1]],
220
+ [[0, 0], [0, 1], [1, 0], [2, 1], [3, 0], [3, 1]],
221
+ [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [3, 0], [3, 1]],
222
+ [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1], [3, 0], [3, 1]]
223
+ ];
224
+ const frames = [];
225
+ const sequence = [...stages, ...stages.slice().reverse().slice(1)];
226
+ for (const dots of sequence) {
227
+ const g = makeGrid(4, 2);
228
+ for (const [r, c] of dots) g[r][c] = true;
229
+ frames.push(gridToBraille(g));
230
+ }
231
+ return frames;
232
+ }
233
+ function genWaveRows() {
234
+ const W = 8, H = 4, totalFrames = 16, frames = [];
235
+ for (let f = 0; f < totalFrames; f++) {
236
+ const g = makeGrid(H, W);
237
+ for (let c = 0; c < W; c++) {
238
+ const phase = f - c * 0.5;
239
+ const row = Math.round((Math.sin(phase * 0.8) + 1) / 2 * (H - 1));
240
+ g[row][c] = true;
241
+ if (row > 0) g[row - 1][c] = (f + c) % 3 === 0;
242
+ }
243
+ frames.push(gridToBraille(g));
244
+ }
245
+ return frames;
246
+ }
247
+ function genCheckerboard() {
248
+ const W = 6, H = 4, frames = [];
249
+ for (let phase = 0; phase < 4; phase++) {
250
+ const g = makeGrid(H, W);
251
+ for (let r = 0; r < H; r++) {
252
+ for (let c = 0; c < W; c++) {
253
+ if (phase < 2) {
254
+ g[r][c] = (r + c + phase) % 2 === 0;
255
+ } else {
256
+ g[r][c] = (r + c + phase) % 3 === 0;
257
+ }
258
+ }
259
+ }
260
+ frames.push(gridToBraille(g));
261
+ }
262
+ return frames;
263
+ }
264
+ function genHelix() {
265
+ const W = 8, H = 4, totalFrames = 16, frames = [];
266
+ for (let f = 0; f < totalFrames; f++) {
267
+ const g = makeGrid(H, W);
268
+ for (let c = 0; c < W; c++) {
269
+ const phase = (f + c) * (Math.PI / 4);
270
+ const y1 = Math.round((Math.sin(phase) + 1) / 2 * (H - 1));
271
+ const y2 = Math.round((Math.sin(phase + Math.PI) + 1) / 2 * (H - 1));
272
+ g[y1][c] = true;
273
+ g[y2][c] = true;
274
+ }
275
+ frames.push(gridToBraille(g));
276
+ }
277
+ return frames;
278
+ }
279
+ function genFillSweep() {
280
+ const W = 4, H = 4, frames = [];
281
+ for (let row = H - 1; row >= 0; row--) {
282
+ const g = makeGrid(H, W);
283
+ for (let r = row; r < H; r++) {
284
+ for (let c = 0; c < W; c++) g[r][c] = true;
285
+ }
286
+ frames.push(gridToBraille(g));
287
+ }
288
+ const full = makeGrid(H, W);
289
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
290
+ frames.push(gridToBraille(full));
291
+ frames.push(gridToBraille(full));
292
+ for (let row = 0; row < H; row++) {
293
+ const g = makeGrid(H, W);
294
+ for (let r = row + 1; r < H; r++) {
295
+ for (let c = 0; c < W; c++) g[r][c] = true;
296
+ }
297
+ frames.push(gridToBraille(g));
298
+ }
299
+ frames.push(gridToBraille(makeGrid(H, W)));
300
+ return frames;
301
+ }
302
+ function genDiagonalSwipe() {
303
+ const W = 4, H = 4, frames = [];
304
+ const maxDiag = W + H - 2;
305
+ for (let d = 0; d <= maxDiag; d++) {
306
+ const g = makeGrid(H, W);
307
+ for (let r = 0; r < H; r++) {
308
+ for (let c = 0; c < W; c++) {
309
+ if (r + c <= d) g[r][c] = true;
310
+ }
311
+ }
312
+ frames.push(gridToBraille(g));
313
+ }
314
+ const full = makeGrid(H, W);
315
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
316
+ frames.push(gridToBraille(full));
317
+ for (let d = 0; d <= maxDiag; d++) {
318
+ const g = makeGrid(H, W);
319
+ for (let r = 0; r < H; r++) {
320
+ for (let c = 0; c < W; c++) {
321
+ if (r + c > d) g[r][c] = true;
322
+ }
323
+ }
324
+ frames.push(gridToBraille(g));
325
+ }
326
+ frames.push(gridToBraille(makeGrid(H, W)));
327
+ return frames;
328
+ }
329
+ var spinners = {
330
+ // === Classic braille single-char ===
331
+ braille: {
332
+ frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"],
333
+ interval: 80
334
+ },
335
+ braillewave: {
336
+ frames: [
337
+ "\u2801\u2802\u2804\u2840\u2880\u2820\u2810\u2808",
338
+ "\u2808\u2801\u2802\u2804\u2840\u2880\u2820\u2810",
339
+ "\u2810\u2808\u2801\u2802\u2804\u2840\u2880\u2820",
340
+ "\u2820\u2810\u2808\u2801\u2802\u2804\u2840\u2880",
341
+ "\u2880\u2820\u2810\u2808\u2801\u2802\u2804\u2840",
342
+ "\u2840\u2880\u2820\u2810\u2808\u2801\u2802\u2804",
343
+ "\u2804\u2840\u2880\u2820\u2810\u2808\u2801\u2802",
344
+ "\u2802\u2804\u2840\u2880\u2820\u2810\u2808\u2801"
345
+ ],
346
+ interval: 100
347
+ },
348
+ dna: {
349
+ frames: [
350
+ "\u280B\u2809\u2819\u281A\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804",
351
+ "\u2819\u281A\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820",
352
+ "\u2839\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820",
353
+ "\u2838\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804",
354
+ "\u283C\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824",
355
+ "\u2834\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834",
356
+ "\u2826\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832",
357
+ "\u2827\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812",
358
+ "\u2807\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802",
359
+ "\u280F\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802",
360
+ "\u280B\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802\u2812",
361
+ "\u2809\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802\u2812\u2832"
362
+ ],
363
+ interval: 80
364
+ },
365
+ // === Generated braille grid animations ===
366
+ scan: { frames: genScan(), interval: 70 },
367
+ rain: { frames: genRain(), interval: 100 },
368
+ scanline: { frames: genScanLine(), interval: 120 },
369
+ pulse: { frames: genPulse(), interval: 180 },
370
+ snake: { frames: genSnake(), interval: 80 },
371
+ sparkle: { frames: genSparkle(), interval: 150 },
372
+ cascade: { frames: genCascade(), interval: 60 },
373
+ columns: { frames: genColumns(), interval: 60 },
374
+ orbit: { frames: genOrbit(), interval: 100 },
375
+ breathe: { frames: genBreathe(), interval: 100 },
376
+ waverows: { frames: genWaveRows(), interval: 90 },
377
+ checkerboard: { frames: genCheckerboard(), interval: 250 },
378
+ helix: { frames: genHelix(), interval: 80 },
379
+ fillsweep: { frames: genFillSweep(), interval: 100 },
380
+ diagswipe: { frames: genDiagonalSwipe(), interval: 60 },
381
+ // === Non-braille classics ===
382
+ arc: {
383
+ frames: ["\u25DC", "\u25E0", "\u25DD", "\u25DE", "\u25E1", "\u25DF"],
384
+ interval: 100
385
+ },
386
+ halfmoon: {
387
+ frames: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
388
+ interval: 180
389
+ },
390
+ line: {
391
+ frames: ["|", "/", "\u2014", "\\"],
392
+ interval: 100
393
+ },
394
+ blocks: {
395
+ frames: ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588", "\u2587", "\u2586", "\u2585", "\u2584", "\u2583", "\u2582"],
396
+ interval: 100
397
+ }
398
+ };
399
+ var braille_default = spinners;
400
+ // Annotate the CommonJS export names for ESM import in node:
401
+ 0 && (module.exports = {
402
+ gridToBraille,
403
+ makeGrid,
404
+ spinners
405
+ });
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Unicode Braille Spinners
3
+ *
4
+ * A collection of animated unicode spinners built on braille characters (U+2800 block).
5
+ * Each braille char is a 2×4 dot grid — these generators compose them into
6
+ * multi-character animated frames for use as loading indicators.
7
+ */
8
+ interface Spinner {
9
+ readonly frames: readonly string[];
10
+ readonly interval: number;
11
+ }
12
+ type BrailleSpinnerName = 'braille' | 'braillewave' | 'dna' | 'scan' | 'rain' | 'scanline' | 'pulse' | 'snake' | 'sparkle' | 'cascade' | 'columns' | 'orbit' | 'breathe' | 'waverows' | 'checkerboard' | 'helix' | 'fillsweep' | 'diagswipe' | 'arc' | 'halfmoon' | 'line' | 'blocks';
13
+ /**
14
+ * Convert a 2D boolean grid into a braille string.
15
+ * grid[row][col] = true means dot is raised.
16
+ * Width must be even (2 dot-columns per braille char).
17
+ */
18
+ declare function gridToBraille(grid: boolean[][]): string;
19
+ /** Create an empty grid of given dimensions */
20
+ declare function makeGrid(rows: number, cols: number): boolean[][];
21
+ declare const spinners: Record<BrailleSpinnerName, Spinner>;
22
+
23
+ export { type BrailleSpinnerName, type Spinner, spinners as default, gridToBraille, makeGrid, spinners };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Unicode Braille Spinners
3
+ *
4
+ * A collection of animated unicode spinners built on braille characters (U+2800 block).
5
+ * Each braille char is a 2×4 dot grid — these generators compose them into
6
+ * multi-character animated frames for use as loading indicators.
7
+ */
8
+ interface Spinner {
9
+ readonly frames: readonly string[];
10
+ readonly interval: number;
11
+ }
12
+ type BrailleSpinnerName = 'braille' | 'braillewave' | 'dna' | 'scan' | 'rain' | 'scanline' | 'pulse' | 'snake' | 'sparkle' | 'cascade' | 'columns' | 'orbit' | 'breathe' | 'waverows' | 'checkerboard' | 'helix' | 'fillsweep' | 'diagswipe' | 'arc' | 'halfmoon' | 'line' | 'blocks';
13
+ /**
14
+ * Convert a 2D boolean grid into a braille string.
15
+ * grid[row][col] = true means dot is raised.
16
+ * Width must be even (2 dot-columns per braille char).
17
+ */
18
+ declare function gridToBraille(grid: boolean[][]): string;
19
+ /** Create an empty grid of given dimensions */
20
+ declare function makeGrid(rows: number, cols: number): boolean[][];
21
+ declare const spinners: Record<BrailleSpinnerName, Spinner>;
22
+
23
+ export { type BrailleSpinnerName, type Spinner, spinners as default, gridToBraille, makeGrid, spinners };
@@ -0,0 +1,12 @@
1
+ import {
2
+ braille_default,
3
+ gridToBraille,
4
+ makeGrid,
5
+ spinners
6
+ } from "./chunk-MLXIK7E7.js";
7
+ export {
8
+ braille_default as default,
9
+ gridToBraille,
10
+ makeGrid,
11
+ spinners
12
+ };
@@ -0,0 +1,379 @@
1
+ // src/braille.ts
2
+ var BRAILLE_DOT_MAP = [
3
+ [1, 8],
4
+ // row 0
5
+ [2, 16],
6
+ // row 1
7
+ [4, 32],
8
+ // row 2
9
+ [64, 128]
10
+ // row 3
11
+ ];
12
+ function gridToBraille(grid) {
13
+ const rows = grid.length;
14
+ const cols = grid[0] ? grid[0].length : 0;
15
+ const charCount = Math.ceil(cols / 2);
16
+ let result = "";
17
+ for (let c = 0; c < charCount; c++) {
18
+ let code = 10240;
19
+ for (let r = 0; r < 4 && r < rows; r++) {
20
+ for (let d = 0; d < 2; d++) {
21
+ const col = c * 2 + d;
22
+ if (col < cols && grid[r] && grid[r][col]) {
23
+ code |= BRAILLE_DOT_MAP[r][d];
24
+ }
25
+ }
26
+ }
27
+ result += String.fromCodePoint(code);
28
+ }
29
+ return result;
30
+ }
31
+ function makeGrid(rows, cols) {
32
+ return Array.from({ length: rows }, () => Array(cols).fill(false));
33
+ }
34
+ function genScan() {
35
+ const W = 8, H = 4, frames = [];
36
+ for (let pos = -1; pos < W + 1; pos++) {
37
+ const g = makeGrid(H, W);
38
+ for (let r = 0; r < H; r++) {
39
+ for (let c = 0; c < W; c++) {
40
+ if (c === pos || c === pos - 1) g[r][c] = true;
41
+ }
42
+ }
43
+ frames.push(gridToBraille(g));
44
+ }
45
+ return frames;
46
+ }
47
+ function genRain() {
48
+ const W = 8, H = 4, totalFrames = 12, frames = [];
49
+ const offsets = [0, 3, 1, 5, 2, 7, 4, 6];
50
+ for (let f = 0; f < totalFrames; f++) {
51
+ const g = makeGrid(H, W);
52
+ for (let c = 0; c < W; c++) {
53
+ const row = (f + offsets[c]) % (H + 2);
54
+ if (row < H) g[row][c] = true;
55
+ }
56
+ frames.push(gridToBraille(g));
57
+ }
58
+ return frames;
59
+ }
60
+ function genScanLine() {
61
+ const W = 6, H = 4, frames = [];
62
+ const positions = [0, 1, 2, 3, 2, 1];
63
+ for (const row of positions) {
64
+ const g = makeGrid(H, W);
65
+ for (let c = 0; c < W; c++) {
66
+ g[row][c] = true;
67
+ if (row > 0) g[row - 1][c] = c % 2 === 0;
68
+ }
69
+ frames.push(gridToBraille(g));
70
+ }
71
+ return frames;
72
+ }
73
+ function genPulse() {
74
+ const W = 6, H = 4, frames = [];
75
+ const cx = W / 2 - 0.5, cy = H / 2 - 0.5;
76
+ const radii = [0.5, 1.2, 2, 3, 3.5];
77
+ for (const r of radii) {
78
+ const g = makeGrid(H, W);
79
+ for (let row = 0; row < H; row++) {
80
+ for (let col = 0; col < W; col++) {
81
+ const dist = Math.sqrt((col - cx) ** 2 + (row - cy) ** 2);
82
+ if (Math.abs(dist - r) < 0.9) g[row][col] = true;
83
+ }
84
+ }
85
+ frames.push(gridToBraille(g));
86
+ }
87
+ return frames;
88
+ }
89
+ function genSnake() {
90
+ const W = 4, H = 4;
91
+ const path = [];
92
+ for (let r = 0; r < H; r++) {
93
+ if (r % 2 === 0) {
94
+ for (let c = 0; c < W; c++) path.push([r, c]);
95
+ } else {
96
+ for (let c = W - 1; c >= 0; c--) path.push([r, c]);
97
+ }
98
+ }
99
+ const frames = [];
100
+ for (let i = 0; i < path.length; i++) {
101
+ const g = makeGrid(H, W);
102
+ for (let t = 0; t < 4; t++) {
103
+ const idx = (i - t + path.length) % path.length;
104
+ g[path[idx][0]][path[idx][1]] = true;
105
+ }
106
+ frames.push(gridToBraille(g));
107
+ }
108
+ return frames;
109
+ }
110
+ function genSparkle() {
111
+ const patterns = [
112
+ [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0],
113
+ [0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0],
114
+ [0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1],
115
+ [1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0],
116
+ [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
117
+ [0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0]
118
+ ];
119
+ const W = 8, H = 4, frames = [];
120
+ for (const pat of patterns) {
121
+ const g = makeGrid(H, W);
122
+ for (let r = 0; r < H; r++) {
123
+ for (let c = 0; c < W; c++) {
124
+ g[r][c] = !!pat[r * W + c];
125
+ }
126
+ }
127
+ frames.push(gridToBraille(g));
128
+ }
129
+ return frames;
130
+ }
131
+ function genCascade() {
132
+ const W = 8, H = 4, frames = [];
133
+ for (let offset = -2; offset < W + H; offset++) {
134
+ const g = makeGrid(H, W);
135
+ for (let r = 0; r < H; r++) {
136
+ for (let c = 0; c < W; c++) {
137
+ const diag = c + r;
138
+ if (diag === offset || diag === offset - 1) g[r][c] = true;
139
+ }
140
+ }
141
+ frames.push(gridToBraille(g));
142
+ }
143
+ return frames;
144
+ }
145
+ function genColumns() {
146
+ const W = 6, H = 4, frames = [];
147
+ for (let col = 0; col < W; col++) {
148
+ for (let fillTo = H - 1; fillTo >= 0; fillTo--) {
149
+ const g = makeGrid(H, W);
150
+ for (let pc = 0; pc < col; pc++) {
151
+ for (let r = 0; r < H; r++) g[r][pc] = true;
152
+ }
153
+ for (let r = fillTo; r < H; r++) g[r][col] = true;
154
+ frames.push(gridToBraille(g));
155
+ }
156
+ }
157
+ const full = makeGrid(H, W);
158
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
159
+ frames.push(gridToBraille(full));
160
+ frames.push(gridToBraille(makeGrid(H, W)));
161
+ return frames;
162
+ }
163
+ function genOrbit() {
164
+ const W = 2, H = 4;
165
+ const path = [
166
+ [0, 0],
167
+ [0, 1],
168
+ [1, 1],
169
+ [2, 1],
170
+ [3, 1],
171
+ [3, 0],
172
+ [2, 0],
173
+ [1, 0]
174
+ ];
175
+ const frames = [];
176
+ for (let i = 0; i < path.length; i++) {
177
+ const g = makeGrid(H, W);
178
+ g[path[i][0]][path[i][1]] = true;
179
+ const t1 = (i - 1 + path.length) % path.length;
180
+ g[path[t1][0]][path[t1][1]] = true;
181
+ frames.push(gridToBraille(g));
182
+ }
183
+ return frames;
184
+ }
185
+ function genBreathe() {
186
+ const stages = [
187
+ [],
188
+ [[1, 0]],
189
+ [[0, 1], [2, 0]],
190
+ [[0, 0], [1, 1], [3, 0]],
191
+ [[0, 0], [1, 1], [2, 0], [3, 1]],
192
+ [[0, 0], [0, 1], [1, 1], [2, 0], [3, 1]],
193
+ [[0, 0], [0, 1], [1, 0], [2, 1], [3, 0], [3, 1]],
194
+ [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [3, 0], [3, 1]],
195
+ [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1], [3, 0], [3, 1]]
196
+ ];
197
+ const frames = [];
198
+ const sequence = [...stages, ...stages.slice().reverse().slice(1)];
199
+ for (const dots of sequence) {
200
+ const g = makeGrid(4, 2);
201
+ for (const [r, c] of dots) g[r][c] = true;
202
+ frames.push(gridToBraille(g));
203
+ }
204
+ return frames;
205
+ }
206
+ function genWaveRows() {
207
+ const W = 8, H = 4, totalFrames = 16, frames = [];
208
+ for (let f = 0; f < totalFrames; f++) {
209
+ const g = makeGrid(H, W);
210
+ for (let c = 0; c < W; c++) {
211
+ const phase = f - c * 0.5;
212
+ const row = Math.round((Math.sin(phase * 0.8) + 1) / 2 * (H - 1));
213
+ g[row][c] = true;
214
+ if (row > 0) g[row - 1][c] = (f + c) % 3 === 0;
215
+ }
216
+ frames.push(gridToBraille(g));
217
+ }
218
+ return frames;
219
+ }
220
+ function genCheckerboard() {
221
+ const W = 6, H = 4, frames = [];
222
+ for (let phase = 0; phase < 4; phase++) {
223
+ const g = makeGrid(H, W);
224
+ for (let r = 0; r < H; r++) {
225
+ for (let c = 0; c < W; c++) {
226
+ if (phase < 2) {
227
+ g[r][c] = (r + c + phase) % 2 === 0;
228
+ } else {
229
+ g[r][c] = (r + c + phase) % 3 === 0;
230
+ }
231
+ }
232
+ }
233
+ frames.push(gridToBraille(g));
234
+ }
235
+ return frames;
236
+ }
237
+ function genHelix() {
238
+ const W = 8, H = 4, totalFrames = 16, frames = [];
239
+ for (let f = 0; f < totalFrames; f++) {
240
+ const g = makeGrid(H, W);
241
+ for (let c = 0; c < W; c++) {
242
+ const phase = (f + c) * (Math.PI / 4);
243
+ const y1 = Math.round((Math.sin(phase) + 1) / 2 * (H - 1));
244
+ const y2 = Math.round((Math.sin(phase + Math.PI) + 1) / 2 * (H - 1));
245
+ g[y1][c] = true;
246
+ g[y2][c] = true;
247
+ }
248
+ frames.push(gridToBraille(g));
249
+ }
250
+ return frames;
251
+ }
252
+ function genFillSweep() {
253
+ const W = 4, H = 4, frames = [];
254
+ for (let row = H - 1; row >= 0; row--) {
255
+ const g = makeGrid(H, W);
256
+ for (let r = row; r < H; r++) {
257
+ for (let c = 0; c < W; c++) g[r][c] = true;
258
+ }
259
+ frames.push(gridToBraille(g));
260
+ }
261
+ const full = makeGrid(H, W);
262
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
263
+ frames.push(gridToBraille(full));
264
+ frames.push(gridToBraille(full));
265
+ for (let row = 0; row < H; row++) {
266
+ const g = makeGrid(H, W);
267
+ for (let r = row + 1; r < H; r++) {
268
+ for (let c = 0; c < W; c++) g[r][c] = true;
269
+ }
270
+ frames.push(gridToBraille(g));
271
+ }
272
+ frames.push(gridToBraille(makeGrid(H, W)));
273
+ return frames;
274
+ }
275
+ function genDiagonalSwipe() {
276
+ const W = 4, H = 4, frames = [];
277
+ const maxDiag = W + H - 2;
278
+ for (let d = 0; d <= maxDiag; d++) {
279
+ const g = makeGrid(H, W);
280
+ for (let r = 0; r < H; r++) {
281
+ for (let c = 0; c < W; c++) {
282
+ if (r + c <= d) g[r][c] = true;
283
+ }
284
+ }
285
+ frames.push(gridToBraille(g));
286
+ }
287
+ const full = makeGrid(H, W);
288
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
289
+ frames.push(gridToBraille(full));
290
+ for (let d = 0; d <= maxDiag; d++) {
291
+ const g = makeGrid(H, W);
292
+ for (let r = 0; r < H; r++) {
293
+ for (let c = 0; c < W; c++) {
294
+ if (r + c > d) g[r][c] = true;
295
+ }
296
+ }
297
+ frames.push(gridToBraille(g));
298
+ }
299
+ frames.push(gridToBraille(makeGrid(H, W)));
300
+ return frames;
301
+ }
302
+ var spinners = {
303
+ // === Classic braille single-char ===
304
+ braille: {
305
+ frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"],
306
+ interval: 80
307
+ },
308
+ braillewave: {
309
+ frames: [
310
+ "\u2801\u2802\u2804\u2840\u2880\u2820\u2810\u2808",
311
+ "\u2808\u2801\u2802\u2804\u2840\u2880\u2820\u2810",
312
+ "\u2810\u2808\u2801\u2802\u2804\u2840\u2880\u2820",
313
+ "\u2820\u2810\u2808\u2801\u2802\u2804\u2840\u2880",
314
+ "\u2880\u2820\u2810\u2808\u2801\u2802\u2804\u2840",
315
+ "\u2840\u2880\u2820\u2810\u2808\u2801\u2802\u2804",
316
+ "\u2804\u2840\u2880\u2820\u2810\u2808\u2801\u2802",
317
+ "\u2802\u2804\u2840\u2880\u2820\u2810\u2808\u2801"
318
+ ],
319
+ interval: 100
320
+ },
321
+ dna: {
322
+ frames: [
323
+ "\u280B\u2809\u2819\u281A\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804",
324
+ "\u2819\u281A\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820",
325
+ "\u2839\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820",
326
+ "\u2838\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804",
327
+ "\u283C\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824",
328
+ "\u2834\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834",
329
+ "\u2826\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832",
330
+ "\u2827\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812",
331
+ "\u2807\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802",
332
+ "\u280F\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802",
333
+ "\u280B\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802\u2812",
334
+ "\u2809\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802\u2812\u2832"
335
+ ],
336
+ interval: 80
337
+ },
338
+ // === Generated braille grid animations ===
339
+ scan: { frames: genScan(), interval: 70 },
340
+ rain: { frames: genRain(), interval: 100 },
341
+ scanline: { frames: genScanLine(), interval: 120 },
342
+ pulse: { frames: genPulse(), interval: 180 },
343
+ snake: { frames: genSnake(), interval: 80 },
344
+ sparkle: { frames: genSparkle(), interval: 150 },
345
+ cascade: { frames: genCascade(), interval: 60 },
346
+ columns: { frames: genColumns(), interval: 60 },
347
+ orbit: { frames: genOrbit(), interval: 100 },
348
+ breathe: { frames: genBreathe(), interval: 100 },
349
+ waverows: { frames: genWaveRows(), interval: 90 },
350
+ checkerboard: { frames: genCheckerboard(), interval: 250 },
351
+ helix: { frames: genHelix(), interval: 80 },
352
+ fillsweep: { frames: genFillSweep(), interval: 100 },
353
+ diagswipe: { frames: genDiagonalSwipe(), interval: 60 },
354
+ // === Non-braille classics ===
355
+ arc: {
356
+ frames: ["\u25DC", "\u25E0", "\u25DD", "\u25DE", "\u25E1", "\u25DF"],
357
+ interval: 100
358
+ },
359
+ halfmoon: {
360
+ frames: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
361
+ interval: 180
362
+ },
363
+ line: {
364
+ frames: ["|", "/", "\u2014", "\\"],
365
+ interval: 100
366
+ },
367
+ blocks: {
368
+ frames: ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588", "\u2587", "\u2586", "\u2585", "\u2584", "\u2583", "\u2582"],
369
+ interval: 100
370
+ }
371
+ };
372
+ var braille_default = spinners;
373
+
374
+ export {
375
+ gridToBraille,
376
+ makeGrid,
377
+ spinners,
378
+ braille_default
379
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ default: () => braille_default,
24
+ gridToBraille: () => gridToBraille,
25
+ makeGrid: () => makeGrid,
26
+ spinners: () => spinners
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/braille.ts
31
+ var BRAILLE_DOT_MAP = [
32
+ [1, 8],
33
+ // row 0
34
+ [2, 16],
35
+ // row 1
36
+ [4, 32],
37
+ // row 2
38
+ [64, 128]
39
+ // row 3
40
+ ];
41
+ function gridToBraille(grid) {
42
+ const rows = grid.length;
43
+ const cols = grid[0] ? grid[0].length : 0;
44
+ const charCount = Math.ceil(cols / 2);
45
+ let result = "";
46
+ for (let c = 0; c < charCount; c++) {
47
+ let code = 10240;
48
+ for (let r = 0; r < 4 && r < rows; r++) {
49
+ for (let d = 0; d < 2; d++) {
50
+ const col = c * 2 + d;
51
+ if (col < cols && grid[r] && grid[r][col]) {
52
+ code |= BRAILLE_DOT_MAP[r][d];
53
+ }
54
+ }
55
+ }
56
+ result += String.fromCodePoint(code);
57
+ }
58
+ return result;
59
+ }
60
+ function makeGrid(rows, cols) {
61
+ return Array.from({ length: rows }, () => Array(cols).fill(false));
62
+ }
63
+ function genScan() {
64
+ const W = 8, H = 4, frames = [];
65
+ for (let pos = -1; pos < W + 1; pos++) {
66
+ const g = makeGrid(H, W);
67
+ for (let r = 0; r < H; r++) {
68
+ for (let c = 0; c < W; c++) {
69
+ if (c === pos || c === pos - 1) g[r][c] = true;
70
+ }
71
+ }
72
+ frames.push(gridToBraille(g));
73
+ }
74
+ return frames;
75
+ }
76
+ function genRain() {
77
+ const W = 8, H = 4, totalFrames = 12, frames = [];
78
+ const offsets = [0, 3, 1, 5, 2, 7, 4, 6];
79
+ for (let f = 0; f < totalFrames; f++) {
80
+ const g = makeGrid(H, W);
81
+ for (let c = 0; c < W; c++) {
82
+ const row = (f + offsets[c]) % (H + 2);
83
+ if (row < H) g[row][c] = true;
84
+ }
85
+ frames.push(gridToBraille(g));
86
+ }
87
+ return frames;
88
+ }
89
+ function genScanLine() {
90
+ const W = 6, H = 4, frames = [];
91
+ const positions = [0, 1, 2, 3, 2, 1];
92
+ for (const row of positions) {
93
+ const g = makeGrid(H, W);
94
+ for (let c = 0; c < W; c++) {
95
+ g[row][c] = true;
96
+ if (row > 0) g[row - 1][c] = c % 2 === 0;
97
+ }
98
+ frames.push(gridToBraille(g));
99
+ }
100
+ return frames;
101
+ }
102
+ function genPulse() {
103
+ const W = 6, H = 4, frames = [];
104
+ const cx = W / 2 - 0.5, cy = H / 2 - 0.5;
105
+ const radii = [0.5, 1.2, 2, 3, 3.5];
106
+ for (const r of radii) {
107
+ const g = makeGrid(H, W);
108
+ for (let row = 0; row < H; row++) {
109
+ for (let col = 0; col < W; col++) {
110
+ const dist = Math.sqrt((col - cx) ** 2 + (row - cy) ** 2);
111
+ if (Math.abs(dist - r) < 0.9) g[row][col] = true;
112
+ }
113
+ }
114
+ frames.push(gridToBraille(g));
115
+ }
116
+ return frames;
117
+ }
118
+ function genSnake() {
119
+ const W = 4, H = 4;
120
+ const path = [];
121
+ for (let r = 0; r < H; r++) {
122
+ if (r % 2 === 0) {
123
+ for (let c = 0; c < W; c++) path.push([r, c]);
124
+ } else {
125
+ for (let c = W - 1; c >= 0; c--) path.push([r, c]);
126
+ }
127
+ }
128
+ const frames = [];
129
+ for (let i = 0; i < path.length; i++) {
130
+ const g = makeGrid(H, W);
131
+ for (let t = 0; t < 4; t++) {
132
+ const idx = (i - t + path.length) % path.length;
133
+ g[path[idx][0]][path[idx][1]] = true;
134
+ }
135
+ frames.push(gridToBraille(g));
136
+ }
137
+ return frames;
138
+ }
139
+ function genSparkle() {
140
+ const patterns = [
141
+ [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0],
142
+ [0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0],
143
+ [0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1],
144
+ [1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0],
145
+ [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1],
146
+ [0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0]
147
+ ];
148
+ const W = 8, H = 4, frames = [];
149
+ for (const pat of patterns) {
150
+ const g = makeGrid(H, W);
151
+ for (let r = 0; r < H; r++) {
152
+ for (let c = 0; c < W; c++) {
153
+ g[r][c] = !!pat[r * W + c];
154
+ }
155
+ }
156
+ frames.push(gridToBraille(g));
157
+ }
158
+ return frames;
159
+ }
160
+ function genCascade() {
161
+ const W = 8, H = 4, frames = [];
162
+ for (let offset = -2; offset < W + H; offset++) {
163
+ const g = makeGrid(H, W);
164
+ for (let r = 0; r < H; r++) {
165
+ for (let c = 0; c < W; c++) {
166
+ const diag = c + r;
167
+ if (diag === offset || diag === offset - 1) g[r][c] = true;
168
+ }
169
+ }
170
+ frames.push(gridToBraille(g));
171
+ }
172
+ return frames;
173
+ }
174
+ function genColumns() {
175
+ const W = 6, H = 4, frames = [];
176
+ for (let col = 0; col < W; col++) {
177
+ for (let fillTo = H - 1; fillTo >= 0; fillTo--) {
178
+ const g = makeGrid(H, W);
179
+ for (let pc = 0; pc < col; pc++) {
180
+ for (let r = 0; r < H; r++) g[r][pc] = true;
181
+ }
182
+ for (let r = fillTo; r < H; r++) g[r][col] = true;
183
+ frames.push(gridToBraille(g));
184
+ }
185
+ }
186
+ const full = makeGrid(H, W);
187
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
188
+ frames.push(gridToBraille(full));
189
+ frames.push(gridToBraille(makeGrid(H, W)));
190
+ return frames;
191
+ }
192
+ function genOrbit() {
193
+ const W = 2, H = 4;
194
+ const path = [
195
+ [0, 0],
196
+ [0, 1],
197
+ [1, 1],
198
+ [2, 1],
199
+ [3, 1],
200
+ [3, 0],
201
+ [2, 0],
202
+ [1, 0]
203
+ ];
204
+ const frames = [];
205
+ for (let i = 0; i < path.length; i++) {
206
+ const g = makeGrid(H, W);
207
+ g[path[i][0]][path[i][1]] = true;
208
+ const t1 = (i - 1 + path.length) % path.length;
209
+ g[path[t1][0]][path[t1][1]] = true;
210
+ frames.push(gridToBraille(g));
211
+ }
212
+ return frames;
213
+ }
214
+ function genBreathe() {
215
+ const stages = [
216
+ [],
217
+ [[1, 0]],
218
+ [[0, 1], [2, 0]],
219
+ [[0, 0], [1, 1], [3, 0]],
220
+ [[0, 0], [1, 1], [2, 0], [3, 1]],
221
+ [[0, 0], [0, 1], [1, 1], [2, 0], [3, 1]],
222
+ [[0, 0], [0, 1], [1, 0], [2, 1], [3, 0], [3, 1]],
223
+ [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [3, 0], [3, 1]],
224
+ [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1], [3, 0], [3, 1]]
225
+ ];
226
+ const frames = [];
227
+ const sequence = [...stages, ...stages.slice().reverse().slice(1)];
228
+ for (const dots of sequence) {
229
+ const g = makeGrid(4, 2);
230
+ for (const [r, c] of dots) g[r][c] = true;
231
+ frames.push(gridToBraille(g));
232
+ }
233
+ return frames;
234
+ }
235
+ function genWaveRows() {
236
+ const W = 8, H = 4, totalFrames = 16, frames = [];
237
+ for (let f = 0; f < totalFrames; f++) {
238
+ const g = makeGrid(H, W);
239
+ for (let c = 0; c < W; c++) {
240
+ const phase = f - c * 0.5;
241
+ const row = Math.round((Math.sin(phase * 0.8) + 1) / 2 * (H - 1));
242
+ g[row][c] = true;
243
+ if (row > 0) g[row - 1][c] = (f + c) % 3 === 0;
244
+ }
245
+ frames.push(gridToBraille(g));
246
+ }
247
+ return frames;
248
+ }
249
+ function genCheckerboard() {
250
+ const W = 6, H = 4, frames = [];
251
+ for (let phase = 0; phase < 4; phase++) {
252
+ const g = makeGrid(H, W);
253
+ for (let r = 0; r < H; r++) {
254
+ for (let c = 0; c < W; c++) {
255
+ if (phase < 2) {
256
+ g[r][c] = (r + c + phase) % 2 === 0;
257
+ } else {
258
+ g[r][c] = (r + c + phase) % 3 === 0;
259
+ }
260
+ }
261
+ }
262
+ frames.push(gridToBraille(g));
263
+ }
264
+ return frames;
265
+ }
266
+ function genHelix() {
267
+ const W = 8, H = 4, totalFrames = 16, frames = [];
268
+ for (let f = 0; f < totalFrames; f++) {
269
+ const g = makeGrid(H, W);
270
+ for (let c = 0; c < W; c++) {
271
+ const phase = (f + c) * (Math.PI / 4);
272
+ const y1 = Math.round((Math.sin(phase) + 1) / 2 * (H - 1));
273
+ const y2 = Math.round((Math.sin(phase + Math.PI) + 1) / 2 * (H - 1));
274
+ g[y1][c] = true;
275
+ g[y2][c] = true;
276
+ }
277
+ frames.push(gridToBraille(g));
278
+ }
279
+ return frames;
280
+ }
281
+ function genFillSweep() {
282
+ const W = 4, H = 4, frames = [];
283
+ for (let row = H - 1; row >= 0; row--) {
284
+ const g = makeGrid(H, W);
285
+ for (let r = row; r < H; r++) {
286
+ for (let c = 0; c < W; c++) g[r][c] = true;
287
+ }
288
+ frames.push(gridToBraille(g));
289
+ }
290
+ const full = makeGrid(H, W);
291
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
292
+ frames.push(gridToBraille(full));
293
+ frames.push(gridToBraille(full));
294
+ for (let row = 0; row < H; row++) {
295
+ const g = makeGrid(H, W);
296
+ for (let r = row + 1; r < H; r++) {
297
+ for (let c = 0; c < W; c++) g[r][c] = true;
298
+ }
299
+ frames.push(gridToBraille(g));
300
+ }
301
+ frames.push(gridToBraille(makeGrid(H, W)));
302
+ return frames;
303
+ }
304
+ function genDiagonalSwipe() {
305
+ const W = 4, H = 4, frames = [];
306
+ const maxDiag = W + H - 2;
307
+ for (let d = 0; d <= maxDiag; d++) {
308
+ const g = makeGrid(H, W);
309
+ for (let r = 0; r < H; r++) {
310
+ for (let c = 0; c < W; c++) {
311
+ if (r + c <= d) g[r][c] = true;
312
+ }
313
+ }
314
+ frames.push(gridToBraille(g));
315
+ }
316
+ const full = makeGrid(H, W);
317
+ for (let r = 0; r < H; r++) for (let c = 0; c < W; c++) full[r][c] = true;
318
+ frames.push(gridToBraille(full));
319
+ for (let d = 0; d <= maxDiag; d++) {
320
+ const g = makeGrid(H, W);
321
+ for (let r = 0; r < H; r++) {
322
+ for (let c = 0; c < W; c++) {
323
+ if (r + c > d) g[r][c] = true;
324
+ }
325
+ }
326
+ frames.push(gridToBraille(g));
327
+ }
328
+ frames.push(gridToBraille(makeGrid(H, W)));
329
+ return frames;
330
+ }
331
+ var spinners = {
332
+ // === Classic braille single-char ===
333
+ braille: {
334
+ frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"],
335
+ interval: 80
336
+ },
337
+ braillewave: {
338
+ frames: [
339
+ "\u2801\u2802\u2804\u2840\u2880\u2820\u2810\u2808",
340
+ "\u2808\u2801\u2802\u2804\u2840\u2880\u2820\u2810",
341
+ "\u2810\u2808\u2801\u2802\u2804\u2840\u2880\u2820",
342
+ "\u2820\u2810\u2808\u2801\u2802\u2804\u2840\u2880",
343
+ "\u2880\u2820\u2810\u2808\u2801\u2802\u2804\u2840",
344
+ "\u2840\u2880\u2820\u2810\u2808\u2801\u2802\u2804",
345
+ "\u2804\u2840\u2880\u2820\u2810\u2808\u2801\u2802",
346
+ "\u2802\u2804\u2840\u2880\u2820\u2810\u2808\u2801"
347
+ ],
348
+ interval: 100
349
+ },
350
+ dna: {
351
+ frames: [
352
+ "\u280B\u2809\u2819\u281A\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804",
353
+ "\u2819\u281A\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820",
354
+ "\u2839\u2812\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820",
355
+ "\u2838\u2802\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804",
356
+ "\u283C\u2802\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824",
357
+ "\u2834\u2812\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834",
358
+ "\u2826\u2832\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832",
359
+ "\u2827\u2834\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812",
360
+ "\u2807\u2824\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802",
361
+ "\u280F\u2804\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802",
362
+ "\u280B\u2804\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802\u2812",
363
+ "\u2809\u2820\u2820\u2804\u2824\u2834\u2832\u2812\u2802\u2802\u2812\u2832"
364
+ ],
365
+ interval: 80
366
+ },
367
+ // === Generated braille grid animations ===
368
+ scan: { frames: genScan(), interval: 70 },
369
+ rain: { frames: genRain(), interval: 100 },
370
+ scanline: { frames: genScanLine(), interval: 120 },
371
+ pulse: { frames: genPulse(), interval: 180 },
372
+ snake: { frames: genSnake(), interval: 80 },
373
+ sparkle: { frames: genSparkle(), interval: 150 },
374
+ cascade: { frames: genCascade(), interval: 60 },
375
+ columns: { frames: genColumns(), interval: 60 },
376
+ orbit: { frames: genOrbit(), interval: 100 },
377
+ breathe: { frames: genBreathe(), interval: 100 },
378
+ waverows: { frames: genWaveRows(), interval: 90 },
379
+ checkerboard: { frames: genCheckerboard(), interval: 250 },
380
+ helix: { frames: genHelix(), interval: 80 },
381
+ fillsweep: { frames: genFillSweep(), interval: 100 },
382
+ diagswipe: { frames: genDiagonalSwipe(), interval: 60 },
383
+ // === Non-braille classics ===
384
+ arc: {
385
+ frames: ["\u25DC", "\u25E0", "\u25DD", "\u25DE", "\u25E1", "\u25DF"],
386
+ interval: 100
387
+ },
388
+ halfmoon: {
389
+ frames: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
390
+ interval: 180
391
+ },
392
+ line: {
393
+ frames: ["|", "/", "\u2014", "\\"],
394
+ interval: 100
395
+ },
396
+ blocks: {
397
+ frames: ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588", "\u2587", "\u2586", "\u2585", "\u2584", "\u2583", "\u2582"],
398
+ interval: 100
399
+ }
400
+ };
401
+ var braille_default = spinners;
402
+ // Annotate the CommonJS export names for ESM import in node:
403
+ 0 && (module.exports = {
404
+ gridToBraille,
405
+ makeGrid,
406
+ spinners
407
+ });
@@ -0,0 +1 @@
1
+ export { BrailleSpinnerName, Spinner, default, gridToBraille, makeGrid, default as spinners } from './braille.cjs';
@@ -0,0 +1 @@
1
+ export { BrailleSpinnerName, Spinner, default, gridToBraille, makeGrid, default as spinners } from './braille.js';
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ braille_default,
3
+ gridToBraille,
4
+ makeGrid,
5
+ spinners
6
+ } from "./chunk-MLXIK7E7.js";
7
+ export {
8
+ braille_default as default,
9
+ gridToBraille,
10
+ makeGrid,
11
+ spinners
12
+ };
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "unicode-animations",
3
+ "version": "0.1.0",
4
+ "description": "Unicode spinner animations as raw frame data",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
9
+ "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
10
+ },
11
+ "./braille": {
12
+ "import": { "types": "./dist/braille.d.ts", "default": "./dist/braille.js" },
13
+ "require": { "types": "./dist/braille.d.cts", "default": "./dist/braille.cjs" }
14
+ }
15
+ },
16
+ "main": "./dist/index.cjs",
17
+ "module": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "files": ["dist"],
20
+ "sideEffects": false,
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "keywords": ["braille", "spinner", "unicode", "animation", "loading", "cli", "terminal"],
26
+ "license": "MIT",
27
+ "devDependencies": {
28
+ "tsup": "^8.4.0",
29
+ "typescript": "^5.7.0"
30
+ }
31
+ }