asciify-engine 1.0.5 → 1.0.6
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 +186 -191
- 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 +186 -192
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/embed.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){'use strict';function fn(o,p,n){let e=t=>{let a=atob(t),f=new Uint8Array(a.length);for(let M=0;M<a.length;M++)f[M]=a.charCodeAt(M);return f};return Array.isArray(o)?o.map(e):[e(o)]}function mn(o,p,n,e){let t=(n*e+p)*5;return {r:o[t],g:o[t+1],b:o[t+2],a:o[t+3],l:o[t+4]}}function Mn(o){return o*o*(3-2*o)}function gn(o,p){if(o==="fullcolor")return (n,e,t)=>`rgb(${n},${e},${t})`;if(o==="matrix")return (n,e,t)=>`rgb(0,${Math.floor(.299*n+.587*e+.114*t)},0)`;if(o==="accent"){let n=p.replace("#",""),e=parseInt(n.substring(0,2),16),t=parseInt(n.substring(2,4),16),a=parseInt(n.substring(4,6),16);return (f,M,c)=>{let r=(.299*f+.587*M+.114*c)/255;return `rgb(${Math.floor(e*r)},${Math.floor(t*r)},${Math.floor(a*r)})`}}return (n,e,t)=>{let a=Math.floor(.299*n+.587*e+.114*t);return `rgb(${a},${a},${a})`}}function bn(o,p,n,e,t,a,f){let M=p,c=f*M;switch(o){case "wave":{let r=Math.sin(n/t*Math.PI*4+c*3)*.5+.5,s=Math.sin(e/a*Math.PI*3+c*2)*.5+.5;return .3+.7*(r*.6+s*.4)}case "pulse":{let r=t/2,s=a/2,m=Math.sqrt((n-r)**2+(e-s)**2),h=Math.sqrt(r*r+s*s);return .2+.8*(Math.sin(m/h*Math.PI*6-c*4)*.5+.5)}case "rain":return .1+.9*(Math.sin(e/a*Math.PI*8-c*5+n*.3)*.5+.5)*(Math.sin(n/t*Math.PI*2+c)*.3+.7);case "breathe":return Math.max(.1,Math.min(1,Math.sin(c*2)*.3+.7+Math.sin((n+e)*.1+c)*.1));case "sparkle":{let r=Math.sin(n*127.1+e*311.7+Math.floor(c*8)*43758.5453)*43758.5453,s=r-Math.floor(r);return s>.7?1:.15+s*.4}case "glitch":{let r=Math.floor(e/(a*.05)),s=Math.sin(r*43.23+Math.floor(c*6)*17.89)*43758.5453;if(s-Math.floor(s)>.85){let h=Math.sin(c*30+r)*.5+.5;return h<.3?0:h}return 1}case "spiral":{let r=t/2,s=a/2,m=n-r,h=e-s,g=Math.atan2(h,m),$=Math.sqrt(m*m+h*h),k=Math.sqrt(r*r+s*s);return .15+.85*(Math.sin(g*3+$/k*Math.PI*8-c*3)*.5+.5)}case "typewriter":{let r=t*a,s=e*t+n,m=c*.5%1,h=m*r*1.3,g=s-h;return g>0?0:Math.min(1,Math.max(0,1+g/(r*.15)))}case "scatter":{let r=t/2,s=a/2,m=n-r,h=e-s,g=Math.sqrt(m*m+h*h)/Math.sqrt(r*r+s*s),$=Math.sin(c*1.5)*.5+.5;return g>$?Math.max(0,1-(g-$)*3):.7+.3*Math.sin(g*10-c*2)}default:return 1}}function dn(o,p,n){let e=document.getElementById(o);if(!e){console.error(`Asciify: canvas #${o} not found`);return}let t=e.getContext("2d"),{r:a,c:f,w:M,h:c}=n,r=n.fps??10,s=n.cs??" .:-=+*#%@",m=n.cm??"grayscale",h=n.ac??"#ffffff",g=n.as??"none",$=n.sp??1,k=n.inv??false,l=n.hs??0,en=n.hr??.3,E=n.he??"spotlight",T=n.hc??"#ffffff",rn=n.dr??.7,sn=n.dots??false,K=n.anim??false,an=parseInt(T.slice(1,3),16)||255,on=parseInt(T.slice(3,5),16)||255,cn=parseInt(T.slice(5,7),16)||255,I=M/f,w=c/a,N=fn(p),hn=gn(m,h),B=l>0,Q=g!=="none"||K,L=-1,U=-1,v=0,W=.5,X=.5,Y=0,V=0;B&&(e.addEventListener("mousemove",q=>{let P=e.getBoundingClientRect();L=(q.clientX-P.left)/P.width,U=(q.clientY-P.top)/P.height;}),e.addEventListener("mouseleave",()=>{L=-1,U=-1;}));function D(q){let P=q/1e3;K&&q-V>=1e3/r&&(Y=(Y+1)%N.length,V=q);let ln=N[Y];t.clearRect(0,0,M,c),t.fillStyle="#0a0a0a",t.fillRect(0,0,M,c),B&&(L>=0?(W+=(L-W)*.1,X+=(U-X)*.1,v+=(1-v)*.12):(v*=.96,v<.003&&(v=0)));for(let R=0;R<a;R++)for(let S=0;S<f;S++){let x=mn(ln,S,R,f);if(x.a<10)continue;let G=bn(g,$,S,R,f,a,P);if(G<.05)continue;let C=1,J=0,j=0,F=0,A=0;if(B&&v>.003){let u=S/f,b=R/a,d=u-W,y=b-X,nn=Math.sqrt(d*d+y*y),tn=.08+en*.35+l*.04;if(nn<tn){let un=1-nn/tn,i=Mn(un)*v,O=Math.atan2(y,d);if(E==="spotlight"){C=1+i*l*1.8;let H=i*i*l*.6;J=Math.cos(O)*H*I,j=Math.sin(O)*H*w,F=i*l*.4,A=i*i*l*.25;}else if(E==="magnify")C=1+i*l*2.5,F=i*l*.15;else if(E==="repel"){C=1+i*l*.3;let H=i*i*l*1.2;J=Math.cos(O)*H*I,j=Math.sin(O)*H*w;}else E==="glow"?(F=i*l*.8,A=i*l*.4):E==="colorShift"&&(C=1+i*l*.4,F=i*l*.2,A=i*l*.7);}}let Z=S*I+I/2+J,_=R*w+w/2+j,z=hn(x.r,x.g,x.b);if(A>0){let u=z.match(/rgb\((\d+),(\d+),(\d+)\)/);if(u){let b=+u[1],d=+u[2],y=+u[3];z=`rgb(${Math.min(255,Math.round(b+(an-b)*A))},${Math.min(255,Math.round(d+(on-d)*A))},${Math.min(255,Math.round(y+(cn-y)*A))})`;}}if(t.globalAlpha=Math.min(1,x.a/255*G*(1+F)),t.fillStyle=z,sn){let u=x.l/255;if(k&&(u=1-u),u<.02)continue;let b=Math.min(I,w)*.5*rn*u*G*C;if(b<.3)continue;t.beginPath(),t.arc(Z,_,b,0,Math.PI*2),t.fill();}else {let u=x.l/255;k&&(u=1-u);let b=Math.floor(u*(s.length-1)),d=s[Math.max(0,Math.min(s.length-1,b))];if(d===" ")continue;let y=Math.min(I/.55,w)*.9*C;t.font=`${y}px "JetBrains Mono",monospace`,t.textAlign="center",t.textBaseline="middle",t.fillText(d,Z,_);}}t.globalAlpha=1,(Q||B)&&requestAnimationFrame(D);}Q||B?requestAnimationFrame(D):D(0);}window.Asciify=dn;})();
|
package/dist/index.cjs
CHANGED
|
@@ -276,6 +276,8 @@ function getAnimationMultiplier(x, y, cols, rows, time, style, speed) {
|
|
|
276
276
|
}
|
|
277
277
|
return 0.7 + 0.3 * Math.sin(sdist * 10 - t * 2);
|
|
278
278
|
}
|
|
279
|
+
case "waveField":
|
|
280
|
+
return 1;
|
|
279
281
|
default:
|
|
280
282
|
return 1;
|
|
281
283
|
}
|
|
@@ -468,6 +470,24 @@ function computeHoverEffect(nx, ny, hoverX, hoverY, hoverIntensity, strength, ce
|
|
|
468
470
|
return _hoverResult;
|
|
469
471
|
}
|
|
470
472
|
function renderFrameToCanvas(ctx, frame, options, canvasWidth, canvasHeight, time = 0, hoverPos) {
|
|
473
|
+
if (options.animationStyle === "waveField") {
|
|
474
|
+
const mouseNorm = hoverPos ? { x: hoverPos.x, y: hoverPos.y } : { x: 0.5, y: 0.5 };
|
|
475
|
+
const acHexWF = (options.accentColor || "#d4ff00").replace("#", "");
|
|
476
|
+
parseInt(acHexWF.substring(0, 2), 16) || 212;
|
|
477
|
+
parseInt(acHexWF.substring(2, 4), 16) || 255;
|
|
478
|
+
parseInt(acHexWF.substring(4, 6), 16) || 0;
|
|
479
|
+
renderWaveBackground(ctx, canvasWidth, canvasHeight, time, mouseNorm, {
|
|
480
|
+
accentColor: `#${acHexWF}`,
|
|
481
|
+
accentThreshold: 0.52,
|
|
482
|
+
mouseInfluence: options.hoverStrength > 0 ? Math.min(1, 0.3 + options.hoverStrength * 0.5) : 0.55,
|
|
483
|
+
mouseFalloff: 2.8,
|
|
484
|
+
speed: options.animationSpeed,
|
|
485
|
+
vortex: options.hoverStrength > 0,
|
|
486
|
+
sparkles: true,
|
|
487
|
+
breathe: true
|
|
488
|
+
});
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
471
491
|
const rows = frame.length;
|
|
472
492
|
if (rows === 0) return;
|
|
473
493
|
const cols = frame[0].length;
|
|
@@ -700,36 +720,27 @@ function renderFrameToCanvas(ctx, frame, options, canvasWidth, canvasHeight, tim
|
|
|
700
720
|
ctx.globalAlpha = 1;
|
|
701
721
|
}
|
|
702
722
|
function serializeFrame(frame, includeChars) {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
case "fullcolor":
|
|
720
|
-
return `function(c){return 'rgb('+c.r+','+c.g+','+c.b+')'}`;
|
|
721
|
-
case "matrix":
|
|
722
|
-
return `function(c){var b=Math.floor(.299*c.r+.587*c.g+.114*c.b);return 'rgb(0,'+b+',0)'}`;
|
|
723
|
-
case "accent": {
|
|
724
|
-
const hex = options.accentColor.replace("#", "");
|
|
725
|
-
const ar = parseInt(hex.substring(0, 2), 16);
|
|
726
|
-
const ag = parseInt(hex.substring(2, 4), 16);
|
|
727
|
-
const ab = parseInt(hex.substring(4, 6), 16);
|
|
728
|
-
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)+')'}`;
|
|
723
|
+
const rows = frame.length;
|
|
724
|
+
const cols = rows > 0 ? frame[0].length : 0;
|
|
725
|
+
const buf = new Uint8Array(rows * cols * 5);
|
|
726
|
+
let i = 0;
|
|
727
|
+
for (let y = 0; y < rows; y++) {
|
|
728
|
+
for (let x = 0; x < cols; x++) {
|
|
729
|
+
const cell = frame[y][x];
|
|
730
|
+
buf[i++] = cell.r;
|
|
731
|
+
buf[i++] = cell.g;
|
|
732
|
+
buf[i++] = cell.b;
|
|
733
|
+
buf[i++] = cell.a;
|
|
734
|
+
if (includeChars) {
|
|
735
|
+
buf[i++] = cell.char.charCodeAt(0) & 255;
|
|
736
|
+
} else {
|
|
737
|
+
buf[i++] = Math.round(0.299 * cell.r + 0.587 * cell.g + 0.114 * cell.b);
|
|
738
|
+
}
|
|
729
739
|
}
|
|
730
|
-
default:
|
|
731
|
-
return `function(c){var g=Math.floor(.299*c.r+.587*c.g+.114*c.b);return 'rgb('+g+','+g+','+g+')'}`;
|
|
732
740
|
}
|
|
741
|
+
let binary = "";
|
|
742
|
+
for (let j = 0; j < buf.length; j++) binary += String.fromCharCode(buf[j]);
|
|
743
|
+
return btoa(binary);
|
|
733
744
|
}
|
|
734
745
|
async function asciify(source, canvas, { fontSize = 10, style = "classic", options = {} } = {}) {
|
|
735
746
|
let el;
|
|
@@ -821,188 +832,171 @@ async function asciifyVideo(source, canvas, { fontSize = 10, style = "classic",
|
|
|
821
832
|
cancelAnimationFrame(animId);
|
|
822
833
|
};
|
|
823
834
|
}
|
|
835
|
+
var EMBED_CDN_VERSION = "1.0.5";
|
|
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
|
+
}
|
|
824
859
|
function generateEmbedCode(frame, options, width, height) {
|
|
825
860
|
const rows = frame.length;
|
|
826
861
|
if (rows === 0) return "";
|
|
827
862
|
const cols = frame[0].length;
|
|
828
863
|
const isDots = options.renderMode === "dots";
|
|
829
864
|
const data = serializeFrame(frame, !isDots);
|
|
830
|
-
const
|
|
831
|
-
const
|
|
832
|
-
const charset = isDots ? "" : options.charset;
|
|
833
|
-
const hc = options.hoverColor || "#ffffff";
|
|
834
|
-
const hcR = parseInt(hc.slice(1, 3), 16) || 255;
|
|
835
|
-
const hcG = parseInt(hc.slice(3, 5), 16) || 255;
|
|
836
|
-
const hcB = parseInt(hc.slice(5, 7), 16) || 255;
|
|
837
|
-
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);
|
|
838
867
|
return `<!-- Asciify Embed -->
|
|
839
|
-
<canvas id="
|
|
840
|
-
<script>
|
|
841
|
-
(
|
|
842
|
-
var D=${JSON.stringify(data)};
|
|
843
|
-
var R=${rows},C=${cols},W=${width},H=${height};
|
|
844
|
-
var cW=W/C,cH=H/R;
|
|
845
|
-
var isDots=${isDots};
|
|
846
|
-
var invert=${options.invert};
|
|
847
|
-
var dotR=${options.dotSizeRatio};
|
|
848
|
-
var hStr=${options.hoverStrength},hRad=${options.hoverRadius};
|
|
849
|
-
var hcR=${hcR},hcG=${hcG},hcB=${hcB};
|
|
850
|
-
var hEff='${options.hoverEffect}';
|
|
851
|
-
var charset=${JSON.stringify(charset)};
|
|
852
|
-
var hasTr=${hasTransparency};
|
|
853
|
-
var cv=document.getElementById('ar-embed'),ctx=cv.getContext('2d');
|
|
854
|
-
var mx=-1,my=-1,mIn=0;
|
|
855
|
-
var getColor=${buildColorFnJS(options)};
|
|
856
|
-
var getAnim=${buildAnimFnJS(options.animationStyle, options.animationSpeed)};
|
|
857
|
-
${hasHover ? `
|
|
858
|
-
cv.addEventListener('mousemove',function(e){var r=cv.getBoundingClientRect();mx=(e.clientX-r.left)/r.width;my=(e.clientY-r.top)/r.height});
|
|
859
|
-
cv.addEventListener('mouseleave',function(){mx=-1;my=-1});
|
|
860
|
-
function ss(t){return t*t*(3-2*t)}
|
|
861
|
-
` : ""}
|
|
862
|
-
var smX=.5,smY=.5;
|
|
863
|
-
function draw(t){
|
|
864
|
-
var time=t/1000;
|
|
865
|
-
ctx.clearRect(0,0,W,H);
|
|
866
|
-
if(!hasTr){ctx.fillStyle='#0a0a0a';ctx.fillRect(0,0,W,H)};
|
|
867
|
-
${hasHover ? `
|
|
868
|
-
if(mx>=0){smX+=(mx-smX)*.1;smY+=(my-smY)*.1;mIn+=(1-mIn)*.12}
|
|
869
|
-
else{mIn*=.96;if(mIn<.003)mIn=0}
|
|
870
|
-
` : ""}
|
|
871
|
-
for(var y=0;y<R;y++)for(var x=0;x<C;x++){
|
|
872
|
-
var p=D[y][x];if(p.a<10)continue;
|
|
873
|
-
var am=getAnim(x,y,C,R,time);if(am<.05)continue;
|
|
874
|
-
var sc=1,ox=0,oy=0,gl=0,cb=0;
|
|
875
|
-
${hasHover ? `
|
|
876
|
-
if(mIn>.003&&hStr>0){
|
|
877
|
-
var nx=x/C,ny=y/R,dx=nx-smX,dy=ny-smY,dd=Math.sqrt(dx*dx+dy*dy);
|
|
878
|
-
var rad=(.08+hRad*.35)+hStr*.04;
|
|
879
|
-
if(dd<rad){
|
|
880
|
-
var tt=1-dd/rad,e=ss(tt)*mIn,ang=Math.atan2(dy,dx);
|
|
881
|
-
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}
|
|
882
|
-
else if(hEff==='magnify'){sc=1+e*hStr*2.5;gl=e*hStr*.15}
|
|
883
|
-
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}
|
|
884
|
-
else if(hEff==='glow'){gl=e*hStr*.8;cb=e*hStr*.4}
|
|
885
|
-
else if(hEff==='colorShift'){sc=1+e*hStr*.4;gl=e*hStr*.2;cb=e*hStr*.7}
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
` : ""}
|
|
889
|
-
var px=x*cW+cW/2+ox,py=y*cH+cH/2+oy;
|
|
890
|
-
var col=getColor(p);
|
|
891
|
-
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))+')'}}
|
|
892
|
-
if(isDots){
|
|
893
|
-
var lum=p.l/255;var int=invert?1-lum:lum;if(int<.02)continue;
|
|
894
|
-
var rad=Math.min(cW,cH)*.5*dotR*int*am*sc;if(rad<.3)continue;
|
|
895
|
-
ctx.globalAlpha=Math.min(1,(p.a/255)*am*(1+gl));
|
|
896
|
-
ctx.fillStyle=col;ctx.beginPath();ctx.arc(px,py,rad,0,Math.PI*2);ctx.fill()
|
|
897
|
-
}else{
|
|
898
|
-
var lum=(.299*p.r+.587*p.g+.114*p.b)/255;if(invert)lum=1-lum;
|
|
899
|
-
var ci=Math.floor(lum*(charset.length-1));
|
|
900
|
-
var ch=charset[Math.max(0,Math.min(charset.length-1,ci))];
|
|
901
|
-
if(ch===' ')continue;
|
|
902
|
-
ctx.globalAlpha=Math.min(1,(p.a/255)*am*(1+gl));
|
|
903
|
-
ctx.fillStyle=col;
|
|
904
|
-
var fs=Math.min(cW/.55,cH)*.9*sc;
|
|
905
|
-
ctx.font=fs+'px "JetBrains Mono",monospace';ctx.textAlign='center';ctx.textBaseline='middle';
|
|
906
|
-
ctx.fillText(ch,px,py)
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
ctx.globalAlpha=1;
|
|
910
|
-
${hasAnim || hasHover ? "requestAnimationFrame(draw)" : ""};
|
|
911
|
-
}
|
|
912
|
-
${hasAnim || hasHover ? "requestAnimationFrame(draw)" : "draw(0)"};
|
|
913
|
-
})();
|
|
914
|
-
</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>
|
|
915
871
|
<!-- /Asciify Embed -->`;
|
|
916
872
|
}
|
|
917
873
|
function generateAnimatedEmbedCode(frames, options, fps, width, height) {
|
|
874
|
+
if (frames.length === 0) return "";
|
|
918
875
|
const rows = frames[0].length;
|
|
919
876
|
const cols = frames[0][0].length;
|
|
920
877
|
const isDots = options.renderMode === "dots";
|
|
921
878
|
const allData = frames.map((f) => serializeFrame(f, !isDots));
|
|
922
|
-
const
|
|
923
|
-
const
|
|
924
|
-
const hcR = parseInt(hc.slice(1, 3), 16) || 255;
|
|
925
|
-
const hcG = parseInt(hc.slice(3, 5), 16) || 255;
|
|
926
|
-
const hcB = parseInt(hc.slice(5, 7), 16) || 255;
|
|
927
|
-
const charset = isDots ? "" : options.charset;
|
|
928
|
-
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);
|
|
929
881
|
return `<!-- Asciify Animated Embed -->
|
|
930
|
-
<canvas id="
|
|
931
|
-
<script>
|
|
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
|
-
|
|
974
|
-
|
|
975
|
-
|
|
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);
|
|
976
981
|
}
|
|
977
982
|
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
if(
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
ctx.fillStyle=
|
|
987
|
-
}else{
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
if(ch===' ')continue;
|
|
992
|
-
ctx.globalAlpha=Math.min(1,(p.a/255)*(1+gl));
|
|
993
|
-
ctx.fillStyle=col;
|
|
994
|
-
var fs=Math.min(cW/.55,cH)*.9*sc;
|
|
995
|
-
ctx.font=fs+'px "JetBrains Mono",monospace';ctx.textAlign='center';ctx.textBaseline='middle';
|
|
996
|
-
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})`;
|
|
997
996
|
}
|
|
997
|
+
ctx.fillText(chars[charIdx], col * charW, row * lineH);
|
|
998
998
|
}
|
|
999
|
-
ctx.globalAlpha=1;
|
|
1000
|
-
requestAnimationFrame(draw);
|
|
1001
999
|
}
|
|
1002
|
-
requestAnimationFrame(draw);
|
|
1003
|
-
})();
|
|
1004
|
-
</script>
|
|
1005
|
-
<!-- /Asciify Animated Embed -->`;
|
|
1006
1000
|
}
|
|
1007
1001
|
|
|
1008
1002
|
// src/webgl-engine.ts
|
|
@@ -1267,7 +1261,7 @@ function makeTexture(gl, filter = gl.NEAREST) {
|
|
|
1267
1261
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1268
1262
|
return t;
|
|
1269
1263
|
}
|
|
1270
|
-
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"];
|
|
1271
1265
|
var HOVER_EFFECTS = ["spotlight", "magnify", "repel", "glow", "colorShift"];
|
|
1272
1266
|
var COLOR_MODES = ["grayscale", "fullcolor", "matrix", "accent"];
|
|
1273
1267
|
function tryCreateWebGLRenderer(canvas) {
|
|
@@ -1465,6 +1459,7 @@ exports.generateEmbedCode = generateEmbedCode;
|
|
|
1465
1459
|
exports.gifToAsciiFrames = gifToAsciiFrames;
|
|
1466
1460
|
exports.imageToAsciiFrame = imageToAsciiFrame;
|
|
1467
1461
|
exports.renderFrameToCanvas = renderFrameToCanvas;
|
|
1462
|
+
exports.renderWaveBackground = renderWaveBackground;
|
|
1468
1463
|
exports.tryCreateWebGLRenderer = tryCreateWebGLRenderer;
|
|
1469
1464
|
exports.videoToAsciiFrames = videoToAsciiFrames;
|
|
1470
1465
|
//# sourceMappingURL=index.cjs.map
|