@automatajs/core 0.2.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/dist/engine.js ADDED
@@ -0,0 +1,255 @@
1
+ import { Grid } from "./grid";
2
+ import { Renderer } from "./renderer";
3
+ import { Interaction } from "./interaction";
4
+ import { gameOfLife } from "./presets";
5
+ /**
6
+ * Main Automata engine class.
7
+ * Orchestrates grid, renderer, simulation loop, and interaction.
8
+ *
9
+ * Usage:
10
+ * ```ts
11
+ * const ca = new Automata(canvasElement, {
12
+ * cols: 80,
13
+ * rows: 60,
14
+ * fps: 10,
15
+ * rule: gameOfLife,
16
+ * });
17
+ * ca.randomize(0.3);
18
+ * ca.play();
19
+ * ```
20
+ */
21
+ export class Automata {
22
+ constructor(canvas, options = {}) {
23
+ this._generation = 0;
24
+ this._playing = false;
25
+ this.animFrameId = null;
26
+ this.lastFrameTime = 0;
27
+ // Callbacks
28
+ this.onStepCallbacks = [];
29
+ const cols = options.cols ?? 80;
30
+ const rows = options.rows ?? 60;
31
+ this.grid = new Grid(cols, rows, {
32
+ wrap: options.wrap ?? true,
33
+ neighborhood: options.neighborhood ?? "moore",
34
+ });
35
+ this.renderer = new Renderer(canvas, {
36
+ aliveColor: options.aliveColor,
37
+ deadColor: options.deadColor,
38
+ backgroundColor: options.backgroundColor,
39
+ gridLineColor: options.gridLineColor,
40
+ showGridLines: options.showGridLines,
41
+ cellSize: options.cellSize,
42
+ });
43
+ this.interaction = new Interaction(canvas, this.renderer, this.grid);
44
+ this.rule = options.rule ?? gameOfLife;
45
+ this._fps = options.fps ?? 10;
46
+ // Set style function if provided
47
+ if (options.style) {
48
+ this.renderer.styleFunction = options.style;
49
+ }
50
+ // Save initial state
51
+ this.initialGrid = new Uint8Array(cols * rows);
52
+ // Auto-resize canvas
53
+ this.renderer.resizeToContainer();
54
+ // Initial render
55
+ this.render();
56
+ }
57
+ // ─── Grid Management ───
58
+ /** Get the underlying grid. */
59
+ getGrid() {
60
+ return this.grid;
61
+ }
62
+ /** Create a new grid, replacing the current one. */
63
+ createGrid(cols, rows) {
64
+ this.grid = new Grid(cols, rows, {
65
+ wrap: this.grid.wrap,
66
+ neighborhood: this.grid.neighborhood,
67
+ });
68
+ this.initialGrid = new Uint8Array(cols * rows);
69
+ this.interaction.setGrid(this.grid);
70
+ this._generation = 0;
71
+ this.render();
72
+ }
73
+ /** Clear the grid. */
74
+ clearGrid() {
75
+ this.grid.clear();
76
+ this._generation = 0;
77
+ this.render();
78
+ }
79
+ /** Randomize the grid. */
80
+ randomize(density = 0.3) {
81
+ this.grid.randomize(density);
82
+ this.initialGrid.set(this.grid.current);
83
+ this._generation = 0;
84
+ this.render();
85
+ }
86
+ /** Get cell state. */
87
+ getCell(x, y) {
88
+ return this.grid.get(x, y);
89
+ }
90
+ /** Set cell state. */
91
+ setCell(x, y, state) {
92
+ this.grid.set(x, y, state);
93
+ this.render();
94
+ }
95
+ /** Toggle cell state. */
96
+ toggleCell(x, y) {
97
+ this.grid.toggle(x, y);
98
+ this.render();
99
+ }
100
+ /** Stamp a pattern onto the grid. */
101
+ stamp(pattern, offsetX, offsetY) {
102
+ this.grid.stamp(pattern, offsetX, offsetY);
103
+ this.render();
104
+ }
105
+ // ─── Simulation ───
106
+ /** Set the rule function. */
107
+ setRule(rule) {
108
+ this.rule = rule;
109
+ }
110
+ /** Set the style function for per-cell coloring. Pass null to reset to default. */
111
+ setStyle(style) {
112
+ this.renderer.styleFunction = style;
113
+ this.render();
114
+ }
115
+ /** Advance one generation. */
116
+ step() {
117
+ this.grid.step(this.rule);
118
+ this._generation++;
119
+ this.render();
120
+ for (const cb of this.onStepCallbacks) {
121
+ cb(this._generation);
122
+ }
123
+ }
124
+ /** Start the simulation loop. */
125
+ play() {
126
+ if (this._playing)
127
+ return;
128
+ this._playing = true;
129
+ this.lastFrameTime = performance.now();
130
+ this.loop();
131
+ }
132
+ /** Pause the simulation. */
133
+ pause() {
134
+ this._playing = false;
135
+ if (this.animFrameId !== null) {
136
+ cancelAnimationFrame(this.animFrameId);
137
+ this.animFrameId = null;
138
+ }
139
+ }
140
+ /** Reset to initial state (from last randomize or manual setup). */
141
+ reset() {
142
+ this.pause();
143
+ this.grid.current.set(this.initialGrid);
144
+ this.grid.next.fill(0);
145
+ this._generation = 0;
146
+ this.render();
147
+ }
148
+ /** Save the current grid state as the initial state. */
149
+ saveState() {
150
+ this.initialGrid.set(this.grid.current);
151
+ }
152
+ /** Is the simulation running? */
153
+ get playing() {
154
+ return this._playing;
155
+ }
156
+ /** Current generation count. */
157
+ get generation() {
158
+ return this._generation;
159
+ }
160
+ /** Get the current FPS setting. */
161
+ get fps() {
162
+ return this._fps;
163
+ }
164
+ /** Set the target frames per second. */
165
+ setFrameRate(fps) {
166
+ this._fps = Math.max(1, Math.min(120, fps));
167
+ }
168
+ /** Population count. */
169
+ get population() {
170
+ return this.grid.population();
171
+ }
172
+ /** Grid dimensions. */
173
+ get cols() {
174
+ return this.grid.cols;
175
+ }
176
+ get rows() {
177
+ return this.grid.rows;
178
+ }
179
+ /** Register a callback after each step. */
180
+ onStep(fn) {
181
+ this.onStepCallbacks.push(fn);
182
+ }
183
+ // ─── Rendering ───
184
+ /** Force a re-render. */
185
+ render() {
186
+ this.renderer.render(this.grid);
187
+ }
188
+ /** Resize the canvas to fit its container. */
189
+ resize() {
190
+ this.renderer.resizeToContainer();
191
+ this.render();
192
+ }
193
+ /** Set alive cell color. */
194
+ setAliveColor(color) {
195
+ this.renderer.aliveColor = color;
196
+ this.render();
197
+ }
198
+ /** Set dead cell color. */
199
+ setDeadColor(color) {
200
+ this.renderer.deadColor = color;
201
+ this.render();
202
+ }
203
+ /** Set background color. */
204
+ setBackground(color) {
205
+ this.renderer.backgroundColor = color;
206
+ this.render();
207
+ }
208
+ /** Toggle grid lines on/off. */
209
+ toggleGridLines(show) {
210
+ this.renderer.showGridLines = show ?? !this.renderer.showGridLines;
211
+ this.render();
212
+ }
213
+ /** Export canvas as data URL. */
214
+ toDataURL(format) {
215
+ return this.renderer.toDataURL(format);
216
+ }
217
+ // ─── Interaction ───
218
+ /** Set custom cell click handler. */
219
+ onCellClick(fn) {
220
+ this.interaction.onCellClick(fn);
221
+ }
222
+ /** Set custom cell drag handler. */
223
+ onCellDrag(fn) {
224
+ this.interaction.onCellDrag(fn);
225
+ }
226
+ /** Enable mouse/touch interaction. */
227
+ enableInteraction() {
228
+ this.interaction.enable();
229
+ }
230
+ /** Disable mouse/touch interaction. */
231
+ disableInteraction() {
232
+ this.interaction.disable();
233
+ }
234
+ // ─── Lifecycle ───
235
+ /** Clean up all resources. */
236
+ destroy() {
237
+ this.pause();
238
+ this.interaction.destroy();
239
+ }
240
+ // ─── Private ───
241
+ loop() {
242
+ if (!this._playing)
243
+ return;
244
+ this.animFrameId = requestAnimationFrame((now) => {
245
+ const interval = 1000 / this._fps;
246
+ const elapsed = now - this.lastFrameTime;
247
+ if (elapsed >= interval) {
248
+ this.lastFrameTime = now - (elapsed % interval);
249
+ this.step();
250
+ }
251
+ this.loop();
252
+ });
253
+ }
254
+ }
255
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/dist/grid.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ import type { GridOptions, NeighborhoodType, RuleFunction, CellContext } from "./types";
2
+ /**
3
+ * Double-buffered grid backed by Uint8Array.
4
+ * Supports toroidal wrapping and Moore/Von Neumann neighborhoods.
5
+ */
6
+ export declare class Grid {
7
+ readonly cols: number;
8
+ readonly rows: number;
9
+ readonly wrap: boolean;
10
+ readonly neighborhood: NeighborhoodType;
11
+ /** Current generation buffer */
12
+ current: Uint8Array;
13
+ /** Next generation buffer (written to during step, then swapped) */
14
+ next: Uint8Array;
15
+ private mooreOffsets;
16
+ private vonNeumannOffsets;
17
+ constructor(cols: number, rows: number, options?: GridOptions);
18
+ /** Get cell state at (x, y). Returns 0 for out-of-bounds when wrap=false. */
19
+ get(x: number, y: number): number;
20
+ /** Set cell state at (x, y) in the current buffer. */
21
+ set(x: number, y: number, state: number): void;
22
+ /** Toggle cell at (x, y) between 0 and 1. */
23
+ toggle(x: number, y: number): void;
24
+ /** Get individual neighbor state values for the cell at (x, y). */
25
+ getNeighborValues(x: number, y: number): number[];
26
+ /** Count alive neighbors for the cell at (x, y). */
27
+ countNeighbors(x: number, y: number): number;
28
+ /** Build a CellContext for the cell at (x, y). */
29
+ buildContext(x: number, y: number): CellContext;
30
+ /**
31
+ * Detect whether a rule function uses the new CellContext signature
32
+ * or the legacy positional signature.
33
+ *
34
+ * New-style: function(ctx) — 1 parameter
35
+ * Legacy: function(neighbors, currentState, x, y, grid) — 5 parameters
36
+ */
37
+ private static isLegacyRule;
38
+ /** Apply rule to all cells: write to next buffer, then swap. */
39
+ step(rule: RuleFunction): void;
40
+ /** Swap current and next buffers. */
41
+ private swap;
42
+ /** Clear both buffers. */
43
+ clear(): void;
44
+ /** Randomize the grid with a given density (0–1, default 0.3). */
45
+ randomize(density?: number): void;
46
+ /** Return total number of alive cells. */
47
+ population(): number;
48
+ /** Create a deep copy of this grid. */
49
+ clone(): Grid;
50
+ /** Load a 2D pattern array at the given offset. */
51
+ stamp(pattern: number[][], offsetX?: number, offsetY?: number): void;
52
+ /** Export current state as a 2D array. */
53
+ toArray(): number[][];
54
+ }
55
+ //# sourceMappingURL=grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAExF;;;GAGG;AACH,qBAAa,IAAI;IACf,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IAExC,gCAAgC;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,oEAAoE;IACpE,IAAI,EAAE,UAAU,CAAC;IAGjB,OAAO,CAAC,YAAY,CASlB;IAEF,OAAO,CAAC,iBAAiB,CAKvB;gBAEU,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IASjE,6EAA6E;IAC7E,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAUjC,sDAAsD;IACtD,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAK9C,6CAA6C;IAC7C,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAMlC,mEAAmE;IACnE,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAajD,oDAAoD;IACpD,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAa5C,kDAAkD;IAClD,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW;IAmB/C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAI3B,gEAAgE;IAChE,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IA0B9B,qCAAqC;IACrC,OAAO,CAAC,IAAI;IAMZ,0BAA0B;IAC1B,KAAK,IAAI,IAAI;IAKb,kEAAkE;IAClE,SAAS,CAAC,OAAO,GAAE,MAAY,GAAG,IAAI;IAMtC,0CAA0C;IAC1C,UAAU,IAAI,MAAM;IAQpB,uCAAuC;IACvC,KAAK,IAAI,IAAI;IAUb,mDAAmD;IACnD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAE,MAAU,EAAE,OAAO,GAAE,MAAU,GAAG,IAAI;IAY1E,0CAA0C;IAC1C,OAAO,IAAI,MAAM,EAAE,EAAE;CAWtB"}
package/dist/grid.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Double-buffered grid backed by Uint8Array.
3
+ * Supports toroidal wrapping and Moore/Von Neumann neighborhoods.
4
+ */
5
+ export class Grid {
6
+ constructor(cols, rows, options = {}) {
7
+ // Precomputed neighbor offset tables
8
+ this.mooreOffsets = [
9
+ [-1, -1],
10
+ [0, -1],
11
+ [1, -1],
12
+ [-1, 0],
13
+ [1, 0],
14
+ [-1, 1],
15
+ [0, 1],
16
+ [1, 1],
17
+ ];
18
+ this.vonNeumannOffsets = [
19
+ [0, -1],
20
+ [-1, 0],
21
+ [1, 0],
22
+ [0, 1],
23
+ ];
24
+ this.cols = cols;
25
+ this.rows = rows;
26
+ this.wrap = options.wrap ?? true;
27
+ this.neighborhood = options.neighborhood ?? "moore";
28
+ this.current = new Uint8Array(cols * rows);
29
+ this.next = new Uint8Array(cols * rows);
30
+ }
31
+ /** Get cell state at (x, y). Returns 0 for out-of-bounds when wrap=false. */
32
+ get(x, y) {
33
+ if (this.wrap) {
34
+ x = ((x % this.cols) + this.cols) % this.cols;
35
+ y = ((y % this.rows) + this.rows) % this.rows;
36
+ }
37
+ else if (x < 0 || x >= this.cols || y < 0 || y >= this.rows) {
38
+ return 0;
39
+ }
40
+ return this.current[y * this.cols + x];
41
+ }
42
+ /** Set cell state at (x, y) in the current buffer. */
43
+ set(x, y, state) {
44
+ if (x < 0 || x >= this.cols || y < 0 || y >= this.rows)
45
+ return;
46
+ this.current[y * this.cols + x] = state;
47
+ }
48
+ /** Toggle cell at (x, y) between 0 and 1. */
49
+ toggle(x, y) {
50
+ if (x < 0 || x >= this.cols || y < 0 || y >= this.rows)
51
+ return;
52
+ const idx = y * this.cols + x;
53
+ this.current[idx] = this.current[idx] ? 0 : 1;
54
+ }
55
+ /** Get individual neighbor state values for the cell at (x, y). */
56
+ getNeighborValues(x, y) {
57
+ const offsets = this.neighborhood === "moore"
58
+ ? this.mooreOffsets
59
+ : this.vonNeumannOffsets;
60
+ const values = [];
61
+ for (const [dx, dy] of offsets) {
62
+ values.push(this.get(x + dx, y + dy));
63
+ }
64
+ return values;
65
+ }
66
+ /** Count alive neighbors for the cell at (x, y). */
67
+ countNeighbors(x, y) {
68
+ const offsets = this.neighborhood === "moore"
69
+ ? this.mooreOffsets
70
+ : this.vonNeumannOffsets;
71
+ let count = 0;
72
+ for (const [dx, dy] of offsets) {
73
+ count += this.get(x + dx, y + dy) > 0 ? 1 : 0;
74
+ }
75
+ return count;
76
+ }
77
+ /** Build a CellContext for the cell at (x, y). */
78
+ buildContext(x, y) {
79
+ const neighborValues = this.getNeighborValues(x, y);
80
+ let neighborCount = 0;
81
+ for (const v of neighborValues) {
82
+ if (v > 0)
83
+ neighborCount++;
84
+ }
85
+ return {
86
+ self: this.current[y * this.cols + x],
87
+ x,
88
+ y,
89
+ neighborCount,
90
+ neighbors: neighborValues,
91
+ get: (gx, gy) => this.get(gx, gy),
92
+ cols: this.cols,
93
+ rows: this.rows,
94
+ };
95
+ }
96
+ /**
97
+ * Detect whether a rule function uses the new CellContext signature
98
+ * or the legacy positional signature.
99
+ *
100
+ * New-style: function(ctx) — 1 parameter
101
+ * Legacy: function(neighbors, currentState, x, y, grid) — 5 parameters
102
+ */
103
+ static isLegacyRule(rule) {
104
+ return rule.length > 1;
105
+ }
106
+ /** Apply rule to all cells: write to next buffer, then swap. */
107
+ step(rule) {
108
+ const legacy = Grid.isLegacyRule(rule);
109
+ for (let y = 0; y < this.rows; y++) {
110
+ for (let x = 0; x < this.cols; x++) {
111
+ if (legacy) {
112
+ // Legacy signature: (neighbors, currentState, x, y, grid)
113
+ const neighbors = this.countNeighbors(x, y);
114
+ const currentState = this.current[y * this.cols + x];
115
+ this.next[y * this.cols + x] = rule(neighbors, currentState, x, y, this.current);
116
+ }
117
+ else {
118
+ // New CellContext signature
119
+ const ctx = this.buildContext(x, y);
120
+ this.next[y * this.cols + x] = rule(ctx);
121
+ }
122
+ }
123
+ }
124
+ this.swap();
125
+ }
126
+ /** Swap current and next buffers. */
127
+ swap() {
128
+ const temp = this.current;
129
+ this.current = this.next;
130
+ this.next = temp;
131
+ }
132
+ /** Clear both buffers. */
133
+ clear() {
134
+ this.current.fill(0);
135
+ this.next.fill(0);
136
+ }
137
+ /** Randomize the grid with a given density (0–1, default 0.3). */
138
+ randomize(density = 0.3) {
139
+ for (let i = 0; i < this.current.length; i++) {
140
+ this.current[i] = Math.random() < density ? 1 : 0;
141
+ }
142
+ }
143
+ /** Return total number of alive cells. */
144
+ population() {
145
+ let count = 0;
146
+ for (let i = 0; i < this.current.length; i++) {
147
+ count += this.current[i];
148
+ }
149
+ return count;
150
+ }
151
+ /** Create a deep copy of this grid. */
152
+ clone() {
153
+ const g = new Grid(this.cols, this.rows, {
154
+ wrap: this.wrap,
155
+ neighborhood: this.neighborhood,
156
+ });
157
+ g.current.set(this.current);
158
+ g.next.set(this.next);
159
+ return g;
160
+ }
161
+ /** Load a 2D pattern array at the given offset. */
162
+ stamp(pattern, offsetX = 0, offsetY = 0) {
163
+ for (let py = 0; py < pattern.length; py++) {
164
+ for (let px = 0; px < pattern[py].length; px++) {
165
+ const x = offsetX + px;
166
+ const y = offsetY + py;
167
+ if (x >= 0 && x < this.cols && y >= 0 && y < this.rows) {
168
+ this.current[y * this.cols + x] = pattern[py][px];
169
+ }
170
+ }
171
+ }
172
+ }
173
+ /** Export current state as a 2D array. */
174
+ toArray() {
175
+ const arr = [];
176
+ for (let y = 0; y < this.rows; y++) {
177
+ const row = [];
178
+ for (let x = 0; x < this.cols; x++) {
179
+ row.push(this.current[y * this.cols + x]);
180
+ }
181
+ arr.push(row);
182
+ }
183
+ return arr;
184
+ }
185
+ }
186
+ //# sourceMappingURL=grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.js","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * automata.js v0.2.0
3
+ *
4
+ * A focused cellular automata engine for the browser.
5
+ * Inspired by p5.js. Minimal API, instant feedback, decoupled rules and style.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Automata, gameOfLife, patterns } from "@automatajs/core";
10
+ *
11
+ * const ca = new Automata(canvas, {
12
+ * cols: 80,
13
+ * rows: 60,
14
+ * fps: 10,
15
+ * rule: gameOfLife,
16
+ * });
17
+ * ca.randomize(0.3);
18
+ * ca.play();
19
+ * ```
20
+ */
21
+ export { Automata } from "./engine";
22
+ export { Grid } from "./grid";
23
+ export { Renderer } from "./renderer";
24
+ export { Interaction } from "./interaction";
25
+ export { gameOfLife, highLife, seeds, dayAndNight, diamoeba, createRule, patterns, presets, } from "./presets";
26
+ export type { AutomataOptions, GridOptions, NeighborhoodType, RuleFunction, StyleFunction, CellContext, CellCallback, ExportOptions, RGBA, } from "./types";
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EACL,UAAU,EACV,QAAQ,EACR,KAAK,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,OAAO,GACR,MAAM,WAAW,CAAC;AAGnB,YAAY,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,YAAY,EACZ,aAAa,EACb,IAAI,GACL,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * automata.js v0.2.0
3
+ *
4
+ * A focused cellular automata engine for the browser.
5
+ * Inspired by p5.js. Minimal API, instant feedback, decoupled rules and style.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Automata, gameOfLife, patterns } from "@automatajs/core";
10
+ *
11
+ * const ca = new Automata(canvas, {
12
+ * cols: 80,
13
+ * rows: 60,
14
+ * fps: 10,
15
+ * rule: gameOfLife,
16
+ * });
17
+ * ca.randomize(0.3);
18
+ * ca.play();
19
+ * ```
20
+ */
21
+ // Core
22
+ export { Automata } from "./engine";
23
+ export { Grid } from "./grid";
24
+ export { Renderer } from "./renderer";
25
+ export { Interaction } from "./interaction";
26
+ // Presets & Patterns
27
+ export { gameOfLife, highLife, seeds, dayAndNight, diamoeba, createRule, patterns, presets, } from "./presets";
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO;AACP,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,qBAAqB;AACrB,OAAO,EACL,UAAU,EACV,QAAQ,EACR,KAAK,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,OAAO,GACR,MAAM,WAAW,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { Grid } from "./grid";
2
+ import { Renderer } from "./renderer";
3
+ import type { CellCallback } from "./types";
4
+ /**
5
+ * Handles mouse/touch interaction on the canvas.
6
+ * - Click toggles a cell
7
+ * - Drag paints alive cells
8
+ */
9
+ export declare class Interaction {
10
+ private canvas;
11
+ private renderer;
12
+ private grid;
13
+ private enabled;
14
+ private isDragging;
15
+ private lastCell;
16
+ private onClickCb;
17
+ private onDragCb;
18
+ private handleMouseDown;
19
+ private handleMouseMove;
20
+ private handleMouseUp;
21
+ private handleTouchStart;
22
+ private handleTouchMove;
23
+ private handleTouchEnd;
24
+ constructor(canvas: HTMLCanvasElement, renderer: Renderer, grid: Grid);
25
+ private attach;
26
+ /** Update grid reference (e.g., after reset). */
27
+ setGrid(grid: Grid): void;
28
+ /** Set custom click callback. */
29
+ onCellClick(fn: CellCallback): void;
30
+ /** Set custom drag callback. */
31
+ onCellDrag(fn: CellCallback): void;
32
+ enable(): void;
33
+ disable(): void;
34
+ private getCanvasCoords;
35
+ private _onMouseDown;
36
+ private _onMouseMove;
37
+ private _onMouseUp;
38
+ private _onTouchStart;
39
+ private _onTouchMove;
40
+ private _onTouchEnd;
41
+ /** Remove all event listeners. */
42
+ destroy(): void;
43
+ }
44
+ //# sourceMappingURL=interaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../src/interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,QAAQ,CAAyC;IAEzD,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,QAAQ,CAA6B;IAG7C,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,cAAc,CAAa;gBAEvB,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI;IAerE,OAAO,CAAC,MAAM;IAad,iDAAiD;IACjD,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIzB,iCAAiC;IACjC,WAAW,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI;IAInC,gCAAgC;IAChC,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI;IAIlC,MAAM,IAAI,IAAI;IAId,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,WAAW;IAKnB,kCAAkC;IAClC,OAAO,IAAI,IAAI;CAQhB"}