asciify-engine 1.0.45 → 1.0.46
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/README.md +41 -0
- package/dist/index.cjs +29 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -131,6 +131,47 @@ All conversion and render functions accept an `AsciiOptions` object. Spread `DEF
|
|
|
131
131
|
| `hoverEffect` | `string` | `'none'` | Interactive effect driven by cursor position. See hover effects below. |
|
|
132
132
|
| `hoverStrength` | `number` | `0.8` | Effect intensity (0–1). |
|
|
133
133
|
| `hoverRadius` | `number` | `0.3` | Effect radius relative to canvas size (0–1). |
|
|
134
|
+
| `chromaKey` | `{r,g,b} \| string \| null` | `null` | Remove a background colour (green/blue screen). Keyed pixels become transparent spaces. Accepts `{r,g,b}`, any CSS colour string, or `null` to disable. |
|
|
135
|
+
| `chromaKeyTolerance` | `number` | `60` | Euclidean RGB distance threshold for chroma-key detection. `0` = exact match, higher = more pixels removed (max useful ~100). |
|
|
136
|
+
|
|
137
|
+
### Chroma Key (Green/Blue Screen)
|
|
138
|
+
|
|
139
|
+
Remove a solid background colour from any source — images, GIFs, or video — so the canvas background shows through keyed pixels.
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import { asciify, DEFAULT_OPTIONS } from 'asciify-engine';
|
|
143
|
+
|
|
144
|
+
// Green screen
|
|
145
|
+
asciify(img, canvas, {
|
|
146
|
+
options: {
|
|
147
|
+
...DEFAULT_OPTIONS,
|
|
148
|
+
chromaKey: '#00ff00', // CSS colour string — hex, rgb(), named all work
|
|
149
|
+
chromaKeyTolerance: 60, // tune to your footage (0 = exact, ~80 = loose)
|
|
150
|
+
colorMode: 'fullcolor',
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Blue screen
|
|
155
|
+
asciify(img, canvas, {
|
|
156
|
+
options: { ...DEFAULT_OPTIONS, chromaKey: 'blue', chromaKeyTolerance: 70 },
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Custom RGB key
|
|
160
|
+
asciify(img, canvas, {
|
|
161
|
+
options: { ...DEFAULT_OPTIONS, chromaKey: { r: 0, g: 180, b: 90 }, chromaKeyTolerance: 50 },
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Live video with green screen
|
|
165
|
+
asciifyVideo('/footage.mp4', canvas, {
|
|
166
|
+
fitTo: '#container',
|
|
167
|
+
options: { ...DEFAULT_OPTIONS, chromaKey: '#00b140', chromaKeyTolerance: 65, colorMode: 'fullcolor' },
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Tolerance guide:**
|
|
172
|
+
- `40–60` — tight key, natural green screen under good lighting
|
|
173
|
+
- `60–80` — broader key, wrinkled fabric or uneven lighting
|
|
174
|
+
- `80–120` — aggressive; expect some spill into the subject
|
|
134
175
|
|
|
135
176
|
### Color Modes
|
|
136
177
|
|
package/dist/index.cjs
CHANGED
|
@@ -119,7 +119,9 @@ var DEFAULT_OPTIONS = {
|
|
|
119
119
|
hoverEffect: "spotlight",
|
|
120
120
|
hoverColor: "#ffffff",
|
|
121
121
|
artStyle: "classic",
|
|
122
|
-
customText: ""
|
|
122
|
+
customText: "",
|
|
123
|
+
chromaKey: null,
|
|
124
|
+
chromaKeyTolerance: 60
|
|
123
125
|
};
|
|
124
126
|
var HOVER_PRESETS = {
|
|
125
127
|
none: {
|
|
@@ -258,6 +260,17 @@ function getCellColorRGB(cell, colorMode, acR, acG, acB) {
|
|
|
258
260
|
}
|
|
259
261
|
return _colorRGB;
|
|
260
262
|
}
|
|
263
|
+
function parseChromaKeyColor(color) {
|
|
264
|
+
if (typeof color !== "string") return color;
|
|
265
|
+
const canvas = document.createElement("canvas");
|
|
266
|
+
canvas.width = 1;
|
|
267
|
+
canvas.height = 1;
|
|
268
|
+
const ctx = canvas.getContext("2d");
|
|
269
|
+
ctx.fillStyle = color;
|
|
270
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
271
|
+
const d = ctx.getImageData(0, 0, 1, 1).data;
|
|
272
|
+
return { r: d[0], g: d[1], b: d[2] };
|
|
273
|
+
}
|
|
261
274
|
|
|
262
275
|
// src/core/animation.ts
|
|
263
276
|
function smoothstep(t) {
|
|
@@ -635,6 +648,12 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
|
|
|
635
648
|
normRange = hi > lo ? hi - lo : 255;
|
|
636
649
|
}
|
|
637
650
|
const frame = [];
|
|
651
|
+
let ckRGB = null;
|
|
652
|
+
let ckTolSq = 0;
|
|
653
|
+
if (options.chromaKey != null) {
|
|
654
|
+
ckRGB = parseChromaKeyColor(options.chromaKey);
|
|
655
|
+
ckTolSq = (options.chromaKeyTolerance ?? 60) ** 2;
|
|
656
|
+
}
|
|
638
657
|
for (let y = 0; y < rows; y++) {
|
|
639
658
|
const row = [];
|
|
640
659
|
for (let x = 0; x < cols; x++) {
|
|
@@ -643,6 +662,15 @@ function imageToAsciiFrame(source, options, targetWidth, targetHeight) {
|
|
|
643
662
|
const g = pixels[i + 1];
|
|
644
663
|
const b = pixels[i + 2];
|
|
645
664
|
const a = pixels[i + 3];
|
|
665
|
+
if (ckRGB !== null) {
|
|
666
|
+
const dr = r - ckRGB.r;
|
|
667
|
+
const dg = g - ckRGB.g;
|
|
668
|
+
const db = b - ckRGB.b;
|
|
669
|
+
if (dr * dr + dg * dg + db * db <= ckTolSq) {
|
|
670
|
+
row.push({ char: " ", r: 0, g: 0, b: 0, a: 0 });
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
646
674
|
const rawLum = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
647
675
|
const lum = options.normalize ? (rawLum - normMin) / normRange * 255 : rawLum;
|
|
648
676
|
const adjustedLum = adjustLuminance(lum, options.brightness, options.contrast);
|