asciify-engine 1.0.5 → 1.0.7
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/embed.js +1 -0
- package/dist/index.cjs +189 -192
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -6
- package/dist/index.d.ts +78 -6
- package/dist/index.js +189 -193
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -274,6 +274,8 @@ function getAnimationMultiplier(x, y, cols, rows, time, style, speed) {
|
|
|
274
274
|
}
|
|
275
275
|
return 0.7 + 0.3 * Math.sin(sdist * 10 - t * 2);
|
|
276
276
|
}
|
|
277
|
+
case "waveField":
|
|
278
|
+
return 1;
|
|
277
279
|
default:
|
|
278
280
|
return 1;
|
|
279
281
|
}
|
|
@@ -466,6 +468,24 @@ function computeHoverEffect(nx, ny, hoverX, hoverY, hoverIntensity, strength, ce
|
|
|
466
468
|
return _hoverResult;
|
|
467
469
|
}
|
|
468
470
|
function renderFrameToCanvas(ctx, frame, options, canvasWidth, canvasHeight, time = 0, hoverPos) {
|
|
471
|
+
if (options.animationStyle === "waveField") {
|
|
472
|
+
const mouseNorm = hoverPos ? { x: hoverPos.x, y: hoverPos.y } : { x: 0.5, y: 0.5 };
|
|
473
|
+
const acHexWF = (options.accentColor || "#d4ff00").replace("#", "");
|
|
474
|
+
parseInt(acHexWF.substring(0, 2), 16) || 212;
|
|
475
|
+
parseInt(acHexWF.substring(2, 4), 16) || 255;
|
|
476
|
+
parseInt(acHexWF.substring(4, 6), 16) || 0;
|
|
477
|
+
renderWaveBackground(ctx, canvasWidth, canvasHeight, time, mouseNorm, {
|
|
478
|
+
accentColor: `#${acHexWF}`,
|
|
479
|
+
accentThreshold: 0.52,
|
|
480
|
+
mouseInfluence: options.hoverStrength > 0 ? Math.min(1, 0.3 + options.hoverStrength * 0.5) : 0.55,
|
|
481
|
+
mouseFalloff: 2.8,
|
|
482
|
+
speed: options.animationSpeed,
|
|
483
|
+
vortex: options.hoverStrength > 0,
|
|
484
|
+
sparkles: true,
|
|
485
|
+
breathe: true
|
|
486
|
+
});
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
469
489
|
const rows = frame.length;
|
|
470
490
|
if (rows === 0) return;
|
|
471
491
|
const cols = frame[0].length;
|
|
@@ -697,37 +717,30 @@ function renderFrameToCanvas(ctx, frame, options, canvasWidth, canvasHeight, tim
|
|
|
697
717
|
}
|
|
698
718
|
ctx.globalAlpha = 1;
|
|
699
719
|
}
|
|
700
|
-
function serializeFrame(frame,
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
case "matrix":
|
|
720
|
-
return `function(c){var b=Math.floor(.299*c.r+.587*c.g+.114*c.b);return 'rgb(0,'+b+',0)'}`;
|
|
721
|
-
case "accent": {
|
|
722
|
-
const hex = options.accentColor.replace("#", "");
|
|
723
|
-
const ar = parseInt(hex.substring(0, 2), 16);
|
|
724
|
-
const ag = parseInt(hex.substring(2, 4), 16);
|
|
725
|
-
const ab = parseInt(hex.substring(4, 6), 16);
|
|
726
|
-
return `function(c){var b=(.299*c.r+.587*c.g+.114*c.b)/255;return 'rgb('+Math.floor(${ar}*b)+','+Math.floor(${ag}*b)+','+Math.floor(${ab}*b)+')'}`;
|
|
720
|
+
function serializeFrame(frame, fullColor) {
|
|
721
|
+
const rows = frame.length;
|
|
722
|
+
const cols = rows > 0 ? frame[0].length : 0;
|
|
723
|
+
const stride = fullColor ? 4 : 2;
|
|
724
|
+
const buf = new Uint8Array(1 + rows * cols * stride);
|
|
725
|
+
buf[0] = stride;
|
|
726
|
+
let i = 1;
|
|
727
|
+
for (let y = 0; y < rows; y++) {
|
|
728
|
+
for (let x = 0; x < cols; x++) {
|
|
729
|
+
const cell = frame[y][x];
|
|
730
|
+
if (fullColor) {
|
|
731
|
+
buf[i++] = cell.r;
|
|
732
|
+
buf[i++] = cell.g;
|
|
733
|
+
buf[i++] = cell.b;
|
|
734
|
+
buf[i++] = cell.a;
|
|
735
|
+
} else {
|
|
736
|
+
buf[i++] = Math.round(0.299 * cell.r + 0.587 * cell.g + 0.114 * cell.b);
|
|
737
|
+
buf[i++] = cell.a;
|
|
738
|
+
}
|
|
727
739
|
}
|
|
728
|
-
default:
|
|
729
|
-
return `function(c){var g=Math.floor(.299*c.r+.587*c.g+.114*c.b);return 'rgb('+g+','+g+','+g+')'}`;
|
|
730
740
|
}
|
|
741
|
+
let binary = "";
|
|
742
|
+
for (let j = 0; j < buf.length; j++) binary += String.fromCharCode(buf[j]);
|
|
743
|
+
return btoa(binary);
|
|
731
744
|
}
|
|
732
745
|
async function asciify(source, canvas, { fontSize = 10, style = "classic", options = {} } = {}) {
|
|
733
746
|
let el;
|
|
@@ -819,188 +832,171 @@ async function asciifyVideo(source, canvas, { fontSize = 10, style = "classic",
|
|
|
819
832
|
cancelAnimationFrame(animId);
|
|
820
833
|
};
|
|
821
834
|
}
|
|
835
|
+
var EMBED_CDN_VERSION = "1.0.7";
|
|
836
|
+
function buildEmbedOpts(options, rows, cols, width, height, fps, animated) {
|
|
837
|
+
const o = {
|
|
838
|
+
r: rows,
|
|
839
|
+
c: cols,
|
|
840
|
+
w: width,
|
|
841
|
+
h: height,
|
|
842
|
+
cs: options.charset,
|
|
843
|
+
cm: options.colorMode,
|
|
844
|
+
as: options.animationStyle,
|
|
845
|
+
sp: options.animationSpeed,
|
|
846
|
+
inv: options.invert,
|
|
847
|
+
hs: options.hoverStrength,
|
|
848
|
+
hr: options.hoverRadius,
|
|
849
|
+
he: options.hoverEffect,
|
|
850
|
+
hc: options.hoverColor,
|
|
851
|
+
dr: options.dotSizeRatio,
|
|
852
|
+
dots: options.renderMode === "dots"
|
|
853
|
+
};
|
|
854
|
+
if (options.colorMode === "accent") o.ac = options.accentColor;
|
|
855
|
+
if (fps !== void 0) o.fps = fps;
|
|
856
|
+
if (animated) o.anim = true;
|
|
857
|
+
return JSON.stringify(o);
|
|
858
|
+
}
|
|
822
859
|
function generateEmbedCode(frame, options, width, height) {
|
|
823
860
|
const rows = frame.length;
|
|
824
861
|
if (rows === 0) return "";
|
|
825
862
|
const cols = frame[0].length;
|
|
826
863
|
const isDots = options.renderMode === "dots";
|
|
827
864
|
const data = serializeFrame(frame, !isDots);
|
|
828
|
-
const
|
|
829
|
-
const
|
|
830
|
-
const charset = isDots ? "" : options.charset;
|
|
831
|
-
const hc = options.hoverColor || "#ffffff";
|
|
832
|
-
const hcR = parseInt(hc.slice(1, 3), 16) || 255;
|
|
833
|
-
const hcG = parseInt(hc.slice(3, 5), 16) || 255;
|
|
834
|
-
const hcB = parseInt(hc.slice(5, 7), 16) || 255;
|
|
835
|
-
const hasTransparency = frame.some((row) => row.some((cell) => cell.a < 200));
|
|
865
|
+
const id = `ar-${Math.random().toString(36).slice(2, 9)}`;
|
|
866
|
+
const opts = buildEmbedOpts(options, rows, cols, width, height);
|
|
836
867
|
return `<!-- Asciify Embed -->
|
|
837
|
-
<canvas id="
|
|
838
|
-
<script>
|
|
839
|
-
(
|
|
840
|
-
var D=${JSON.stringify(data)};
|
|
841
|
-
var R=${rows},C=${cols},W=${width},H=${height};
|
|
842
|
-
var cW=W/C,cH=H/R;
|
|
843
|
-
var isDots=${isDots};
|
|
844
|
-
var invert=${options.invert};
|
|
845
|
-
var dotR=${options.dotSizeRatio};
|
|
846
|
-
var hStr=${options.hoverStrength},hRad=${options.hoverRadius};
|
|
847
|
-
var hcR=${hcR},hcG=${hcG},hcB=${hcB};
|
|
848
|
-
var hEff='${options.hoverEffect}';
|
|
849
|
-
var charset=${JSON.stringify(charset)};
|
|
850
|
-
var hasTr=${hasTransparency};
|
|
851
|
-
var cv=document.getElementById('ar-embed'),ctx=cv.getContext('2d');
|
|
852
|
-
var mx=-1,my=-1,mIn=0;
|
|
853
|
-
var getColor=${buildColorFnJS(options)};
|
|
854
|
-
var getAnim=${buildAnimFnJS(options.animationStyle, options.animationSpeed)};
|
|
855
|
-
${hasHover ? `
|
|
856
|
-
cv.addEventListener('mousemove',function(e){var r=cv.getBoundingClientRect();mx=(e.clientX-r.left)/r.width;my=(e.clientY-r.top)/r.height});
|
|
857
|
-
cv.addEventListener('mouseleave',function(){mx=-1;my=-1});
|
|
858
|
-
function ss(t){return t*t*(3-2*t)}
|
|
859
|
-
` : ""}
|
|
860
|
-
var smX=.5,smY=.5;
|
|
861
|
-
function draw(t){
|
|
862
|
-
var time=t/1000;
|
|
863
|
-
ctx.clearRect(0,0,W,H);
|
|
864
|
-
if(!hasTr){ctx.fillStyle='#0a0a0a';ctx.fillRect(0,0,W,H)};
|
|
865
|
-
${hasHover ? `
|
|
866
|
-
if(mx>=0){smX+=(mx-smX)*.1;smY+=(my-smY)*.1;mIn+=(1-mIn)*.12}
|
|
867
|
-
else{mIn*=.96;if(mIn<.003)mIn=0}
|
|
868
|
-
` : ""}
|
|
869
|
-
for(var y=0;y<R;y++)for(var x=0;x<C;x++){
|
|
870
|
-
var p=D[y][x];if(p.a<10)continue;
|
|
871
|
-
var am=getAnim(x,y,C,R,time);if(am<.05)continue;
|
|
872
|
-
var sc=1,ox=0,oy=0,gl=0,cb=0;
|
|
873
|
-
${hasHover ? `
|
|
874
|
-
if(mIn>.003&&hStr>0){
|
|
875
|
-
var nx=x/C,ny=y/R,dx=nx-smX,dy=ny-smY,dd=Math.sqrt(dx*dx+dy*dy);
|
|
876
|
-
var rad=(.08+hRad*.35)+hStr*.04;
|
|
877
|
-
if(dd<rad){
|
|
878
|
-
var tt=1-dd/rad,e=ss(tt)*mIn,ang=Math.atan2(dy,dx);
|
|
879
|
-
if(hEff==='spotlight'){sc=1+e*hStr*1.8;var pf=e*e*hStr*.6;ox=Math.cos(ang)*pf*cW;oy=Math.sin(ang)*pf*cH;gl=e*hStr*.4;cb=e*e*hStr*.25}
|
|
880
|
-
else if(hEff==='magnify'){sc=1+e*hStr*2.5;gl=e*hStr*.15}
|
|
881
|
-
else if(hEff==='repel'){sc=1+e*hStr*.3;var pf=e*e*hStr*1.2;ox=Math.cos(ang)*pf*cW;oy=Math.sin(ang)*pf*cH}
|
|
882
|
-
else if(hEff==='glow'){gl=e*hStr*.8;cb=e*hStr*.4}
|
|
883
|
-
else if(hEff==='colorShift'){sc=1+e*hStr*.4;gl=e*hStr*.2;cb=e*hStr*.7}
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
` : ""}
|
|
887
|
-
var px=x*cW+cW/2+ox,py=y*cH+cH/2+oy;
|
|
888
|
-
var col=getColor(p);
|
|
889
|
-
if(cb>0){var m=col.match(/rgb\\((\\d+),(\\d+),(\\d+)\\)/);if(m){var rr=+m[1],gg=+m[2],bb=+m[3];col='rgb('+Math.min(255,Math.round(rr+(hcR-rr)*cb))+','+Math.min(255,Math.round(gg+(hcG-gg)*cb))+','+Math.min(255,Math.round(bb+(hcB-bb)*cb))+')'}}
|
|
890
|
-
if(isDots){
|
|
891
|
-
var lum=p.l/255;var int=invert?1-lum:lum;if(int<.02)continue;
|
|
892
|
-
var rad=Math.min(cW,cH)*.5*dotR*int*am*sc;if(rad<.3)continue;
|
|
893
|
-
ctx.globalAlpha=Math.min(1,(p.a/255)*am*(1+gl));
|
|
894
|
-
ctx.fillStyle=col;ctx.beginPath();ctx.arc(px,py,rad,0,Math.PI*2);ctx.fill()
|
|
895
|
-
}else{
|
|
896
|
-
var lum=(.299*p.r+.587*p.g+.114*p.b)/255;if(invert)lum=1-lum;
|
|
897
|
-
var ci=Math.floor(lum*(charset.length-1));
|
|
898
|
-
var ch=charset[Math.max(0,Math.min(charset.length-1,ci))];
|
|
899
|
-
if(ch===' ')continue;
|
|
900
|
-
ctx.globalAlpha=Math.min(1,(p.a/255)*am*(1+gl));
|
|
901
|
-
ctx.fillStyle=col;
|
|
902
|
-
var fs=Math.min(cW/.55,cH)*.9*sc;
|
|
903
|
-
ctx.font=fs+'px "JetBrains Mono",monospace';ctx.textAlign='center';ctx.textBaseline='middle';
|
|
904
|
-
ctx.fillText(ch,px,py)
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
ctx.globalAlpha=1;
|
|
908
|
-
${hasAnim || hasHover ? "requestAnimationFrame(draw)" : ""};
|
|
909
|
-
}
|
|
910
|
-
${hasAnim || hasHover ? "requestAnimationFrame(draw)" : "draw(0)"};
|
|
911
|
-
})();
|
|
912
|
-
</script>
|
|
868
|
+
<canvas id="${id}" width="${width}" height="${height}" style="display:block"></canvas>
|
|
869
|
+
<script src="https://cdn.jsdelivr.net/npm/asciify-engine@${EMBED_CDN_VERSION}/dist/embed.js"></script>
|
|
870
|
+
<script>Asciify('${id}','${data}',${opts})</script>
|
|
913
871
|
<!-- /Asciify Embed -->`;
|
|
914
872
|
}
|
|
915
873
|
function generateAnimatedEmbedCode(frames, options, fps, width, height) {
|
|
874
|
+
if (frames.length === 0) return "";
|
|
916
875
|
const rows = frames[0].length;
|
|
917
876
|
const cols = frames[0][0].length;
|
|
918
877
|
const isDots = options.renderMode === "dots";
|
|
919
878
|
const allData = frames.map((f) => serializeFrame(f, !isDots));
|
|
920
|
-
const
|
|
921
|
-
const
|
|
922
|
-
const hcR = parseInt(hc.slice(1, 3), 16) || 255;
|
|
923
|
-
const hcG = parseInt(hc.slice(3, 5), 16) || 255;
|
|
924
|
-
const hcB = parseInt(hc.slice(5, 7), 16) || 255;
|
|
925
|
-
const charset = isDots ? "" : options.charset;
|
|
926
|
-
const hasTransparency = frames.some((f) => f.some((row) => row.some((cell) => cell.a < 200)));
|
|
879
|
+
const id = `ar-${Math.random().toString(36).slice(2, 9)}`;
|
|
880
|
+
const opts = buildEmbedOpts(options, rows, cols, width, height, fps, true);
|
|
927
881
|
return `<!-- Asciify Animated Embed -->
|
|
928
|
-
<canvas id="
|
|
929
|
-
<script>
|
|
930
|
-
(
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
882
|
+
<canvas id="${id}" width="${width}" height="${height}" style="display:block"></canvas>
|
|
883
|
+
<script src="https://cdn.jsdelivr.net/npm/asciify-engine@${EMBED_CDN_VERSION}/dist/embed.js"></script>
|
|
884
|
+
<script>Asciify('${id}',${JSON.stringify(allData)},${opts})</script>
|
|
885
|
+
<!-- /Asciify Animated Embed -->`;
|
|
886
|
+
}
|
|
887
|
+
function _fade(t) {
|
|
888
|
+
return t * t * t * (t * (t * 6 - 15) + 10);
|
|
889
|
+
}
|
|
890
|
+
function _lerp(a, b, t) {
|
|
891
|
+
return a + (b - a) * t;
|
|
892
|
+
}
|
|
893
|
+
function _hash2(ix, iy) {
|
|
894
|
+
let n = ix * 127 + iy * 311;
|
|
895
|
+
n = n >> 13 ^ n;
|
|
896
|
+
return (n * (n * n * 15731 + 789221) + 1376312589 & 2147483647) / 1073741823 - 1;
|
|
897
|
+
}
|
|
898
|
+
function _vnoise(x, y) {
|
|
899
|
+
const ix = Math.floor(x), iy = Math.floor(y);
|
|
900
|
+
const fx = x - ix, fy = y - iy;
|
|
901
|
+
const ux = _fade(fx), uy = _fade(fy);
|
|
902
|
+
const v00 = _hash2(ix, iy);
|
|
903
|
+
const v10 = _hash2(ix + 1, iy);
|
|
904
|
+
const v01 = _hash2(ix, iy + 1);
|
|
905
|
+
const v11 = _hash2(ix + 1, iy + 1);
|
|
906
|
+
return _lerp(_lerp(v00, v10, ux), _lerp(v01, v11, ux), uy);
|
|
907
|
+
}
|
|
908
|
+
function _fbm(x, y) {
|
|
909
|
+
return (_vnoise(x, y) * 0.5 + _vnoise(x * 2.1, y * 2.1) * 0.25 + _vnoise(x * 4.3, y * 4.3) * 0.125) / 0.875;
|
|
910
|
+
}
|
|
911
|
+
function renderWaveBackground(ctx, width, height, time, mousePos = { x: 0.5, y: 0.5 }, options = {}) {
|
|
912
|
+
const {
|
|
913
|
+
fontSize = 13,
|
|
914
|
+
charAspect = 0.62,
|
|
915
|
+
lineHeightRatio = 1.4,
|
|
916
|
+
chars = " .:-=+*#%@",
|
|
917
|
+
baseColor = null,
|
|
918
|
+
accentColor = "#d4ff00",
|
|
919
|
+
accentThreshold = 0.52,
|
|
920
|
+
mouseInfluence = 0.55,
|
|
921
|
+
mouseFalloff = 2.8,
|
|
922
|
+
speed = 1,
|
|
923
|
+
vortex = true,
|
|
924
|
+
sparkles = true,
|
|
925
|
+
breathe = true,
|
|
926
|
+
lightMode = false
|
|
927
|
+
} = options;
|
|
928
|
+
const charW = fontSize * charAspect;
|
|
929
|
+
const lineH = fontSize * lineHeightRatio;
|
|
930
|
+
const cols = Math.ceil(width / charW);
|
|
931
|
+
const rows = Math.ceil(height / lineH);
|
|
932
|
+
const mx = mousePos.x;
|
|
933
|
+
const my = mousePos.y;
|
|
934
|
+
let acR = 212, acG = 255, acB = 0;
|
|
935
|
+
if (accentColor) {
|
|
936
|
+
const hex = accentColor.replace("#", "");
|
|
937
|
+
if (hex.length === 6) {
|
|
938
|
+
acR = parseInt(hex.slice(0, 2), 16);
|
|
939
|
+
acG = parseInt(hex.slice(2, 4), 16);
|
|
940
|
+
acB = parseInt(hex.slice(4, 6), 16);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
ctx.clearRect(0, 0, width, height);
|
|
944
|
+
ctx.font = `${fontSize}px "JetBrains Mono", monospace`;
|
|
945
|
+
ctx.textBaseline = "top";
|
|
946
|
+
const t = time * speed;
|
|
947
|
+
const breatheAmp = breathe ? (Math.sin(t * 0.22) * 0.5 + 0.5) * 0.12 : 0;
|
|
948
|
+
for (let row = 0; row < rows; row++) {
|
|
949
|
+
for (let col = 0; col < cols; col++) {
|
|
950
|
+
const nx = col / cols;
|
|
951
|
+
const ny = row / rows;
|
|
952
|
+
const w1 = Math.sin(col * 0.08 + row * 0.05 + t * 0.6) * 0.5 + 0.5;
|
|
953
|
+
const w2 = Math.sin(col * 0.03 - row * 0.07 + t * 0.4) * 0.5 + 0.5;
|
|
954
|
+
const w3 = Math.sin(col * 0.05 + row * 0.03 + t * 0.8) * 0.5 + 0.5;
|
|
955
|
+
const sinePart = (w1 + w2 + w3) / 3;
|
|
956
|
+
const noiseScale = 0.045;
|
|
957
|
+
const noiseShift = t * 0.08;
|
|
958
|
+
const noisePart = _fbm(col * noiseScale + noiseShift, row * noiseScale * 1.4 - noiseShift * 0.7) * 0.5 + 0.5;
|
|
959
|
+
const driftFreq = 0.06;
|
|
960
|
+
const driftPart = Math.sin((col + row * 0.65) * driftFreq + t * 1.1) * 0.5 + 0.5;
|
|
961
|
+
const wavePart = sinePart * 0.45 + noisePart * 0.35 + driftPart * 0.2 + breatheAmp;
|
|
962
|
+
const dxRaw = nx - mx;
|
|
963
|
+
const dyRaw = ny - my;
|
|
964
|
+
const distRaw = Math.sqrt(dxRaw * dxRaw + dyRaw * dyRaw);
|
|
965
|
+
let vortexBump = 0;
|
|
966
|
+
if (vortex && distRaw < 0.35) {
|
|
967
|
+
const angle = Math.atan2(dyRaw, dxRaw);
|
|
968
|
+
const swirl = Math.sin(angle * 4 + t * 2.2 - distRaw * 14);
|
|
969
|
+
const falloff = Math.max(0, 1 - distRaw / 0.35);
|
|
970
|
+
vortexBump = swirl * falloff * falloff * 0.22;
|
|
971
|
+
}
|
|
972
|
+
const proximity = Math.max(0, 1 - distRaw * mouseFalloff);
|
|
973
|
+
const intensity = wavePart * (1 - mouseInfluence) + (proximity + vortexBump * 0.5) * mouseInfluence + vortexBump * 0.15;
|
|
974
|
+
const clamped = Math.min(1, Math.max(0, intensity));
|
|
975
|
+
let finalIntensity = clamped;
|
|
976
|
+
if (sparkles && clamped > 0.72) {
|
|
977
|
+
const bucket = Math.floor(t * 8);
|
|
978
|
+
const sparkleSeed = _hash2(col * 7 + bucket * 3, row * 11 + bucket);
|
|
979
|
+
if (sparkleSeed > 0.88) {
|
|
980
|
+
finalIntensity = Math.min(1, clamped + (sparkleSeed - 0.88) * 4);
|
|
974
981
|
}
|
|
975
982
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
if(
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
ctx.fillStyle=
|
|
985
|
-
}else{
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if(ch===' ')continue;
|
|
990
|
-
ctx.globalAlpha=Math.min(1,(p.a/255)*(1+gl));
|
|
991
|
-
ctx.fillStyle=col;
|
|
992
|
-
var fs=Math.min(cW/.55,cH)*.9*sc;
|
|
993
|
-
ctx.font=fs+'px "JetBrains Mono",monospace';ctx.textAlign='center';ctx.textBaseline='middle';
|
|
994
|
-
ctx.fillText(ch,px,py)
|
|
983
|
+
const charIdx = Math.floor(finalIntensity * (chars.length - 1));
|
|
984
|
+
if (chars[charIdx] === " ") continue;
|
|
985
|
+
const alpha = 0.015 + finalIntensity * 0.07;
|
|
986
|
+
const isAccent = finalIntensity > accentThreshold;
|
|
987
|
+
if (isAccent) {
|
|
988
|
+
const accentAlpha = Math.min(lightMode ? 0.4 : 0.28, alpha * (lightMode ? 4 : 2.8));
|
|
989
|
+
ctx.fillStyle = `rgba(${acR},${acG},${acB},${accentAlpha})`;
|
|
990
|
+
} else if (baseColor) {
|
|
991
|
+
ctx.fillStyle = baseColor.replace("{a}", String(alpha));
|
|
992
|
+
} else if (lightMode) {
|
|
993
|
+
ctx.fillStyle = `rgba(0,0,0,${alpha * 1.3})`;
|
|
994
|
+
} else {
|
|
995
|
+
ctx.fillStyle = `rgba(255,255,255,${alpha})`;
|
|
995
996
|
}
|
|
997
|
+
ctx.fillText(chars[charIdx], col * charW, row * lineH);
|
|
996
998
|
}
|
|
997
|
-
ctx.globalAlpha=1;
|
|
998
|
-
requestAnimationFrame(draw);
|
|
999
999
|
}
|
|
1000
|
-
requestAnimationFrame(draw);
|
|
1001
|
-
})();
|
|
1002
|
-
</script>
|
|
1003
|
-
<!-- /Asciify Animated Embed -->`;
|
|
1004
1000
|
}
|
|
1005
1001
|
|
|
1006
1002
|
// src/webgl-engine.ts
|
|
@@ -1265,7 +1261,7 @@ function makeTexture(gl, filter = gl.NEAREST) {
|
|
|
1265
1261
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1266
1262
|
return t;
|
|
1267
1263
|
}
|
|
1268
|
-
var ANIM_STYLES = ["none", "wave", "pulse", "rain", "breathe", "sparkle", "glitch", "spiral", "typewriter", "scatter"];
|
|
1264
|
+
var ANIM_STYLES = ["none", "wave", "pulse", "rain", "breathe", "sparkle", "glitch", "spiral", "typewriter", "scatter", "waveField"];
|
|
1269
1265
|
var HOVER_EFFECTS = ["spotlight", "magnify", "repel", "glow", "colorShift"];
|
|
1270
1266
|
var COLOR_MODES = ["grayscale", "fullcolor", "matrix", "accent"];
|
|
1271
1267
|
function tryCreateWebGLRenderer(canvas) {
|
|
@@ -1451,6 +1447,6 @@ function tryCreateWebGLRenderer(canvas) {
|
|
|
1451
1447
|
}
|
|
1452
1448
|
}
|
|
1453
1449
|
|
|
1454
|
-
export { ART_STYLE_PRESETS, CHARSETS, DEFAULT_OPTIONS, HOVER_PRESETS, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, renderFrameToCanvas, tryCreateWebGLRenderer, videoToAsciiFrames };
|
|
1450
|
+
export { ART_STYLE_PRESETS, CHARSETS, DEFAULT_OPTIONS, HOVER_PRESETS, asciify, asciifyGif, asciifyVideo, generateAnimatedEmbedCode, generateEmbedCode, gifToAsciiFrames, imageToAsciiFrame, renderFrameToCanvas, renderWaveBackground, tryCreateWebGLRenderer, videoToAsciiFrames };
|
|
1455
1451
|
//# sourceMappingURL=index.js.map
|
|
1456
1452
|
//# sourceMappingURL=index.js.map
|