asciify-engine 1.0.16 → 1.0.17
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/index.cjs +238 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -3
- package/dist/index.d.ts +59 -3
- package/dist/index.js +236 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -832,7 +832,7 @@ async function asciifyVideo(source, canvas, { fontSize = 10, style = "classic",
|
|
|
832
832
|
cancelAnimationFrame(animId);
|
|
833
833
|
};
|
|
834
834
|
}
|
|
835
|
-
var EMBED_CDN_VERSION = "1.0.
|
|
835
|
+
var EMBED_CDN_VERSION = "1.0.17";
|
|
836
836
|
function buildEmbedOpts(options, rows, cols, width, height, fps, animated) {
|
|
837
837
|
const o = {
|
|
838
838
|
r: rows,
|
|
@@ -1417,6 +1417,216 @@ function renderAuroraBackground(ctx, width, height, time, mousePos = { x: 0.5, y
|
|
|
1417
1417
|
}
|
|
1418
1418
|
}
|
|
1419
1419
|
}
|
|
1420
|
+
function renderSilkBackground(ctx, width, height, time, options = {}) {
|
|
1421
|
+
const {
|
|
1422
|
+
fontSize = 13,
|
|
1423
|
+
color,
|
|
1424
|
+
accentColor = "#d4ff00",
|
|
1425
|
+
speed = 0.4,
|
|
1426
|
+
layers = 4,
|
|
1427
|
+
turbulence = 0.8,
|
|
1428
|
+
lightMode = false
|
|
1429
|
+
} = options;
|
|
1430
|
+
const charW = fontSize * 0.62;
|
|
1431
|
+
const lineH = fontSize * 1.4;
|
|
1432
|
+
const cols = Math.ceil(width / charW);
|
|
1433
|
+
const rows = Math.ceil(height / lineH);
|
|
1434
|
+
ctx.clearRect(0, 0, width, height);
|
|
1435
|
+
ctx.font = `${fontSize}px monospace`;
|
|
1436
|
+
ctx.textBaseline = "top";
|
|
1437
|
+
let cr = 255, cg = 255, cb = 255;
|
|
1438
|
+
if (lightMode) {
|
|
1439
|
+
cr = 0;
|
|
1440
|
+
cg = 0;
|
|
1441
|
+
cb = 0;
|
|
1442
|
+
}
|
|
1443
|
+
if (color) {
|
|
1444
|
+
const p = _parseColor(color);
|
|
1445
|
+
if (p) {
|
|
1446
|
+
cr = p.r;
|
|
1447
|
+
cg = p.g;
|
|
1448
|
+
cb = p.b;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
let acR = 212, acG = 255, acB = 0;
|
|
1452
|
+
const ap = _parseColor(accentColor);
|
|
1453
|
+
if (ap) {
|
|
1454
|
+
acR = ap.r;
|
|
1455
|
+
acG = ap.g;
|
|
1456
|
+
acB = ap.b;
|
|
1457
|
+
}
|
|
1458
|
+
const t = time * speed;
|
|
1459
|
+
const dirChars = ["\u2500", "\u2500", "\u254C", "\xB7", "\u254C", "\u2500", "\u2500", "\u254C", "\xB7"];
|
|
1460
|
+
for (let row = 0; row < rows; row++) {
|
|
1461
|
+
const ny = row / rows;
|
|
1462
|
+
for (let col = 0; col < cols; col++) {
|
|
1463
|
+
const nx = col / cols;
|
|
1464
|
+
let angleSum = 0;
|
|
1465
|
+
let intensitySum = 0;
|
|
1466
|
+
for (let l = 0; l < layers; l++) {
|
|
1467
|
+
const ls = _hash2(l * 13, l * 7 + 3);
|
|
1468
|
+
const ls2 = _hash2(l * 29, l * 11 + 1);
|
|
1469
|
+
const fx = 1.1 + ls * 2.4;
|
|
1470
|
+
const fy = 0.9 + ls2 * 2;
|
|
1471
|
+
const ph = ls * Math.PI * 6;
|
|
1472
|
+
const dr = (0.2 + _hash2(l * 41, l * 17) * 0.5) * (l % 2 === 0 ? 1 : -1.3);
|
|
1473
|
+
const u = Math.sin(nx * fx * Math.PI * 2 + t * dr + ph);
|
|
1474
|
+
const v = Math.cos(ny * fy * Math.PI * 2 + t * dr * 0.6 + ph * 1.7);
|
|
1475
|
+
const cross = Math.sin(nx * fy * Math.PI * turbulence + ny * fx * Math.PI * turbulence + t * dr * 0.4);
|
|
1476
|
+
angleSum += Math.atan2(v + cross * 0.3, u);
|
|
1477
|
+
intensitySum += (u * v + 1) * 0.5;
|
|
1478
|
+
}
|
|
1479
|
+
const angle = angleSum / layers;
|
|
1480
|
+
const intensity = Math.min(1, intensitySum / layers);
|
|
1481
|
+
if (intensity < 0.1) continue;
|
|
1482
|
+
const angleNorm = (angle + Math.PI) / (Math.PI * 2);
|
|
1483
|
+
const charIdx = Math.floor(angleNorm * dirChars.length) % dirChars.length;
|
|
1484
|
+
const ch = dirChars[charIdx];
|
|
1485
|
+
const isAccent = intensity > 0.8;
|
|
1486
|
+
const alpha = lightMode ? intensity * 0.16 : intensity * 0.13;
|
|
1487
|
+
ctx.fillStyle = isAccent ? `rgba(${acR},${acG},${acB},${lightMode ? 0.44 : 0.26})` : `rgba(${cr},${cg},${cb},${alpha})`;
|
|
1488
|
+
ctx.fillText(ch, col * charW, row * lineH);
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
function renderVoidBackground(ctx, width, height, time, mousePos = { x: 0.5, y: 0.5 }, options = {}) {
|
|
1493
|
+
const {
|
|
1494
|
+
fontSize = 13,
|
|
1495
|
+
chars = " \xB7:;=+*#%@",
|
|
1496
|
+
color,
|
|
1497
|
+
accentColor = "#d4ff00",
|
|
1498
|
+
speed = 1,
|
|
1499
|
+
radius = 0.38,
|
|
1500
|
+
swirl = 3,
|
|
1501
|
+
lightMode = false
|
|
1502
|
+
} = options;
|
|
1503
|
+
const charW = fontSize * 0.62;
|
|
1504
|
+
const lineH = fontSize * 1.4;
|
|
1505
|
+
const cols = Math.ceil(width / charW);
|
|
1506
|
+
const rows = Math.ceil(height / lineH);
|
|
1507
|
+
const aspect = width / height;
|
|
1508
|
+
ctx.clearRect(0, 0, width, height);
|
|
1509
|
+
ctx.font = `${fontSize}px monospace`;
|
|
1510
|
+
ctx.textBaseline = "top";
|
|
1511
|
+
let cr = 255, cg = 255, cb = 255;
|
|
1512
|
+
if (lightMode) {
|
|
1513
|
+
cr = 0;
|
|
1514
|
+
cg = 0;
|
|
1515
|
+
cb = 0;
|
|
1516
|
+
}
|
|
1517
|
+
if (color) {
|
|
1518
|
+
const p = _parseColor(color);
|
|
1519
|
+
if (p) {
|
|
1520
|
+
cr = p.r;
|
|
1521
|
+
cg = p.g;
|
|
1522
|
+
cb = p.b;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
let acR = 212, acG = 255, acB = 0;
|
|
1526
|
+
const ap = _parseColor(accentColor);
|
|
1527
|
+
if (ap) {
|
|
1528
|
+
acR = ap.r;
|
|
1529
|
+
acG = ap.g;
|
|
1530
|
+
acB = ap.b;
|
|
1531
|
+
}
|
|
1532
|
+
const t = time * speed;
|
|
1533
|
+
for (let row = 0; row < rows; row++) {
|
|
1534
|
+
const ny = row / rows;
|
|
1535
|
+
for (let col = 0; col < cols; col++) {
|
|
1536
|
+
const nx = col / cols;
|
|
1537
|
+
const dx = (nx - mousePos.x) * aspect;
|
|
1538
|
+
const dy = ny - mousePos.y;
|
|
1539
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
1540
|
+
const r = dist / radius;
|
|
1541
|
+
if (r > 1) {
|
|
1542
|
+
const outerNoise = _hash2(col * 3, row * 7) * Math.max(0, 1 - (r - 1) * 3);
|
|
1543
|
+
if (outerNoise < 0.62) continue;
|
|
1544
|
+
const alpha2 = outerNoise * (lightMode ? 0.05 : 0.04);
|
|
1545
|
+
const ch2 = chars[1];
|
|
1546
|
+
ctx.fillStyle = `rgba(${cr},${cg},${cb},${alpha2})`;
|
|
1547
|
+
ctx.fillText(ch2, col * charW, row * lineH);
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
const baseAngle = Math.atan2(dy, dx * aspect);
|
|
1551
|
+
const swirlAmt = (1 - r) * swirl;
|
|
1552
|
+
const angle = baseAngle + swirlAmt + t * 0.4;
|
|
1553
|
+
const pulseRing = Math.max(0, 1 - Math.abs(r - (0.15 + 0.12 * Math.sin(t * 1.1))) / 0.07);
|
|
1554
|
+
const gravity = Math.pow(1 - r, 2.2);
|
|
1555
|
+
const intensity = Math.min(1, gravity + pulseRing * 0.6);
|
|
1556
|
+
if (intensity < 0.06) continue;
|
|
1557
|
+
const angleIdx = Math.floor((angle % (Math.PI * 2) + Math.PI * 2) % (Math.PI * 2) / (Math.PI * 2) * 4);
|
|
1558
|
+
const densityI = Math.floor(intensity * (chars.length - 1));
|
|
1559
|
+
const charIdx = Math.min(chars.length - 1, densityI);
|
|
1560
|
+
const ch = chars[charIdx + (angleIdx > 2 && densityI > 2 ? 0 : 0)];
|
|
1561
|
+
const isAccent = pulseRing > 0.35 || r < 0.08;
|
|
1562
|
+
const alpha = lightMode ? intensity * 0.22 : intensity * 0.18;
|
|
1563
|
+
ctx.fillStyle = isAccent ? `rgba(${acR},${acG},${acB},${lightMode ? 0.55 : 0.38})` : `rgba(${cr},${cg},${cb},${alpha})`;
|
|
1564
|
+
ctx.fillText(ch, col * charW, row * lineH);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
function renderMorphBackground(ctx, width, height, time, options = {}) {
|
|
1569
|
+
const {
|
|
1570
|
+
fontSize = 14,
|
|
1571
|
+
chars = " \xB7\u2219\u2022:-=+*#",
|
|
1572
|
+
color,
|
|
1573
|
+
accentColor = "#d4ff00",
|
|
1574
|
+
speed = 0.5,
|
|
1575
|
+
harmonics = 3,
|
|
1576
|
+
lightMode = false
|
|
1577
|
+
} = options;
|
|
1578
|
+
const charW = fontSize * 0.62;
|
|
1579
|
+
const lineH = fontSize * 1.4;
|
|
1580
|
+
const cols = Math.ceil(width / charW);
|
|
1581
|
+
const rows = Math.ceil(height / lineH);
|
|
1582
|
+
ctx.clearRect(0, 0, width, height);
|
|
1583
|
+
ctx.font = `${fontSize}px monospace`;
|
|
1584
|
+
ctx.textBaseline = "top";
|
|
1585
|
+
let cr = 255, cg = 255, cb = 255;
|
|
1586
|
+
if (lightMode) {
|
|
1587
|
+
cr = 0;
|
|
1588
|
+
cg = 0;
|
|
1589
|
+
cb = 0;
|
|
1590
|
+
}
|
|
1591
|
+
if (color) {
|
|
1592
|
+
const p = _parseColor(color);
|
|
1593
|
+
if (p) {
|
|
1594
|
+
cr = p.r;
|
|
1595
|
+
cg = p.g;
|
|
1596
|
+
cb = p.b;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
let acR = 212, acG = 255, acB = 0;
|
|
1600
|
+
const ap = _parseColor(accentColor);
|
|
1601
|
+
if (ap) {
|
|
1602
|
+
acR = ap.r;
|
|
1603
|
+
acG = ap.g;
|
|
1604
|
+
acB = ap.b;
|
|
1605
|
+
}
|
|
1606
|
+
const t = time * speed;
|
|
1607
|
+
for (let row = 0; row < rows; row++) {
|
|
1608
|
+
for (let col = 0; col < cols; col++) {
|
|
1609
|
+
let v = 0;
|
|
1610
|
+
for (let h = 0; h < harmonics; h++) {
|
|
1611
|
+
const fBase = _hash2(col * (h + 3) + 7, row * (h + 5) + 11);
|
|
1612
|
+
const fineF = 0.18 + fBase * 1.4;
|
|
1613
|
+
const phase = _hash2(col * (h + 7), row * (h + 9) + 3) * Math.PI * 2;
|
|
1614
|
+
const weight = 1 / (h + 1);
|
|
1615
|
+
v += Math.sin(t * fineF + phase) * weight;
|
|
1616
|
+
}
|
|
1617
|
+
const maxV = Array.from({ length: harmonics }, (_, h) => 1 / (h + 1)).reduce((a, b) => a + b, 0);
|
|
1618
|
+
const norm = (v / maxV + 1) * 0.5;
|
|
1619
|
+
if (norm < 0.28) continue;
|
|
1620
|
+
const remapped = (norm - 0.28) / 0.72;
|
|
1621
|
+
const charIdx = Math.min(chars.length - 1, Math.floor(remapped * chars.length));
|
|
1622
|
+
const ch = chars[charIdx];
|
|
1623
|
+
const isAccent = norm > 0.88;
|
|
1624
|
+
const alpha = lightMode ? remapped * 0.17 : remapped * 0.13;
|
|
1625
|
+
ctx.fillStyle = isAccent ? `rgba(${acR},${acG},${acB},${lightMode ? 0.45 : 0.28})` : `rgba(${cr},${cg},${cb},${alpha})`;
|
|
1626
|
+
ctx.fillText(ch, col * charW, row * lineH);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1420
1630
|
function _parseColor(c) {
|
|
1421
1631
|
const hex = c.match(/^#([0-9a-f]{3,8})$/i)?.[1];
|
|
1422
1632
|
if (hex) {
|
|
@@ -1505,6 +1715,21 @@ function asciiBackground(target, options = {}) {
|
|
|
1505
1715
|
lightMode: renderOpts.lightMode !== void 0 ? renderOpts.lightMode : isLight(),
|
|
1506
1716
|
color: color ?? renderOpts.color
|
|
1507
1717
|
});
|
|
1718
|
+
const buildSilkOpts = () => ({
|
|
1719
|
+
...renderOpts,
|
|
1720
|
+
lightMode: renderOpts.lightMode !== void 0 ? renderOpts.lightMode : isLight(),
|
|
1721
|
+
color: color ?? renderOpts.color
|
|
1722
|
+
});
|
|
1723
|
+
const buildVoidOpts = () => ({
|
|
1724
|
+
...renderOpts,
|
|
1725
|
+
lightMode: renderOpts.lightMode !== void 0 ? renderOpts.lightMode : isLight(),
|
|
1726
|
+
color: color ?? renderOpts.color
|
|
1727
|
+
});
|
|
1728
|
+
const buildMorphOpts = () => ({
|
|
1729
|
+
...renderOpts,
|
|
1730
|
+
lightMode: renderOpts.lightMode !== void 0 ? renderOpts.lightMode : isLight(),
|
|
1731
|
+
color: color ?? renderOpts.color
|
|
1732
|
+
});
|
|
1508
1733
|
const optsRef = { current: buildWaveOpts() };
|
|
1509
1734
|
const rebuildOpts = () => {
|
|
1510
1735
|
if (type === "rain") optsRef.current = buildRainOpts();
|
|
@@ -1513,6 +1738,9 @@ function asciiBackground(target, options = {}) {
|
|
|
1513
1738
|
else if (type === "noise") optsRef.current = buildNoiseOpts();
|
|
1514
1739
|
else if (type === "grid") optsRef.current = buildGridOpts();
|
|
1515
1740
|
else if (type === "aurora") optsRef.current = buildAuroraOpts();
|
|
1741
|
+
else if (type === "silk") optsRef.current = buildSilkOpts();
|
|
1742
|
+
else if (type === "void") optsRef.current = buildVoidOpts();
|
|
1743
|
+
else if (type === "morph") optsRef.current = buildMorphOpts();
|
|
1516
1744
|
else optsRef.current = buildWaveOpts();
|
|
1517
1745
|
};
|
|
1518
1746
|
rebuildOpts();
|
|
@@ -1553,6 +1781,12 @@ function asciiBackground(target, options = {}) {
|
|
|
1553
1781
|
renderGridBackground(ctx, r.width, r.height, time, smoothMouse, optsRef.current);
|
|
1554
1782
|
} else if (type === "aurora") {
|
|
1555
1783
|
renderAuroraBackground(ctx, r.width, r.height, time, smoothMouse, optsRef.current);
|
|
1784
|
+
} else if (type === "silk") {
|
|
1785
|
+
renderSilkBackground(ctx, r.width, r.height, time, optsRef.current);
|
|
1786
|
+
} else if (type === "void") {
|
|
1787
|
+
renderVoidBackground(ctx, r.width, r.height, time, smoothMouse, optsRef.current);
|
|
1788
|
+
} else if (type === "morph") {
|
|
1789
|
+
renderMorphBackground(ctx, r.width, r.height, time, optsRef.current);
|
|
1556
1790
|
} else {
|
|
1557
1791
|
renderWaveBackground(ctx, r.width, r.height, time, smoothMouse, optsRef.current);
|
|
1558
1792
|
}
|
|
@@ -2037,10 +2271,13 @@ exports.mountWaveBackground = mountWaveBackground;
|
|
|
2037
2271
|
exports.renderAuroraBackground = renderAuroraBackground;
|
|
2038
2272
|
exports.renderFrameToCanvas = renderFrameToCanvas;
|
|
2039
2273
|
exports.renderGridBackground = renderGridBackground;
|
|
2274
|
+
exports.renderMorphBackground = renderMorphBackground;
|
|
2040
2275
|
exports.renderNoiseBackground = renderNoiseBackground;
|
|
2041
2276
|
exports.renderPulseBackground = renderPulseBackground;
|
|
2042
2277
|
exports.renderRainBackground = renderRainBackground;
|
|
2278
|
+
exports.renderSilkBackground = renderSilkBackground;
|
|
2043
2279
|
exports.renderStarsBackground = renderStarsBackground;
|
|
2280
|
+
exports.renderVoidBackground = renderVoidBackground;
|
|
2044
2281
|
exports.renderWaveBackground = renderWaveBackground;
|
|
2045
2282
|
exports.tryCreateWebGLRenderer = tryCreateWebGLRenderer;
|
|
2046
2283
|
exports.videoToAsciiFrames = videoToAsciiFrames;
|