textmode.js 0.4.0 → 0.6.0-beta.1
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/dist/textmode.esm.js +2868 -2164
- package/dist/textmode.esm.min.js +2863 -2159
- package/dist/textmode.umd.js +11 -8
- package/dist/textmode.umd.min.js +11 -8
- package/dist/types/Textmode.d.ts +13 -22
- package/dist/types/index.d.ts +8 -6
- package/dist/types/rendering/index.d.ts +3 -3
- package/dist/types/rendering/webgl/batching/DrawQueue.d.ts +89 -0
- package/dist/types/rendering/webgl/{VAOManager.d.ts → batching/GeometryAttributeCache.d.ts} +4 -4
- package/dist/types/rendering/webgl/batching/InstanceAttributeBinder.d.ts +87 -0
- package/dist/types/rendering/webgl/{InstanceBatch.d.ts → batching/InstanceBatch.d.ts} +25 -34
- package/dist/types/rendering/webgl/batching/InstanceBuffer.d.ts +78 -0
- package/dist/types/rendering/webgl/{InstanceData.d.ts → batching/InstanceData.d.ts} +11 -18
- package/dist/types/rendering/webgl/batching/InstanceWriter.d.ts +70 -0
- package/dist/types/rendering/webgl/{Framebuffer.d.ts → core/Framebuffer.d.ts} +37 -39
- package/dist/types/rendering/webgl/core/Renderer.d.ts +64 -0
- package/dist/types/rendering/webgl/{Shader.d.ts → core/Shader.d.ts} +2 -23
- package/dist/types/rendering/webgl/core/interfaces/IFramebuffer.d.ts +103 -0
- package/dist/types/rendering/webgl/core/interfaces/IRenderer.d.ts +210 -0
- package/dist/types/rendering/webgl/geometries/{Arc.d.ts → 2d/Arc.d.ts} +5 -4
- package/dist/types/rendering/webgl/geometries/{BezierCurve.d.ts → 2d/BezierCurve.d.ts} +5 -4
- package/dist/types/rendering/webgl/geometries/{Ellipse.d.ts → 2d/Ellipse.d.ts} +6 -5
- package/dist/types/rendering/webgl/geometries/{Line.d.ts → 2d/Line.d.ts} +5 -4
- package/dist/types/rendering/webgl/geometries/{Rectangle.d.ts → 2d/Rectangle.d.ts} +5 -4
- package/dist/types/rendering/webgl/geometries/{Triangle.d.ts → 2d/Triangle.d.ts} +5 -4
- package/dist/types/rendering/webgl/geometries/BaseGeometry.d.ts +30 -26
- package/dist/types/rendering/webgl/geometries/immediate/ImmediateQuad.d.ts +33 -0
- package/dist/types/rendering/webgl/geometries/index.d.ts +6 -6
- package/dist/types/rendering/webgl/geometries/utils/GeometryDescriptors.d.ts +31 -0
- package/dist/types/rendering/webgl/geometries/utils/GeometryGenerator.d.ts +16 -0
- package/dist/types/rendering/webgl/index.d.ts +15 -14
- package/dist/types/rendering/webgl/materials/Material.d.ts +26 -0
- package/dist/types/rendering/webgl/materials/MaterialManager.d.ts +63 -0
- package/dist/types/rendering/webgl/materials/index.d.ts +2 -0
- package/dist/types/rendering/webgl/pipeline/MaterialBatchPipeline.d.ts +63 -0
- package/dist/types/rendering/webgl/pipeline/index.d.ts +7 -0
- package/dist/types/rendering/webgl/state/RenderState.d.ts +143 -0
- package/dist/types/rendering/webgl/types/DrawCommand.d.ts +5 -3
- package/dist/types/rendering/webgl/types/GeometryTypes.d.ts +10 -10
- package/dist/types/rendering/webgl/types/RenderTypes.d.ts +1 -1
- package/dist/types/rendering/webgl/utils/GLUtils.d.ts +45 -0
- package/dist/types/rendering/webgl/utils/hash.d.ts +118 -0
- package/dist/types/textmode/AnimationController.d.ts +11 -21
- package/dist/types/textmode/Canvas.d.ts +10 -2
- package/dist/types/textmode/Grid.d.ts +2 -0
- package/dist/types/textmode/TextmodeColor.d.ts +57 -0
- package/dist/types/textmode/Textmodifier.d.ts +40 -212
- package/dist/types/textmode/interfaces/ITextmodifier.d.ts +272 -0
- package/dist/types/textmode/interfaces/index.d.ts +1 -0
- package/dist/types/textmode/loadables/TextmodeImage.d.ts +21 -0
- package/dist/types/textmode/loadables/TextmodeSource.d.ts +130 -0
- package/dist/types/textmode/loadables/TextmodeVideo.d.ts +237 -0
- package/dist/types/textmode/{font → loadables/font}/CharacterColorMapper.d.ts +1 -1
- package/dist/types/textmode/{font → loadables/font}/CharacterExtractor.d.ts +0 -10
- package/dist/types/textmode/{font → loadables/font}/TextmodeFont.d.ts +6 -3
- package/dist/types/textmode/{font → loadables/font}/TextureAtlas.d.ts +4 -11
- package/dist/types/textmode/{font → loadables/font}/typr/types.d.ts +0 -6
- package/dist/types/textmode/loadables/index.d.ts +5 -0
- package/dist/types/textmode/loading/LoadingPhaseTracker.d.ts +20 -0
- package/dist/types/textmode/loading/LoadingScreenManager.d.ts +170 -0
- package/dist/types/textmode/loading/LoadingScreenState.d.ts +22 -0
- package/dist/types/textmode/loading/LoadingScreenTheme.d.ts +26 -0
- package/dist/types/textmode/loading/LoadingScreenTransition.d.ts +17 -0
- package/dist/types/textmode/loading/index.d.ts +6 -0
- package/dist/types/textmode/loading/templates/SpinnerTemplate.d.ts +2 -0
- package/dist/types/textmode/loading/templates/index.d.ts +1 -0
- package/dist/types/textmode/loading/types.d.ts +251 -0
- package/dist/types/textmode/managers/KeyboardManager.d.ts +2 -3
- package/dist/types/textmode/managers/MouseManager.d.ts +1 -1
- package/dist/types/textmode/{plugins → managers}/PluginManager.d.ts +12 -15
- package/dist/types/textmode/managers/TouchManager.d.ts +0 -2
- package/dist/types/textmode/mixins/AnimationMixin.d.ts +2 -122
- package/dist/types/textmode/mixins/FontMixin.d.ts +2 -77
- package/dist/types/textmode/mixins/KeyboardMixin.d.ts +3 -85
- package/dist/types/textmode/mixins/MouseMixin.d.ts +3 -130
- package/dist/types/textmode/mixins/RenderingMixin.d.ts +2 -749
- package/dist/types/textmode/mixins/TextmodifierMixin.d.ts +2 -44
- package/dist/types/textmode/mixins/TouchMixin.d.ts +2 -187
- package/dist/types/textmode/mixins/index.d.ts +8 -8
- package/dist/types/textmode/mixins/interfaces/IAnimationMixin.d.ts +167 -0
- package/dist/types/textmode/mixins/interfaces/IFontMixin.d.ts +46 -0
- package/dist/types/textmode/mixins/interfaces/IKeyboardMixin.d.ts +235 -0
- package/dist/types/textmode/mixins/interfaces/IMouseMixin.d.ts +457 -0
- package/dist/types/textmode/mixins/interfaces/IRenderingMixin.d.ts +1085 -0
- package/dist/types/textmode/mixins/interfaces/ITouchMixin.d.ts +186 -0
- package/dist/types/textmode/types.d.ts +49 -0
- package/dist/types/textmode/utils/cssColor.d.ts +8 -0
- package/dist/types/utils/array.d.ts +34 -0
- package/dist/types/utils/math.d.ts +69 -0
- package/package.json +1 -1
- package/dist/types/rendering/webgl/DrawQueue.d.ts +0 -30
- package/dist/types/rendering/webgl/RenderPipeline.d.ts +0 -30
- package/dist/types/rendering/webgl/RenderState.d.ts +0 -73
- package/dist/types/rendering/webgl/Renderer.d.ts +0 -158
- package/dist/types/rendering/webgl/ShaderManager.d.ts +0 -66
- package/dist/types/rendering/webgl/geometries/NoiseGrid.d.ts +0 -1
- package/dist/types/textmode/TextmodeImage.d.ts +0 -161
- package/dist/types/textmode/mixins/ShaderMixin.d.ts +0 -1
- /package/dist/types/rendering/webgl/{StateCache.d.ts → utils/ViewportCache.d.ts} +0 -0
- /package/dist/types/textmode/{font → loadables/font}/MetricsCalculator.d.ts +0 -0
- /package/dist/types/textmode/{font → loadables/font}/index.d.ts +0 -0
- /package/dist/types/textmode/{font → loadables/font}/types.d.ts +0 -0
- /package/dist/types/textmode/{font → loadables/font}/typr/Typr.d.ts +0 -0
- /package/dist/types/textmode/{font → loadables/font}/utils/FontTableReader.d.ts +0 -0
- /package/dist/types/textmode/{font → loadables/font}/utils/index.d.ts +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import type { KeyboardEventHandler } from "../../managers/KeyboardManager";
|
|
2
|
+
/**
|
|
3
|
+
* Capabilities provided by the KeyboardMixin
|
|
4
|
+
*/
|
|
5
|
+
export interface IKeyboardMixin {
|
|
6
|
+
/**
|
|
7
|
+
* Check if a specific key is currently being pressed.
|
|
8
|
+
*
|
|
9
|
+
* @param key The key to check (e.g., 'a', 'Enter', 'ArrowLeft')
|
|
10
|
+
* @returns true if the key is currently pressed, false otherwise
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```javascript
|
|
14
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
15
|
+
*
|
|
16
|
+
* let playerX = 0;
|
|
17
|
+
* let playerY = 0;
|
|
18
|
+
*
|
|
19
|
+
* t.draw(() => {
|
|
20
|
+
* t.background(0);
|
|
21
|
+
*
|
|
22
|
+
* // Check for arrow keys to move a character
|
|
23
|
+
* if (t.isKeyPressed('ArrowUp')) {
|
|
24
|
+
* playerY -= 1;
|
|
25
|
+
* }
|
|
26
|
+
* if (t.isKeyPressed('ArrowDown')) {
|
|
27
|
+
* playerY += 1;
|
|
28
|
+
* }
|
|
29
|
+
* if (t.isKeyPressed('ArrowLeft')) {
|
|
30
|
+
* playerX -= 1;
|
|
31
|
+
* }
|
|
32
|
+
* if (t.isKeyPressed('ArrowRight')) {
|
|
33
|
+
* playerX += 1;
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // Draw player character
|
|
37
|
+
* t.char('@');
|
|
38
|
+
* t.charColor(255, 255, 0);
|
|
39
|
+
* t.translate(playerX, playerY);
|
|
40
|
+
* t.point();
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
isKeyPressed(key: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Set a callback function that will be called when a key is pressed down.
|
|
47
|
+
*
|
|
48
|
+
* @param callback The function to call when a key is pressed
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```javascript
|
|
52
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
53
|
+
*
|
|
54
|
+
* let lastKey = '?';
|
|
55
|
+
* let pulse = 0;
|
|
56
|
+
*
|
|
57
|
+
* // Update some visual state when a key is pressed
|
|
58
|
+
* t.keyPressed((data) => {
|
|
59
|
+
* lastKey = data.key;
|
|
60
|
+
* pulse = 6; // make the next frames brighter
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* t.draw(() => {
|
|
64
|
+
* t.background(0);
|
|
65
|
+
*
|
|
66
|
+
* // Fade brightness back down each frame
|
|
67
|
+
* const glow = Math.max(0, pulse--);
|
|
68
|
+
* const brightness = 120 + glow * 20;
|
|
69
|
+
* t.charColor(brightness, brightness, 0);
|
|
70
|
+
*
|
|
71
|
+
* // Show the last pressed key at the center of the grid
|
|
72
|
+
* t.push();
|
|
73
|
+
* t.translate(t.grid.cols / 2, t.grid.rows / 2);
|
|
74
|
+
* t.char(lastKey.length ? lastKey[0] : '?');
|
|
75
|
+
* t.point();
|
|
76
|
+
* t.pop();
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
keyPressed(callback: KeyboardEventHandler): void;
|
|
81
|
+
/**
|
|
82
|
+
* Set a callback function that will be called when a key is released.
|
|
83
|
+
*
|
|
84
|
+
* @param callback The function to call when a key is released
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```javascript
|
|
88
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
89
|
+
*
|
|
90
|
+
* let lastRelease = '?';
|
|
91
|
+
* let fade = 0;
|
|
92
|
+
*
|
|
93
|
+
* // Capture the most recent key release and trigger a pulse
|
|
94
|
+
* t.keyReleased((data) => {
|
|
95
|
+
* lastRelease = data.key;
|
|
96
|
+
* fade = 10;
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* t.draw(() => {
|
|
100
|
+
* t.background(0);
|
|
101
|
+
*
|
|
102
|
+
* // Dim the glow over time
|
|
103
|
+
* const glow = Math.max(0, fade--);
|
|
104
|
+
* const color = 80 + glow * 17;
|
|
105
|
+
* t.charColor(color, color, 255);
|
|
106
|
+
*
|
|
107
|
+
* t.char(lastRelease.length ? lastRelease[0] : '?');
|
|
108
|
+
* t.point();
|
|
109
|
+
* });
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
keyReleased(callback: KeyboardEventHandler): void;
|
|
113
|
+
/**
|
|
114
|
+
* Get the last key that was pressed.
|
|
115
|
+
*
|
|
116
|
+
* Returns the key string of the last pressed key, or null if no key has been pressed.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```javascript
|
|
120
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
121
|
+
*
|
|
122
|
+
* t.draw(() => {
|
|
123
|
+
* t.background(0);
|
|
124
|
+
*
|
|
125
|
+
* const lastKey = t.lastKeyPressed;
|
|
126
|
+
* if (lastKey) {
|
|
127
|
+
* // Display the last pressed key
|
|
128
|
+
* t.char(lastKey);
|
|
129
|
+
* t.charColor(255, 255, 255);
|
|
130
|
+
* t.point();
|
|
131
|
+
* }
|
|
132
|
+
* });
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
get lastKeyPressed(): string | null;
|
|
136
|
+
/**
|
|
137
|
+
* Get the last key that was released.
|
|
138
|
+
*
|
|
139
|
+
* Returns the key string of the last released key, or null if no key has been released.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```javascript
|
|
143
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
144
|
+
*
|
|
145
|
+
* t.draw(() => {
|
|
146
|
+
* t.background(0);
|
|
147
|
+
*
|
|
148
|
+
* const lastKey = t.lastKeyReleased;
|
|
149
|
+
* if (lastKey) {
|
|
150
|
+
* // Display the last released key
|
|
151
|
+
* t.char(lastKey);
|
|
152
|
+
* t.charColor(128, 128, 128);
|
|
153
|
+
* t.point();
|
|
154
|
+
* }
|
|
155
|
+
* });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
get lastKeyReleased(): string | null;
|
|
159
|
+
/**
|
|
160
|
+
* Get all currently pressed keys.
|
|
161
|
+
*
|
|
162
|
+
* Returns an array of key strings that are currently being held down.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```javascript
|
|
166
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
167
|
+
*
|
|
168
|
+
* t.draw(() => {
|
|
169
|
+
* t.background(0);
|
|
170
|
+
*
|
|
171
|
+
* const pressed = t.pressedKeys;
|
|
172
|
+
*
|
|
173
|
+
* // Display all currently pressed keys
|
|
174
|
+
* pressed.forEach((key, index) => {
|
|
175
|
+
* t.push();
|
|
176
|
+
* t.char(key[0] || '?'); // Show first character of key name
|
|
177
|
+
* t.charColor(255, 200, 100);
|
|
178
|
+
* t.translate(index, 0);
|
|
179
|
+
* t.point();
|
|
180
|
+
* t.pop();
|
|
181
|
+
* });
|
|
182
|
+
* });
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
get pressedKeys(): string[];
|
|
186
|
+
/**
|
|
187
|
+
* Get current modifier key states.
|
|
188
|
+
*
|
|
189
|
+
* Returns an object with boolean properties for each modifier key.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```javascript
|
|
193
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
194
|
+
*
|
|
195
|
+
* t.draw(() => {
|
|
196
|
+
* t.background(0);
|
|
197
|
+
* const mods = t.modifierState;
|
|
198
|
+
*
|
|
199
|
+
* // Change behavior based on modifier keys
|
|
200
|
+
* if (mods.shift) {
|
|
201
|
+
* // Draw in caps or with different behavior
|
|
202
|
+
* t.char('S');
|
|
203
|
+
* t.charColor(255, 255, 0);
|
|
204
|
+
* t.point();
|
|
205
|
+
* }
|
|
206
|
+
*
|
|
207
|
+
* if (mods.ctrl) {
|
|
208
|
+
* // Control key is pressed
|
|
209
|
+
* t.translate(2, 0);
|
|
210
|
+
* t.char('C');
|
|
211
|
+
* t.charColor(0, 255, 255);
|
|
212
|
+
* t.point();
|
|
213
|
+
* }
|
|
214
|
+
* });
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
get modifierState(): {
|
|
218
|
+
/**
|
|
219
|
+
* Whether the Ctrl key is currently pressed
|
|
220
|
+
*/
|
|
221
|
+
ctrl: boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Whether the Shift key is currently pressed
|
|
224
|
+
*/
|
|
225
|
+
shift: boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Whether the Alt key is currently pressed
|
|
228
|
+
*/
|
|
229
|
+
alt: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Whether the Meta key *(Command on Mac, Windows key on Windows)* is currently pressed
|
|
232
|
+
*/
|
|
233
|
+
meta: boolean;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import type { MouseEventHandler, MousePosition } from "../../managers/MouseManager";
|
|
2
|
+
/**
|
|
3
|
+
* Capabilities provided by the MouseMixin
|
|
4
|
+
*/
|
|
5
|
+
export interface IMouseMixin {
|
|
6
|
+
/**
|
|
7
|
+
* Set a callback function that will be called when the mouse is clicked.
|
|
8
|
+
*
|
|
9
|
+
* @param callback The function to call when the mouse is clicked
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```javascript
|
|
13
|
+
* // Click to spawn ripples.
|
|
14
|
+
*
|
|
15
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
16
|
+
*
|
|
17
|
+
* // Store ripples as { x, y } in center-based coordinates
|
|
18
|
+
* const ripples = [];
|
|
19
|
+
*
|
|
20
|
+
* // Create a ripple at the clicked grid cell
|
|
21
|
+
* t.mouseClicked((data) => {
|
|
22
|
+
* // Convert top-left grid coords to center-based coords (matching draw-time origin)
|
|
23
|
+
* const centerX = Math.round(data.position.x - (t.grid.cols - 1) / 2);
|
|
24
|
+
* const centerY = Math.round(data.position.y - (t.grid.rows - 1) / 2);
|
|
25
|
+
*
|
|
26
|
+
* ripples.push({ x: centerX, y: centerY, age: 0, maxAge: 20 });
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* t.draw(() => {
|
|
30
|
+
* t.background(0);
|
|
31
|
+
*
|
|
32
|
+
* // Update and draw ripples (iterate backwards when removing)
|
|
33
|
+
* for (let i = ripples.length - 1; i >= 0; i--) {
|
|
34
|
+
* const r = ripples[i];
|
|
35
|
+
* r.age++;
|
|
36
|
+
* const life = r.age / r.maxAge; // 0..1
|
|
37
|
+
* const radius = 1 + life * 7; // expands from ~1 to ~8
|
|
38
|
+
* const intensity = Math.round(255 * (1 - life)); // fades out
|
|
39
|
+
*
|
|
40
|
+
* // Keep cells dark so characters stand out
|
|
41
|
+
* t.charColor(intensity, intensity, 255);
|
|
42
|
+
* t.cellColor(0);
|
|
43
|
+
*
|
|
44
|
+
* t.push();
|
|
45
|
+
* // position already in center-based coordinates
|
|
46
|
+
* t.translate(r.x, r.y);
|
|
47
|
+
*
|
|
48
|
+
* // Draw a ring by sampling points around the circle
|
|
49
|
+
* for (let a = 0; a < Math.PI * 2; a += Math.PI / 8) {
|
|
50
|
+
* const ox = Math.round(Math.cos(a) * radius);
|
|
51
|
+
* const oy = Math.round(Math.sin(a) * radius);
|
|
52
|
+
* t.push();
|
|
53
|
+
* t.translate(ox, oy);
|
|
54
|
+
* t.char('*');
|
|
55
|
+
* t.point();
|
|
56
|
+
* t.pop();
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* t.pop();
|
|
60
|
+
*
|
|
61
|
+
* // Remove finished ripples
|
|
62
|
+
* if (r.age > r.maxAge) {
|
|
63
|
+
* ripples.splice(i, 1);
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
*
|
|
67
|
+
* // Show crosshair for the current mouse cell. Convert t.mouse (top-left origin)
|
|
68
|
+
* // to the center-based coordinates used for drawing just like above.
|
|
69
|
+
* if (t.mouse.x !== -1 && t.mouse.y !== -1) {
|
|
70
|
+
* const cx = Math.round(t.mouse.x - (t.grid.cols - 1) / 2);
|
|
71
|
+
* const cy = Math.round(t.mouse.y - (t.grid.rows - 1) / 2);
|
|
72
|
+
* t.push();
|
|
73
|
+
* t.charColor(180);
|
|
74
|
+
* t.translate(cx, cy);
|
|
75
|
+
* t.char('+');
|
|
76
|
+
* t.point();
|
|
77
|
+
* t.pop();
|
|
78
|
+
* }
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
mouseClicked(callback: MouseEventHandler): void;
|
|
83
|
+
/**
|
|
84
|
+
* Set a callback function that will be called when the mouse is pressed down.
|
|
85
|
+
*
|
|
86
|
+
* @param callback The function to call when the mouse is pressed
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```javascript
|
|
90
|
+
* // Hold mouse to spray particles that fall with gravity.
|
|
91
|
+
*
|
|
92
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
93
|
+
*
|
|
94
|
+
* const particles = [];
|
|
95
|
+
* let pressing = false;
|
|
96
|
+
*
|
|
97
|
+
* t.mousePressed((data) => {
|
|
98
|
+
* if (data.position.x === -1 || data.position.y === -1) return;
|
|
99
|
+
* pressing = true;
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* t.mouseReleased(() => {
|
|
103
|
+
* pressing = false;
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* t.draw(() => {
|
|
107
|
+
* t.background(0);
|
|
108
|
+
*
|
|
109
|
+
* // Spawn particles while pressing
|
|
110
|
+
* if (pressing && t.mouse.x !== -1) {
|
|
111
|
+
* const cx = Math.round(t.mouse.x - (t.grid.cols - 1) / 2);
|
|
112
|
+
* const cy = Math.round(t.mouse.y - (t.grid.rows - 1) / 2);
|
|
113
|
+
*
|
|
114
|
+
* for (let i = 0; i < 3; i++) {
|
|
115
|
+
* particles.push({
|
|
116
|
+
* x: cx,
|
|
117
|
+
* y: cy,
|
|
118
|
+
* vx: (Math.random() - 0.5) * 0.8,
|
|
119
|
+
* vy: Math.random() * -0.5 - 0.2,
|
|
120
|
+
* age: 0,
|
|
121
|
+
* maxAge: 30 + Math.random() * 20
|
|
122
|
+
* });
|
|
123
|
+
* }
|
|
124
|
+
* }
|
|
125
|
+
*
|
|
126
|
+
* // Update and draw particles
|
|
127
|
+
* for (let i = particles.length - 1; i >= 0; i--) {
|
|
128
|
+
* const p = particles[i];
|
|
129
|
+
* p.age++;
|
|
130
|
+
* p.vy += 0.08; // gravity
|
|
131
|
+
* p.x += p.vx;
|
|
132
|
+
* p.y += p.vy;
|
|
133
|
+
*
|
|
134
|
+
* if (p.age >= p.maxAge) {
|
|
135
|
+
* particles.splice(i, 1);
|
|
136
|
+
* continue;
|
|
137
|
+
* }
|
|
138
|
+
*
|
|
139
|
+
* const life = 1 - (p.age / p.maxAge);
|
|
140
|
+
* const brightness = Math.round(255 * life);
|
|
141
|
+
*
|
|
142
|
+
* t.push();
|
|
143
|
+
* t.charColor(brightness, brightness * 0.7, 100);
|
|
144
|
+
* t.translate(Math.round(p.x), Math.round(p.y));
|
|
145
|
+
* t.char(life > 0.5 ? 'o' : '.');
|
|
146
|
+
* t.point();
|
|
147
|
+
* t.pop();
|
|
148
|
+
* }
|
|
149
|
+
* });
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
mousePressed(callback: MouseEventHandler): void;
|
|
153
|
+
/**
|
|
154
|
+
* Set a callback function that will be called when the mouse is released.
|
|
155
|
+
*
|
|
156
|
+
* @param callback The function to call when the mouse is released
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```javascript
|
|
160
|
+
* // Drag to draw lines that fade over time.
|
|
161
|
+
*
|
|
162
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
163
|
+
*
|
|
164
|
+
* const lines = [];
|
|
165
|
+
* let dragStart = null;
|
|
166
|
+
*
|
|
167
|
+
* t.mousePressed((data) => {
|
|
168
|
+
* if (data.position.x === -1 || data.position.y === -1) return;
|
|
169
|
+
* const cx = Math.round(data.position.x - (t.grid.cols - 1) / 2);
|
|
170
|
+
* const cy = Math.round(data.position.y - (t.grid.rows - 1) / 2);
|
|
171
|
+
* dragStart = { x: cx, y: cy };
|
|
172
|
+
* });
|
|
173
|
+
*
|
|
174
|
+
* t.mouseReleased((data) => {
|
|
175
|
+
* if (!dragStart || data.position.x === -1) return;
|
|
176
|
+
* const cx = Math.round(data.position.x - (t.grid.cols - 1) / 2);
|
|
177
|
+
* const cy = Math.round(data.position.y - (t.grid.rows - 1) / 2);
|
|
178
|
+
*
|
|
179
|
+
* // Calculate line center and local endpoints
|
|
180
|
+
* const centerX = (dragStart.x + cx) / 2;
|
|
181
|
+
* const centerY = (dragStart.y + cy) / 2;
|
|
182
|
+
* const dx = cx - dragStart.x;
|
|
183
|
+
* const dy = cy - dragStart.y;
|
|
184
|
+
*
|
|
185
|
+
* lines.push({
|
|
186
|
+
* cx: centerX, cy: centerY,
|
|
187
|
+
* dx: dx, dy: dy,
|
|
188
|
+
* age: 0, maxAge: 30
|
|
189
|
+
* });
|
|
190
|
+
* dragStart = null;
|
|
191
|
+
* });
|
|
192
|
+
*
|
|
193
|
+
* t.draw(() => {
|
|
194
|
+
* t.background(0);
|
|
195
|
+
*
|
|
196
|
+
* // Draw stored lines with fade
|
|
197
|
+
* for (let i = lines.length - 1; i >= 0; i--) {
|
|
198
|
+
* const ln = lines[i];
|
|
199
|
+
* ln.age++;
|
|
200
|
+
*
|
|
201
|
+
* if (ln.age >= ln.maxAge) {
|
|
202
|
+
* lines.splice(i, 1);
|
|
203
|
+
* continue;
|
|
204
|
+
* }
|
|
205
|
+
*
|
|
206
|
+
* const life = 1 - (ln.age / ln.maxAge);
|
|
207
|
+
* const brightness = Math.round(150 * life);
|
|
208
|
+
*
|
|
209
|
+
* t.push();
|
|
210
|
+
* t.charColor(brightness, brightness, 255);
|
|
211
|
+
* t.char('-');
|
|
212
|
+
* t.lineWeight(2);
|
|
213
|
+
* t.translate(ln.cx, ln.cy);
|
|
214
|
+
* t.line(-ln.dx / 2, -ln.dy / 2, ln.dx / 2, ln.dy / 2);
|
|
215
|
+
* t.pop();
|
|
216
|
+
* }
|
|
217
|
+
*
|
|
218
|
+
* // Draw current drag line
|
|
219
|
+
* if (dragStart && t.mouse.x !== -1) {
|
|
220
|
+
* const cx = Math.round(t.mouse.x - (t.grid.cols - 1) / 2);
|
|
221
|
+
* const cy = Math.round(t.mouse.y - (t.grid.rows - 1) / 2);
|
|
222
|
+
* const centerX = (dragStart.x + cx) / 2;
|
|
223
|
+
* const centerY = (dragStart.y + cy) / 2;
|
|
224
|
+
* const dx = cx - dragStart.x;
|
|
225
|
+
* const dy = cy - dragStart.y;
|
|
226
|
+
*
|
|
227
|
+
* t.push();
|
|
228
|
+
* t.charColor(255, 200, 0);
|
|
229
|
+
* t.char('o');
|
|
230
|
+
* t.lineWeight(2);
|
|
231
|
+
* t.translate(centerX, centerY);
|
|
232
|
+
* t.line(-dx / 2, -dy / 2, dx / 2, dy / 2);
|
|
233
|
+
* t.pop();
|
|
234
|
+
* }
|
|
235
|
+
* });
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
mouseReleased(callback: MouseEventHandler): void;
|
|
239
|
+
/**
|
|
240
|
+
* Set a callback function that will be called when the mouse moves.
|
|
241
|
+
*
|
|
242
|
+
* @param callback The function to call when the mouse moves
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```javascript
|
|
246
|
+
* // Trail of particles following the mouse.
|
|
247
|
+
*
|
|
248
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
249
|
+
*
|
|
250
|
+
* const trail = [];
|
|
251
|
+
* const maxTrail = 120;
|
|
252
|
+
* let lastMouse = null;
|
|
253
|
+
*
|
|
254
|
+
* t.mouseMoved((data) => {
|
|
255
|
+
* if (data.position.x === -1 || data.position.y === -1) return;
|
|
256
|
+
*
|
|
257
|
+
* // Convert to center-based coords
|
|
258
|
+
* const cx = Math.round(data.position.x - (t.grid.cols - 1) / 2);
|
|
259
|
+
* const cy = Math.round(data.position.y - (t.grid.rows - 1) / 2);
|
|
260
|
+
*
|
|
261
|
+
* // Spawn multiple particles based on movement speed
|
|
262
|
+
* const dx = lastMouse ? cx - lastMouse.x : 0;
|
|
263
|
+
* const dy = lastMouse ? cy - lastMouse.y : 0;
|
|
264
|
+
* const speed = Math.sqrt(dx * dx + dy * dy);
|
|
265
|
+
* const count = Math.max(1, Math.ceil(speed * 1.5));
|
|
266
|
+
*
|
|
267
|
+
* for (let i = 0; i < count; i++) {
|
|
268
|
+
* trail.push({
|
|
269
|
+
* x: cx,
|
|
270
|
+
* y: cy,
|
|
271
|
+
* age: 0,
|
|
272
|
+
* maxAge: 15 + Math.random() * 10
|
|
273
|
+
* });
|
|
274
|
+
* }
|
|
275
|
+
*
|
|
276
|
+
* lastMouse = { x: cx, y: cy };
|
|
277
|
+
* if (trail.length > maxTrail) trail.splice(0, trail.length - maxTrail);
|
|
278
|
+
* });
|
|
279
|
+
*
|
|
280
|
+
* t.draw(() => {
|
|
281
|
+
* t.background(0);
|
|
282
|
+
*
|
|
283
|
+
* // Draw and age particles
|
|
284
|
+
* for (let i = trail.length - 1; i >= 0; i--) {
|
|
285
|
+
* const p = trail[i];
|
|
286
|
+
* p.age++;
|
|
287
|
+
*
|
|
288
|
+
* if (p.age >= p.maxAge) {
|
|
289
|
+
* trail.splice(i, 1);
|
|
290
|
+
* continue;
|
|
291
|
+
* }
|
|
292
|
+
*
|
|
293
|
+
* const life = 1 - (p.age / p.maxAge);
|
|
294
|
+
* const brightness = Math.round(255 * life);
|
|
295
|
+
* const chars = ['.', '*', 'o', '@'];
|
|
296
|
+
* const idx = Math.floor(life * chars.length);
|
|
297
|
+
*
|
|
298
|
+
* t.push();
|
|
299
|
+
* t.charColor(brightness, brightness * 0.6, 255);
|
|
300
|
+
* t.translate(p.x, p.y);
|
|
301
|
+
* t.char(chars[Math.min(idx, chars.length - 1)]);
|
|
302
|
+
* t.point();
|
|
303
|
+
* t.pop();
|
|
304
|
+
* }
|
|
305
|
+
* });
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
mouseMoved(callback: MouseEventHandler): void;
|
|
309
|
+
/**
|
|
310
|
+
* Set a callback function that will be called when the mouse wheel is scrolled.
|
|
311
|
+
*
|
|
312
|
+
* @param callback The function to call when the mouse wheel is scrolled
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```javascript
|
|
316
|
+
* // Scroll to create expanding rings.
|
|
317
|
+
*
|
|
318
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
319
|
+
*
|
|
320
|
+
* const rings = [];
|
|
321
|
+
*
|
|
322
|
+
* t.mouseScrolled((data) => {
|
|
323
|
+
* if (data.position.x === -1 || data.position.y === -1) return;
|
|
324
|
+
*
|
|
325
|
+
* const cx = Math.round(data.position.x - (t.grid.cols - 1) / 2);
|
|
326
|
+
* const cy = Math.round(data.position.y - (t.grid.rows - 1) / 2);
|
|
327
|
+
*
|
|
328
|
+
* // Use scroll delta to determine ring intensity and direction
|
|
329
|
+
* const scrollSpeed = 2;
|
|
330
|
+
* const intensity = Math.min(scrollSpeed * 30, 255);
|
|
331
|
+
* const scrollDown = (data.delta?.y || 0) > 0;
|
|
332
|
+
*
|
|
333
|
+
* rings.push({
|
|
334
|
+
* x: cx,
|
|
335
|
+
* y: cy,
|
|
336
|
+
* radius: 1,
|
|
337
|
+
* maxRadius: 5 + scrollSpeed * 0.5,
|
|
338
|
+
* color: intensity,
|
|
339
|
+
* scrollDown: scrollDown,
|
|
340
|
+
* age: 0,
|
|
341
|
+
* maxAge: 20
|
|
342
|
+
* });
|
|
343
|
+
* });
|
|
344
|
+
*
|
|
345
|
+
* t.draw(() => {
|
|
346
|
+
* t.background(0);
|
|
347
|
+
*
|
|
348
|
+
* // Update and draw rings
|
|
349
|
+
* for (let i = rings.length - 1; i >= 0; i--) {
|
|
350
|
+
* const r = rings[i];
|
|
351
|
+
* r.age++;
|
|
352
|
+
* r.radius += (r.maxRadius - r.radius) * 0.15;
|
|
353
|
+
*
|
|
354
|
+
* if (r.age >= r.maxAge) {
|
|
355
|
+
* rings.splice(i, 1);
|
|
356
|
+
* continue;
|
|
357
|
+
* }
|
|
358
|
+
*
|
|
359
|
+
* const life = 1 - (r.age / r.maxAge);
|
|
360
|
+
* const brightness = Math.round(r.color * life);
|
|
361
|
+
*
|
|
362
|
+
* t.push();
|
|
363
|
+
* // Blue for scroll down, orange for scroll up
|
|
364
|
+
* if (r.scrollDown) {
|
|
365
|
+
* t.charColor(brightness * 0.5, brightness * 0.8, 255);
|
|
366
|
+
* } else {
|
|
367
|
+
* t.charColor(255, brightness * 0.6, brightness * 0.3);
|
|
368
|
+
* }
|
|
369
|
+
* t.translate(r.x, r.y);
|
|
370
|
+
*
|
|
371
|
+
* // Draw ring
|
|
372
|
+
* for (let a = 0; a < Math.PI * 2; a += Math.PI / 6) {
|
|
373
|
+
* const ox = Math.round(Math.cos(a) * r.radius);
|
|
374
|
+
* const oy = Math.round(Math.sin(a) * r.radius);
|
|
375
|
+
* t.push();
|
|
376
|
+
* t.translate(ox, oy);
|
|
377
|
+
* t.char('o');
|
|
378
|
+
* t.point();
|
|
379
|
+
* t.pop();
|
|
380
|
+
* }
|
|
381
|
+
* t.pop();
|
|
382
|
+
* }
|
|
383
|
+
* });
|
|
384
|
+
* ```
|
|
385
|
+
*/
|
|
386
|
+
mouseScrolled(callback: MouseEventHandler): void;
|
|
387
|
+
/**
|
|
388
|
+
* Get the current mouse position in grid coordinates.
|
|
389
|
+
*
|
|
390
|
+
* Returns the mouse position as grid cell coordinates *(column, row)*.
|
|
391
|
+
*
|
|
392
|
+
* If the mouse is outside the grid or the instance is not ready,
|
|
393
|
+
* it returns `{ x: -1, y: -1 }`.
|
|
394
|
+
*
|
|
395
|
+
* @example
|
|
396
|
+
* ```javascript
|
|
397
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
398
|
+
*
|
|
399
|
+
* t.draw(() => {
|
|
400
|
+
* t.background(0);
|
|
401
|
+
*
|
|
402
|
+
* // Convert mouse position from top-left origin to center-based origin
|
|
403
|
+
* const centerX = Math.round(t.mouse.x - (t.grid.cols - 1) / 2);
|
|
404
|
+
* const centerY = Math.round(t.mouse.y - (t.grid.rows - 1) / 2);
|
|
405
|
+
*
|
|
406
|
+
* t.translate(centerX, centerY);
|
|
407
|
+
* t.char('*');
|
|
408
|
+
* t.charColor(255, 0, 0);
|
|
409
|
+
* t.cellColor(100);
|
|
410
|
+
* t.point();
|
|
411
|
+
* });
|
|
412
|
+
* ```
|
|
413
|
+
*/
|
|
414
|
+
get mouse(): MousePosition;
|
|
415
|
+
/**
|
|
416
|
+
* Set the mouse cursor for the textmode canvas.
|
|
417
|
+
*
|
|
418
|
+
* Provide any valid CSS cursor value (e.g. 'default', 'pointer', 'crosshair', 'move', 'text', 'grab', 'grabbing',
|
|
419
|
+
* 'none', 'zoom-in', 'zoom-out', 'ns-resize', 'ew-resize', 'nwse-resize', 'nesw-resize', etc.),
|
|
420
|
+
* or a CSS `url(...)` cursor. Call with no argument or an empty string to reset to default.
|
|
421
|
+
*
|
|
422
|
+
* See MDN for all options: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```javascript
|
|
426
|
+
* const t = textmode.create({ width: 800, height: 600 });
|
|
427
|
+
* const target = { width: 30, height: 15 };
|
|
428
|
+
*
|
|
429
|
+
* t.draw(() => {
|
|
430
|
+
* t.background(0);
|
|
431
|
+
* t.charColor(255); // keep char visible
|
|
432
|
+
* t.char('*');
|
|
433
|
+
* t.rect(target.width, target.height);
|
|
434
|
+
*
|
|
435
|
+
* // Rectangle is centered at (0, 0) which is grid center
|
|
436
|
+
* // Calculate bounds relative to grid center
|
|
437
|
+
* const centerX = t.grid.cols / 2;
|
|
438
|
+
* const centerY = t.grid.rows / 2;
|
|
439
|
+
*
|
|
440
|
+
* const halfRectWidth = target.width / 2;
|
|
441
|
+
* const halfRectHeight = target.height / 2;
|
|
442
|
+
*
|
|
443
|
+
* const rectLeft = centerX - halfRectWidth;
|
|
444
|
+
* const rectRight = centerX + halfRectWidth;
|
|
445
|
+
* const rectTop = centerY - halfRectHeight;
|
|
446
|
+
* const rectBottom = centerY + halfRectHeight;
|
|
447
|
+
*
|
|
448
|
+
* const hovering =
|
|
449
|
+
* t.mouse.x >= rectLeft && t.mouse.x < rectRight &&
|
|
450
|
+
* t.mouse.y >= rectTop && t.mouse.y < rectBottom;
|
|
451
|
+
*
|
|
452
|
+
* t.cursor(hovering ? 'pointer' : 'default');
|
|
453
|
+
* });
|
|
454
|
+
* ```
|
|
455
|
+
*/
|
|
456
|
+
cursor(cursor?: string): void;
|
|
457
|
+
}
|