@jyiro/ascii-script 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.
- package/LICENSE +21 -0
- package/README.md +669 -0
- package/dist/ascii-art-DCOQt4Se.js +285 -0
- package/dist/ascii-script.js +892 -0
- package/dist/procedural-BY9bCgT3.js +66 -0
- package/dist/text-CKJIlRsq.js +262 -0
- package/package.json +49 -0
|
@@ -0,0 +1,892 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
9
|
+
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
10
|
+
set _(value) {
|
|
11
|
+
__privateSet(obj, member, value, setter);
|
|
12
|
+
},
|
|
13
|
+
get _() {
|
|
14
|
+
return __privateGet(obj, member, getter);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
var _instances, _running, _rafId, _lastTime, _loop, _instances2, _nextId, _id, _element, _active, _effects, _startTime, _callbacks, _BaseInstance_instances, trigger_fn, _originalText, _currentText, _effectChain, _renderMode, _threshold, _canvas, _ctx, _TextBlock_instances, setup_fn, setupCanvas_fn, updateDOM_fn, renderCanvas_fn, _canvas2, _ctx2, _cols, _rows, _charset, _cellWidth, _cellHeight, _grid, _generator, _CanvasGrid_instances, setup_fn2, _defaultGenerator, valueToChar_fn, _engine, _registry, _autoStart, _block, _asciiFX, _grid2, _asciiFX2;
|
|
18
|
+
class Engine {
|
|
19
|
+
constructor() {
|
|
20
|
+
__privateAdd(this, _instances, /* @__PURE__ */ new Map());
|
|
21
|
+
__privateAdd(this, _running, false);
|
|
22
|
+
__privateAdd(this, _rafId, null);
|
|
23
|
+
__privateAdd(this, _lastTime, 0);
|
|
24
|
+
/**
|
|
25
|
+
* Main render loop
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
__privateAdd(this, _loop, () => {
|
|
29
|
+
if (!__privateGet(this, _running)) return;
|
|
30
|
+
const time = performance.now();
|
|
31
|
+
const delta = time - __privateGet(this, _lastTime);
|
|
32
|
+
__privateSet(this, _lastTime, time);
|
|
33
|
+
for (const instance of __privateGet(this, _instances).values()) {
|
|
34
|
+
if (instance.active) {
|
|
35
|
+
instance.update(time, delta);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
__privateSet(this, _rafId, requestAnimationFrame(__privateGet(this, _loop)));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register an instance to be updated each frame
|
|
43
|
+
* @param {string} id - Unique instance identifier
|
|
44
|
+
* @param {Object} instance - Instance with update() method
|
|
45
|
+
*/
|
|
46
|
+
register(id, instance) {
|
|
47
|
+
__privateGet(this, _instances).set(id, instance);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Unregister an instance
|
|
51
|
+
* @param {string} id - Instance identifier
|
|
52
|
+
*/
|
|
53
|
+
unregister(id) {
|
|
54
|
+
__privateGet(this, _instances).delete(id);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Start the rendering loop
|
|
58
|
+
*/
|
|
59
|
+
start() {
|
|
60
|
+
if (__privateGet(this, _running)) return;
|
|
61
|
+
__privateSet(this, _running, true);
|
|
62
|
+
__privateSet(this, _lastTime, performance.now());
|
|
63
|
+
__privateGet(this, _loop).call(this);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Stop the rendering loop
|
|
67
|
+
*/
|
|
68
|
+
stop() {
|
|
69
|
+
__privateSet(this, _running, false);
|
|
70
|
+
if (__privateGet(this, _rafId)) {
|
|
71
|
+
cancelAnimationFrame(__privateGet(this, _rafId));
|
|
72
|
+
__privateSet(this, _rafId, null);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get instance count
|
|
77
|
+
*/
|
|
78
|
+
get instanceCount() {
|
|
79
|
+
return __privateGet(this, _instances).size;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if engine is running
|
|
83
|
+
*/
|
|
84
|
+
get isRunning() {
|
|
85
|
+
return __privateGet(this, _running);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
_instances = new WeakMap();
|
|
89
|
+
_running = new WeakMap();
|
|
90
|
+
_rafId = new WeakMap();
|
|
91
|
+
_lastTime = new WeakMap();
|
|
92
|
+
_loop = new WeakMap();
|
|
93
|
+
class Registry {
|
|
94
|
+
constructor() {
|
|
95
|
+
__privateAdd(this, _instances2, /* @__PURE__ */ new Map());
|
|
96
|
+
__privateAdd(this, _nextId, 1);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create a new instance ID
|
|
100
|
+
* @param {string} prefix - Instance prefix (e.g., 'text', 'grid')
|
|
101
|
+
* @returns {string} Unique instance ID
|
|
102
|
+
*/
|
|
103
|
+
createId(prefix = "instance") {
|
|
104
|
+
return `${prefix}-${__privateWrapper(this, _nextId)._++}`;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Add instance to registry
|
|
108
|
+
* @param {string} id - Instance ID
|
|
109
|
+
* @param {Object} instance - Instance object
|
|
110
|
+
*/
|
|
111
|
+
add(id, instance) {
|
|
112
|
+
__privateGet(this, _instances2).set(id, instance);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get instance by ID
|
|
116
|
+
* @param {string} id - Instance ID
|
|
117
|
+
* @returns {Object|undefined} Instance or undefined
|
|
118
|
+
*/
|
|
119
|
+
get(id) {
|
|
120
|
+
return __privateGet(this, _instances2).get(id);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Remove instance from registry
|
|
124
|
+
* @param {string} id - Instance ID
|
|
125
|
+
* @returns {boolean} True if removed
|
|
126
|
+
*/
|
|
127
|
+
remove(id) {
|
|
128
|
+
return __privateGet(this, _instances2).delete(id);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get all instances
|
|
132
|
+
* @returns {Map} All instances
|
|
133
|
+
*/
|
|
134
|
+
getAll() {
|
|
135
|
+
return new Map(__privateGet(this, _instances2));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Clear all instances
|
|
139
|
+
*/
|
|
140
|
+
clear() {
|
|
141
|
+
__privateGet(this, _instances2).clear();
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get instance count
|
|
145
|
+
*/
|
|
146
|
+
get size() {
|
|
147
|
+
return __privateGet(this, _instances2).size;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
_instances2 = new WeakMap();
|
|
151
|
+
_nextId = new WeakMap();
|
|
152
|
+
class BaseInstance {
|
|
153
|
+
constructor(id, element) {
|
|
154
|
+
__privateAdd(this, _BaseInstance_instances);
|
|
155
|
+
__privateAdd(this, _id);
|
|
156
|
+
__privateAdd(this, _element);
|
|
157
|
+
__privateAdd(this, _active, false);
|
|
158
|
+
__privateAdd(this, _effects, []);
|
|
159
|
+
__privateAdd(this, _startTime, null);
|
|
160
|
+
__privateAdd(this, _callbacks, {});
|
|
161
|
+
__privateSet(this, _id, id);
|
|
162
|
+
__privateSet(this, _element, element);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Update instance each frame
|
|
166
|
+
* @param {number} time - Current time
|
|
167
|
+
* @param {number} delta - Time since last frame
|
|
168
|
+
*/
|
|
169
|
+
update(time, delta) {
|
|
170
|
+
if (!__privateGet(this, _active)) return;
|
|
171
|
+
if (!__privateGet(this, _startTime)) __privateSet(this, _startTime, time);
|
|
172
|
+
this.render(time, delta);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Render method (override in subclasses)
|
|
176
|
+
* @param {number} time - Current time
|
|
177
|
+
* @param {number} delta - Time since last frame
|
|
178
|
+
*/
|
|
179
|
+
render(time, delta) {
|
|
180
|
+
throw new Error("render() must be implemented");
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Play/start instance
|
|
184
|
+
*/
|
|
185
|
+
play() {
|
|
186
|
+
__privateSet(this, _active, true);
|
|
187
|
+
__privateSet(this, _startTime, null);
|
|
188
|
+
__privateMethod(this, _BaseInstance_instances, trigger_fn).call(this, "start");
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Pause instance
|
|
192
|
+
*/
|
|
193
|
+
pause() {
|
|
194
|
+
__privateSet(this, _active, false);
|
|
195
|
+
__privateMethod(this, _BaseInstance_instances, trigger_fn).call(this, "pause");
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Stop and reset instance
|
|
199
|
+
*/
|
|
200
|
+
stop() {
|
|
201
|
+
__privateSet(this, _active, false);
|
|
202
|
+
__privateSet(this, _startTime, null);
|
|
203
|
+
__privateMethod(this, _BaseInstance_instances, trigger_fn).call(this, "stop");
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Add event callback
|
|
207
|
+
* @param {string} event - Event name (start, pause, stop, complete, update)
|
|
208
|
+
* @param {Function} callback - Callback function
|
|
209
|
+
*/
|
|
210
|
+
on(event, callback) {
|
|
211
|
+
if (!__privateGet(this, _callbacks)[event]) {
|
|
212
|
+
__privateGet(this, _callbacks)[event] = [];
|
|
213
|
+
}
|
|
214
|
+
__privateGet(this, _callbacks)[event].push(callback);
|
|
215
|
+
return this;
|
|
216
|
+
}
|
|
217
|
+
// Getters
|
|
218
|
+
get id() {
|
|
219
|
+
return __privateGet(this, _id);
|
|
220
|
+
}
|
|
221
|
+
get element() {
|
|
222
|
+
return __privateGet(this, _element);
|
|
223
|
+
}
|
|
224
|
+
get active() {
|
|
225
|
+
return __privateGet(this, _active);
|
|
226
|
+
}
|
|
227
|
+
get startTime() {
|
|
228
|
+
return __privateGet(this, _startTime);
|
|
229
|
+
}
|
|
230
|
+
get effects() {
|
|
231
|
+
return __privateGet(this, _effects);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
_id = new WeakMap();
|
|
235
|
+
_element = new WeakMap();
|
|
236
|
+
_active = new WeakMap();
|
|
237
|
+
_effects = new WeakMap();
|
|
238
|
+
_startTime = new WeakMap();
|
|
239
|
+
_callbacks = new WeakMap();
|
|
240
|
+
_BaseInstance_instances = new WeakSet();
|
|
241
|
+
/**
|
|
242
|
+
* Trigger event callbacks
|
|
243
|
+
* @private
|
|
244
|
+
*/
|
|
245
|
+
trigger_fn = function(event, data) {
|
|
246
|
+
const callbacks = __privateGet(this, _callbacks)[event] || [];
|
|
247
|
+
callbacks.forEach((cb) => cb(data));
|
|
248
|
+
};
|
|
249
|
+
class TextBlock extends BaseInstance {
|
|
250
|
+
constructor(id, element, config = {}) {
|
|
251
|
+
super(id, element);
|
|
252
|
+
__privateAdd(this, _TextBlock_instances);
|
|
253
|
+
__privateAdd(this, _originalText, "");
|
|
254
|
+
__privateAdd(this, _currentText, "");
|
|
255
|
+
__privateAdd(this, _effectChain, []);
|
|
256
|
+
__privateAdd(this, _renderMode, "auto");
|
|
257
|
+
// 'auto', 'dom', 'canvas'
|
|
258
|
+
__privateAdd(this, _threshold, 100);
|
|
259
|
+
// Line threshold for canvas rendering
|
|
260
|
+
__privateAdd(this, _canvas, null);
|
|
261
|
+
__privateAdd(this, _ctx, null);
|
|
262
|
+
__privateSet(this, _originalText, element.textContent || "");
|
|
263
|
+
__privateSet(this, _renderMode, config.renderMode || "auto");
|
|
264
|
+
__privateSet(this, _threshold, config.threshold || 100);
|
|
265
|
+
__privateMethod(this, _TextBlock_instances, setup_fn).call(this);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Use an effect
|
|
269
|
+
* @param {Function} effect - Effect function or dynamic import
|
|
270
|
+
* @param {Object} options - Options
|
|
271
|
+
* @param {boolean} options.replace - Replace existing effects (default: true)
|
|
272
|
+
*/
|
|
273
|
+
async useEffect(effect, options = {}) {
|
|
274
|
+
const { replace = true } = options;
|
|
275
|
+
if (typeof effect === "function" && effect.constructor.name === "AsyncFunction") {
|
|
276
|
+
effect = await effect();
|
|
277
|
+
}
|
|
278
|
+
if (replace) {
|
|
279
|
+
this.clearEffects();
|
|
280
|
+
}
|
|
281
|
+
__privateGet(this, _effectChain).push(effect);
|
|
282
|
+
return this;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Clear all effects
|
|
286
|
+
*/
|
|
287
|
+
clearEffects() {
|
|
288
|
+
for (const effect of __privateGet(this, _effectChain)) {
|
|
289
|
+
if (typeof effect.destroy === "function") {
|
|
290
|
+
effect.destroy();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
__privateSet(this, _effectChain, []);
|
|
294
|
+
if (this.element) {
|
|
295
|
+
this.element.style.transform = "";
|
|
296
|
+
this.element.innerHTML = "";
|
|
297
|
+
this.element.textContent = __privateGet(this, _originalText);
|
|
298
|
+
}
|
|
299
|
+
return this;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Reset to original state
|
|
303
|
+
*/
|
|
304
|
+
reset() {
|
|
305
|
+
this.stop();
|
|
306
|
+
this.clearEffects();
|
|
307
|
+
return this;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Render text with effects
|
|
311
|
+
* @param {number} time - Current time
|
|
312
|
+
* @param {number} delta - Delta time
|
|
313
|
+
*/
|
|
314
|
+
render(time, delta) {
|
|
315
|
+
let text = __privateGet(this, _originalText);
|
|
316
|
+
let hasHTML = false;
|
|
317
|
+
for (const effect of __privateGet(this, _effectChain)) {
|
|
318
|
+
if (typeof effect.render === "function") {
|
|
319
|
+
const result = effect.render(text, time - this.startTime, {
|
|
320
|
+
originalText: __privateGet(this, _originalText),
|
|
321
|
+
element: this.element
|
|
322
|
+
});
|
|
323
|
+
if (result && typeof result === "object" && result.__html) {
|
|
324
|
+
text = result.__text || text;
|
|
325
|
+
this.element.innerHTML = result.__html;
|
|
326
|
+
hasHTML = true;
|
|
327
|
+
} else {
|
|
328
|
+
text = result;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
__privateSet(this, _currentText, text);
|
|
333
|
+
if (!hasHTML) {
|
|
334
|
+
__privateMethod(this, _TextBlock_instances, updateDOM_fn).call(this);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Get current text
|
|
339
|
+
*/
|
|
340
|
+
get text() {
|
|
341
|
+
return __privateGet(this, _currentText);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Set new text
|
|
345
|
+
*/
|
|
346
|
+
set text(value) {
|
|
347
|
+
__privateSet(this, _originalText, value);
|
|
348
|
+
__privateSet(this, _currentText, value);
|
|
349
|
+
__privateMethod(this, _TextBlock_instances, updateDOM_fn).call(this);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
_originalText = new WeakMap();
|
|
353
|
+
_currentText = new WeakMap();
|
|
354
|
+
_effectChain = new WeakMap();
|
|
355
|
+
_renderMode = new WeakMap();
|
|
356
|
+
_threshold = new WeakMap();
|
|
357
|
+
_canvas = new WeakMap();
|
|
358
|
+
_ctx = new WeakMap();
|
|
359
|
+
_TextBlock_instances = new WeakSet();
|
|
360
|
+
/**
|
|
361
|
+
* Setup element and detect rendering mode
|
|
362
|
+
* @private
|
|
363
|
+
*/
|
|
364
|
+
setup_fn = function() {
|
|
365
|
+
const lineCount = __privateGet(this, _originalText).split("\n").length;
|
|
366
|
+
const hasMultiline = __privateGet(this, _originalText).includes("\n");
|
|
367
|
+
if (hasMultiline) {
|
|
368
|
+
this.element.style.whiteSpace = "pre";
|
|
369
|
+
this.element.style.fontFamily = "monospace";
|
|
370
|
+
}
|
|
371
|
+
if (__privateGet(this, _renderMode) === "auto") {
|
|
372
|
+
__privateSet(this, _renderMode, lineCount > __privateGet(this, _threshold) ? "canvas" : "dom");
|
|
373
|
+
}
|
|
374
|
+
if (__privateGet(this, _renderMode) === "canvas") {
|
|
375
|
+
__privateMethod(this, _TextBlock_instances, setupCanvas_fn).call(this, lineCount);
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Setup canvas for large ASCII art
|
|
380
|
+
* @private
|
|
381
|
+
*/
|
|
382
|
+
setupCanvas_fn = function(lineCount) {
|
|
383
|
+
__privateSet(this, _canvas, document.createElement("canvas"));
|
|
384
|
+
__privateSet(this, _ctx, __privateGet(this, _canvas).getContext("2d"));
|
|
385
|
+
const fontSize = 16;
|
|
386
|
+
const lineHeight = fontSize * 1.2;
|
|
387
|
+
const maxLineLength = Math.max(
|
|
388
|
+
...__privateGet(this, _originalText).split("\n").map((l) => l.length)
|
|
389
|
+
);
|
|
390
|
+
__privateGet(this, _canvas).width = maxLineLength * (fontSize * 0.6);
|
|
391
|
+
__privateGet(this, _canvas).height = lineCount * lineHeight;
|
|
392
|
+
__privateGet(this, _canvas).style.fontFamily = "monospace";
|
|
393
|
+
__privateGet(this, _ctx).font = `${fontSize}px monospace`;
|
|
394
|
+
__privateGet(this, _ctx).fillStyle = getComputedStyle(this.element).color || "#000";
|
|
395
|
+
this.element.innerHTML = "";
|
|
396
|
+
this.element.appendChild(__privateGet(this, _canvas));
|
|
397
|
+
};
|
|
398
|
+
/**
|
|
399
|
+
* Update DOM or canvas
|
|
400
|
+
* @private
|
|
401
|
+
*/
|
|
402
|
+
updateDOM_fn = function() {
|
|
403
|
+
if (__privateGet(this, _renderMode) === "canvas") {
|
|
404
|
+
__privateMethod(this, _TextBlock_instances, renderCanvas_fn).call(this);
|
|
405
|
+
} else {
|
|
406
|
+
this.element.textContent = __privateGet(this, _currentText);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
/**
|
|
410
|
+
* Render to canvas
|
|
411
|
+
* @private
|
|
412
|
+
*/
|
|
413
|
+
renderCanvas_fn = function() {
|
|
414
|
+
__privateGet(this, _ctx).clearRect(0, 0, __privateGet(this, _canvas).width, __privateGet(this, _canvas).height);
|
|
415
|
+
const lines = __privateGet(this, _currentText).split("\n");
|
|
416
|
+
const fontSize = 16;
|
|
417
|
+
const lineHeight = fontSize * 1.2;
|
|
418
|
+
lines.forEach((line, i) => {
|
|
419
|
+
__privateGet(this, _ctx).fillText(line, 0, (i + 1) * lineHeight);
|
|
420
|
+
});
|
|
421
|
+
};
|
|
422
|
+
class CanvasGrid extends BaseInstance {
|
|
423
|
+
constructor(id, element, config = {}) {
|
|
424
|
+
super(id, element);
|
|
425
|
+
__privateAdd(this, _CanvasGrid_instances);
|
|
426
|
+
__privateAdd(this, _canvas2, null);
|
|
427
|
+
__privateAdd(this, _ctx2, null);
|
|
428
|
+
__privateAdd(this, _cols, 80);
|
|
429
|
+
__privateAdd(this, _rows, 40);
|
|
430
|
+
__privateAdd(this, _charset, " .:-=+*#%@");
|
|
431
|
+
__privateAdd(this, _cellWidth, 10);
|
|
432
|
+
__privateAdd(this, _cellHeight, 16);
|
|
433
|
+
__privateAdd(this, _grid, []);
|
|
434
|
+
__privateAdd(this, _generator, null);
|
|
435
|
+
/**
|
|
436
|
+
* Default noise generator
|
|
437
|
+
* @private
|
|
438
|
+
*/
|
|
439
|
+
__privateAdd(this, _defaultGenerator, (x, y, time) => {
|
|
440
|
+
const noise = Math.sin(x * 0.1 + time * 1e-3) * Math.cos(y * 0.1 + time * 1e-3);
|
|
441
|
+
return (noise + 1) / 2;
|
|
442
|
+
});
|
|
443
|
+
__privateSet(this, _cols, config.cols || 80);
|
|
444
|
+
__privateSet(this, _rows, config.rows || 40);
|
|
445
|
+
__privateSet(this, _charset, config.charset || " .:-=+*#%@");
|
|
446
|
+
__privateSet(this, _cellWidth, config.cellWidth || 10);
|
|
447
|
+
__privateSet(this, _cellHeight, config.cellHeight || 16);
|
|
448
|
+
__privateSet(this, _generator, config.generator || __privateGet(this, _defaultGenerator));
|
|
449
|
+
__privateMethod(this, _CanvasGrid_instances, setup_fn2).call(this);
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Render grid
|
|
453
|
+
* @param {number} time - Current time
|
|
454
|
+
* @param {number} delta - Delta time
|
|
455
|
+
*/
|
|
456
|
+
render(time, delta) {
|
|
457
|
+
__privateGet(this, _ctx2).clearRect(0, 0, __privateGet(this, _canvas2).width, __privateGet(this, _canvas2).height);
|
|
458
|
+
__privateGet(this, _ctx2).fillStyle = getComputedStyle(this.element).color || "#000";
|
|
459
|
+
for (let y = 0; y < __privateGet(this, _rows); y++) {
|
|
460
|
+
for (let x = 0; x < __privateGet(this, _cols); x++) {
|
|
461
|
+
const value = __privateGet(this, _generator).call(this, x, y, time);
|
|
462
|
+
const char = __privateMethod(this, _CanvasGrid_instances, valueToChar_fn).call(this, value);
|
|
463
|
+
__privateGet(this, _ctx2).fillText(
|
|
464
|
+
char,
|
|
465
|
+
x * __privateGet(this, _cellWidth),
|
|
466
|
+
y * __privateGet(this, _cellHeight)
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Set custom generator function
|
|
473
|
+
* @param {Function} fn - Generator function (x, y, time) => 0-1
|
|
474
|
+
*/
|
|
475
|
+
setGenerator(fn) {
|
|
476
|
+
__privateSet(this, _generator, fn);
|
|
477
|
+
return this;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Set charset
|
|
481
|
+
* @param {string} chars - Character set
|
|
482
|
+
*/
|
|
483
|
+
setCharset(chars) {
|
|
484
|
+
__privateSet(this, _charset, chars);
|
|
485
|
+
return this;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
_canvas2 = new WeakMap();
|
|
489
|
+
_ctx2 = new WeakMap();
|
|
490
|
+
_cols = new WeakMap();
|
|
491
|
+
_rows = new WeakMap();
|
|
492
|
+
_charset = new WeakMap();
|
|
493
|
+
_cellWidth = new WeakMap();
|
|
494
|
+
_cellHeight = new WeakMap();
|
|
495
|
+
_grid = new WeakMap();
|
|
496
|
+
_generator = new WeakMap();
|
|
497
|
+
_CanvasGrid_instances = new WeakSet();
|
|
498
|
+
/**
|
|
499
|
+
* Setup canvas
|
|
500
|
+
* @private
|
|
501
|
+
*/
|
|
502
|
+
setup_fn2 = function() {
|
|
503
|
+
__privateSet(this, _canvas2, document.createElement("canvas"));
|
|
504
|
+
__privateSet(this, _ctx2, __privateGet(this, _canvas2).getContext("2d"));
|
|
505
|
+
__privateGet(this, _canvas2).width = __privateGet(this, _cols) * __privateGet(this, _cellWidth);
|
|
506
|
+
__privateGet(this, _canvas2).height = __privateGet(this, _rows) * __privateGet(this, _cellHeight);
|
|
507
|
+
__privateGet(this, _canvas2).style.width = "100%";
|
|
508
|
+
__privateGet(this, _canvas2).style.height = "100%";
|
|
509
|
+
__privateGet(this, _ctx2).font = `${__privateGet(this, _cellHeight)}px monospace`;
|
|
510
|
+
__privateGet(this, _ctx2).textBaseline = "top";
|
|
511
|
+
this.element.innerHTML = "";
|
|
512
|
+
this.element.appendChild(__privateGet(this, _canvas2));
|
|
513
|
+
__privateSet(this, _grid, Array(__privateGet(this, _rows)).fill(null).map(
|
|
514
|
+
() => Array(__privateGet(this, _cols)).fill(0)
|
|
515
|
+
));
|
|
516
|
+
};
|
|
517
|
+
_defaultGenerator = new WeakMap();
|
|
518
|
+
/**
|
|
519
|
+
* Map value to character
|
|
520
|
+
* @private
|
|
521
|
+
*/
|
|
522
|
+
valueToChar_fn = function(value) {
|
|
523
|
+
const clampedValue = Math.max(0, Math.min(1, value));
|
|
524
|
+
const chars = Array.from(__privateGet(this, _charset));
|
|
525
|
+
const index2 = Math.floor(clampedValue * (chars.length - 1));
|
|
526
|
+
return chars[index2] || " ";
|
|
527
|
+
};
|
|
528
|
+
async function hologram(config = {}) {
|
|
529
|
+
const { GlitchEffect } = await import("./text-CKJIlRsq.js").then((n) => n.g);
|
|
530
|
+
const { PulseEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.p);
|
|
531
|
+
return [
|
|
532
|
+
new GlitchEffect({
|
|
533
|
+
intensity: config.glitchIntensity || 0.08,
|
|
534
|
+
...config.glitch
|
|
535
|
+
}),
|
|
536
|
+
new PulseEffect({
|
|
537
|
+
minScale: 0.98,
|
|
538
|
+
maxScale: 1.02,
|
|
539
|
+
speed: 3e-3,
|
|
540
|
+
...config.pulse
|
|
541
|
+
})
|
|
542
|
+
];
|
|
543
|
+
}
|
|
544
|
+
async function matrix(config = {}) {
|
|
545
|
+
const { MatrixRainEffect } = await import("./text-CKJIlRsq.js").then((n) => n.m);
|
|
546
|
+
const { ScanlinesEffect } = await import("./procedural-BY9bCgT3.js");
|
|
547
|
+
return [
|
|
548
|
+
new MatrixRainEffect({
|
|
549
|
+
speed: 0.1,
|
|
550
|
+
density: 0.05,
|
|
551
|
+
...config.matrix
|
|
552
|
+
}),
|
|
553
|
+
new ScanlinesEffect({
|
|
554
|
+
opacity: 0.15,
|
|
555
|
+
...config.scanlines
|
|
556
|
+
})
|
|
557
|
+
];
|
|
558
|
+
}
|
|
559
|
+
async function decrypt(config = {}) {
|
|
560
|
+
const { ScrambleEffect } = await import("./text-CKJIlRsq.js").then((n) => n.s);
|
|
561
|
+
const { RevealEffect } = await import("./text-CKJIlRsq.js").then((n) => n.r);
|
|
562
|
+
const duration = config.duration || 2e3;
|
|
563
|
+
const scrambleDuration = duration * 0.4;
|
|
564
|
+
const revealDuration = duration * 0.6;
|
|
565
|
+
return [
|
|
566
|
+
new ScrambleEffect({
|
|
567
|
+
duration: scrambleDuration,
|
|
568
|
+
revealMode: "progressive",
|
|
569
|
+
...config.scramble
|
|
570
|
+
}),
|
|
571
|
+
new RevealEffect({
|
|
572
|
+
duration: revealDuration,
|
|
573
|
+
...config.reveal
|
|
574
|
+
})
|
|
575
|
+
];
|
|
576
|
+
}
|
|
577
|
+
async function rainbow(config = {}) {
|
|
578
|
+
const { WaveEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.w);
|
|
579
|
+
const { ColorCycleEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.c);
|
|
580
|
+
return [
|
|
581
|
+
new WaveEffect({
|
|
582
|
+
amplitude: 3,
|
|
583
|
+
frequency: 0.8,
|
|
584
|
+
speed: 2e-3,
|
|
585
|
+
...config.wave
|
|
586
|
+
}),
|
|
587
|
+
new ColorCycleEffect({
|
|
588
|
+
speed: 2e-3,
|
|
589
|
+
spread: 5,
|
|
590
|
+
saturation: 80,
|
|
591
|
+
lightness: 60,
|
|
592
|
+
...config.color
|
|
593
|
+
})
|
|
594
|
+
];
|
|
595
|
+
}
|
|
596
|
+
async function terminal(config = {}) {
|
|
597
|
+
const { TypewriterEffect } = await import("./text-CKJIlRsq.js").then((n) => n.t);
|
|
598
|
+
const { ScanlinesEffect } = await import("./procedural-BY9bCgT3.js");
|
|
599
|
+
return [
|
|
600
|
+
new TypewriterEffect({
|
|
601
|
+
speed: 50,
|
|
602
|
+
showCursor: true,
|
|
603
|
+
...config.typewriter
|
|
604
|
+
}),
|
|
605
|
+
new ScanlinesEffect({
|
|
606
|
+
opacity: 0.1,
|
|
607
|
+
lineHeight: 2,
|
|
608
|
+
...config.scanlines
|
|
609
|
+
})
|
|
610
|
+
];
|
|
611
|
+
}
|
|
612
|
+
const presets = {
|
|
613
|
+
hologram,
|
|
614
|
+
matrix,
|
|
615
|
+
decrypt,
|
|
616
|
+
rainbow,
|
|
617
|
+
terminal
|
|
618
|
+
};
|
|
619
|
+
class AsciiFX {
|
|
620
|
+
constructor(config = {}) {
|
|
621
|
+
__privateAdd(this, _engine, null);
|
|
622
|
+
__privateAdd(this, _registry, null);
|
|
623
|
+
__privateAdd(this, _autoStart, true);
|
|
624
|
+
__privateSet(this, _engine, new Engine());
|
|
625
|
+
__privateSet(this, _registry, new Registry());
|
|
626
|
+
__privateSet(this, _autoStart, config.autoStart !== false);
|
|
627
|
+
if (__privateGet(this, _autoStart)) {
|
|
628
|
+
__privateGet(this, _engine).start();
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Create ASCII art text block
|
|
633
|
+
* @param {string|HTMLElement} selector - Element or selector
|
|
634
|
+
* @param {Object} config - Configuration
|
|
635
|
+
* @returns {TextBlockAPI} Text block API
|
|
636
|
+
*/
|
|
637
|
+
createArt(selector, config = {}) {
|
|
638
|
+
const element = typeof selector === "string" ? document.querySelector(selector) : selector;
|
|
639
|
+
if (!element) {
|
|
640
|
+
throw new Error(`Element not found: ${selector}`);
|
|
641
|
+
}
|
|
642
|
+
const id = __privateGet(this, _registry).createId("text");
|
|
643
|
+
const block = new TextBlock(id, element, config);
|
|
644
|
+
__privateGet(this, _registry).add(id, block);
|
|
645
|
+
__privateGet(this, _engine).register(id, block);
|
|
646
|
+
return new TextBlockAPI(block, this);
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Create text block (alias for createArt)
|
|
650
|
+
*/
|
|
651
|
+
createText(selector, config = {}) {
|
|
652
|
+
return this.createArt(selector, config);
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Create procedural canvas background
|
|
656
|
+
* @param {string|HTMLElement} selector - Element or selector
|
|
657
|
+
* @param {Object} config - Configuration
|
|
658
|
+
* @returns {CanvasGridAPI} Canvas grid API
|
|
659
|
+
*/
|
|
660
|
+
createBackground(selector, config = {}) {
|
|
661
|
+
const element = typeof selector === "string" ? document.querySelector(selector) : selector;
|
|
662
|
+
if (!element) {
|
|
663
|
+
throw new Error(`Element not found: ${selector}`);
|
|
664
|
+
}
|
|
665
|
+
const id = __privateGet(this, _registry).createId("grid");
|
|
666
|
+
const grid = new CanvasGrid(id, element, config);
|
|
667
|
+
__privateGet(this, _registry).add(id, grid);
|
|
668
|
+
__privateGet(this, _engine).register(id, grid);
|
|
669
|
+
return new CanvasGridAPI(grid, this);
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Start engine
|
|
673
|
+
*/
|
|
674
|
+
start() {
|
|
675
|
+
__privateGet(this, _engine).start();
|
|
676
|
+
return this;
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Stop engine
|
|
680
|
+
*/
|
|
681
|
+
stop() {
|
|
682
|
+
__privateGet(this, _engine).stop();
|
|
683
|
+
return this;
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Get instance by ID
|
|
687
|
+
*/
|
|
688
|
+
getInstance(id) {
|
|
689
|
+
return __privateGet(this, _registry).get(id);
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Destroy instance
|
|
693
|
+
*/
|
|
694
|
+
destroy(id) {
|
|
695
|
+
__privateGet(this, _engine).unregister(id);
|
|
696
|
+
__privateGet(this, _registry).remove(id);
|
|
697
|
+
return this;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Get presets
|
|
701
|
+
*/
|
|
702
|
+
get presets() {
|
|
703
|
+
return presets;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
_engine = new WeakMap();
|
|
707
|
+
_registry = new WeakMap();
|
|
708
|
+
_autoStart = new WeakMap();
|
|
709
|
+
class TextBlockAPI {
|
|
710
|
+
constructor(block, asciiFX) {
|
|
711
|
+
__privateAdd(this, _block);
|
|
712
|
+
__privateAdd(this, _asciiFX);
|
|
713
|
+
__privateSet(this, _block, block);
|
|
714
|
+
__privateSet(this, _asciiFX, asciiFX);
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Apply effect
|
|
718
|
+
* @param {Object} effect - Effect instance
|
|
719
|
+
* @param {Object} options - Options
|
|
720
|
+
* @param {boolean} options.replace - Replace existing effects (default: true)
|
|
721
|
+
*/
|
|
722
|
+
async useEffect(effect, options) {
|
|
723
|
+
await __privateGet(this, _block).useEffect(effect, options);
|
|
724
|
+
return this;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Apply preset
|
|
728
|
+
*/
|
|
729
|
+
async preset(name, config = {}) {
|
|
730
|
+
const presetFn = presets[name];
|
|
731
|
+
if (!presetFn) {
|
|
732
|
+
throw new Error(`Preset not found: ${name}`);
|
|
733
|
+
}
|
|
734
|
+
const effects = await presetFn(config);
|
|
735
|
+
for (let i = 0; i < effects.length; i++) {
|
|
736
|
+
await __privateGet(this, _block).useEffect(effects[i], { replace: i === 0 });
|
|
737
|
+
}
|
|
738
|
+
return this;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Fluent API for effects
|
|
742
|
+
*/
|
|
743
|
+
async wave(config) {
|
|
744
|
+
const { WaveEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.w);
|
|
745
|
+
return this.useEffect(new WaveEffect(config), { replace: false });
|
|
746
|
+
}
|
|
747
|
+
async colorCycle(config) {
|
|
748
|
+
const { ColorCycleEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.c);
|
|
749
|
+
return this.useEffect(new ColorCycleEffect(config), { replace: false });
|
|
750
|
+
}
|
|
751
|
+
async colorGradient(config) {
|
|
752
|
+
const { ColorGradientEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.a);
|
|
753
|
+
return this.useEffect(new ColorGradientEffect(config), { replace: false });
|
|
754
|
+
}
|
|
755
|
+
async pulse(config) {
|
|
756
|
+
const { PulseEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.p);
|
|
757
|
+
return this.useEffect(new PulseEffect(config), { replace: false });
|
|
758
|
+
}
|
|
759
|
+
async perspective(config) {
|
|
760
|
+
const { PerspectiveEffect } = await import("./ascii-art-DCOQt4Se.js").then((n) => n.b);
|
|
761
|
+
return this.useEffect(new PerspectiveEffect(config), { replace: false });
|
|
762
|
+
}
|
|
763
|
+
async scramble(config) {
|
|
764
|
+
const { ScrambleEffect } = await import("./text-CKJIlRsq.js").then((n) => n.s);
|
|
765
|
+
return this.useEffect(new ScrambleEffect(config), { replace: false });
|
|
766
|
+
}
|
|
767
|
+
async reveal(config) {
|
|
768
|
+
const { RevealEffect } = await import("./text-CKJIlRsq.js").then((n) => n.r);
|
|
769
|
+
return this.useEffect(new RevealEffect(config), { replace: false });
|
|
770
|
+
}
|
|
771
|
+
async glitch(config) {
|
|
772
|
+
const { GlitchEffect } = await import("./text-CKJIlRsq.js").then((n) => n.g);
|
|
773
|
+
return this.useEffect(new GlitchEffect(config), { replace: false });
|
|
774
|
+
}
|
|
775
|
+
async typewriter(config) {
|
|
776
|
+
const { TypewriterEffect } = await import("./text-CKJIlRsq.js").then((n) => n.t);
|
|
777
|
+
return this.useEffect(new TypewriterEffect(config), { replace: false });
|
|
778
|
+
}
|
|
779
|
+
async matrix(config) {
|
|
780
|
+
const { MatrixRainEffect } = await import("./text-CKJIlRsq.js").then((n) => n.m);
|
|
781
|
+
return this.useEffect(new MatrixRainEffect(config), { replace: false });
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Clear all effects
|
|
785
|
+
*/
|
|
786
|
+
clearEffects() {
|
|
787
|
+
__privateGet(this, _block).clearEffects();
|
|
788
|
+
return this;
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Reset to original state
|
|
792
|
+
*/
|
|
793
|
+
reset() {
|
|
794
|
+
__privateGet(this, _block).reset();
|
|
795
|
+
return this;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Control methods
|
|
799
|
+
*/
|
|
800
|
+
play() {
|
|
801
|
+
__privateGet(this, _block).play();
|
|
802
|
+
return this;
|
|
803
|
+
}
|
|
804
|
+
pause() {
|
|
805
|
+
__privateGet(this, _block).pause();
|
|
806
|
+
return this;
|
|
807
|
+
}
|
|
808
|
+
stop() {
|
|
809
|
+
__privateGet(this, _block).stop();
|
|
810
|
+
return this;
|
|
811
|
+
}
|
|
812
|
+
destroy() {
|
|
813
|
+
__privateGet(this, _block).stop();
|
|
814
|
+
__privateGet(this, _asciiFX).destroy(__privateGet(this, _block).id);
|
|
815
|
+
return this;
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Event handlers
|
|
819
|
+
*/
|
|
820
|
+
on(event, callback) {
|
|
821
|
+
__privateGet(this, _block).on(event, callback);
|
|
822
|
+
return this;
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Get instance
|
|
826
|
+
*/
|
|
827
|
+
get instance() {
|
|
828
|
+
return __privateGet(this, _block);
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Get instance ID
|
|
832
|
+
*/
|
|
833
|
+
get id() {
|
|
834
|
+
return __privateGet(this, _block).id;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
_block = new WeakMap();
|
|
838
|
+
_asciiFX = new WeakMap();
|
|
839
|
+
class CanvasGridAPI {
|
|
840
|
+
constructor(grid, asciiFX) {
|
|
841
|
+
__privateAdd(this, _grid2);
|
|
842
|
+
__privateAdd(this, _asciiFX2);
|
|
843
|
+
__privateSet(this, _grid2, grid);
|
|
844
|
+
__privateSet(this, _asciiFX2, asciiFX);
|
|
845
|
+
}
|
|
846
|
+
setGenerator(fn) {
|
|
847
|
+
__privateGet(this, _grid2).setGenerator(fn);
|
|
848
|
+
return this;
|
|
849
|
+
}
|
|
850
|
+
setCharset(chars) {
|
|
851
|
+
__privateGet(this, _grid2).setCharset(chars);
|
|
852
|
+
return this;
|
|
853
|
+
}
|
|
854
|
+
play() {
|
|
855
|
+
__privateGet(this, _grid2).play();
|
|
856
|
+
return this;
|
|
857
|
+
}
|
|
858
|
+
pause() {
|
|
859
|
+
__privateGet(this, _grid2).pause();
|
|
860
|
+
return this;
|
|
861
|
+
}
|
|
862
|
+
stop() {
|
|
863
|
+
__privateGet(this, _grid2).stop();
|
|
864
|
+
return this;
|
|
865
|
+
}
|
|
866
|
+
destroy() {
|
|
867
|
+
__privateGet(this, _grid2).stop();
|
|
868
|
+
__privateGet(this, _asciiFX2).destroy(__privateGet(this, _grid2).id);
|
|
869
|
+
return this;
|
|
870
|
+
}
|
|
871
|
+
on(event, callback) {
|
|
872
|
+
__privateGet(this, _grid2).on(event, callback);
|
|
873
|
+
return this;
|
|
874
|
+
}
|
|
875
|
+
get instance() {
|
|
876
|
+
return __privateGet(this, _grid2);
|
|
877
|
+
}
|
|
878
|
+
get id() {
|
|
879
|
+
return __privateGet(this, _grid2).id;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
_grid2 = new WeakMap();
|
|
883
|
+
_asciiFX2 = new WeakMap();
|
|
884
|
+
function create(config) {
|
|
885
|
+
return new AsciiFX(config);
|
|
886
|
+
}
|
|
887
|
+
const index = { create, AsciiFX };
|
|
888
|
+
export {
|
|
889
|
+
AsciiFX,
|
|
890
|
+
create,
|
|
891
|
+
index as default
|
|
892
|
+
};
|