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/embed.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){'use strict';function en(t){let f=atob(t),n=new Uint8Array(f.length);for(let s=0;s<f.length;s++)n[s]=f.charCodeAt(s);return n}function fn(t){return Array.isArray(t)?t.map(en):[en(t)]}function Mn(t,f,n,s){let e=t[0],r=1+(n*s+f)*e;if(e===4){let M=Math.round(.299*t[r]+.587*t[r+1]+.114*t[r+2]);return {r:t[r],g:t[r+1],b:t[r+2],a:t[r+3],l:M}}return {r:t[r],g:t[r],b:t[r],l:t[r],a:t[r+1]}}function gn(t){return t*t*(3-2*t)}function dn(t,f){if(t==="fullcolor")return (n,s,e)=>`rgb(${n},${s},${e})`;if(t==="matrix")return (n,s,e)=>`rgb(0,${Math.floor(.299*n+.587*s+.114*e)},0)`;if(t==="accent"){let n=f.replace("#",""),s=parseInt(n.substring(0,2),16),e=parseInt(n.substring(2,4),16),r=parseInt(n.substring(4,6),16);return (M,y,c)=>{let a=(.299*M+.587*y+.114*c)/255;return `rgb(${Math.floor(s*a)},${Math.floor(e*a)},${Math.floor(r*a)})`}}return (n,s,e)=>{let r=Math.floor(.299*n+.587*s+.114*e);return `rgb(${r},${r},${r})`}}function bn(t,f,n,s,e,r,M){let y=f,c=M*y;switch(t){case "wave":{let a=Math.sin(n/e*Math.PI*4+c*3)*.5+.5,o=Math.sin(s/r*Math.PI*3+c*2)*.5+.5;return .3+.7*(a*.6+o*.4)}case "pulse":{let a=e/2,o=r/2,u=Math.sqrt((n-a)**2+(s-o)**2),h=Math.sqrt(a*a+o*o);return .2+.8*(Math.sin(u/h*Math.PI*6-c*4)*.5+.5)}case "rain":return .1+.9*(Math.sin(s/r*Math.PI*8-c*5+n*.3)*.5+.5)*(Math.sin(n/e*Math.PI*2+c)*.3+.7);case "breathe":return Math.max(.1,Math.min(1,Math.sin(c*2)*.3+.7+Math.sin((n+s)*.1+c)*.1));case "sparkle":{let a=Math.sin(n*127.1+s*311.7+Math.floor(c*8)*43758.5453)*43758.5453,o=a-Math.floor(a);return o>.7?1:.15+o*.4}case "glitch":{let a=Math.floor(s/(r*.05)),o=Math.sin(a*43.23+Math.floor(c*6)*17.89)*43758.5453;if(o-Math.floor(o)>.85){let h=Math.sin(c*30+a)*.5+.5;return h<.3?0:h}return 1}case "spiral":{let a=e/2,o=r/2,u=n-a,h=s-o,g=Math.atan2(h,u),$=Math.sqrt(u*u+h*h),k=Math.sqrt(a*a+o*o);return .15+.85*(Math.sin(g*3+$/k*Math.PI*8-c*3)*.5+.5)}case "typewriter":{let a=e*r,o=s*e+n,u=c*.5%1,h=u*a*1.3,g=o-h;return g>0?0:Math.min(1,Math.max(0,1+g/(a*.15)))}case "scatter":{let a=e/2,o=r/2,u=n-a,h=s-o,g=Math.sqrt(u*u+h*h)/Math.sqrt(a*a+o*o),$=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 pn(t,f,n){let s=document.getElementById(t);if(!s){console.error(`Asciify: canvas #${t} not found`);return}let e=s.getContext("2d"),{r,c:M,w:y,h:c}=n,a=n.fps??10,o=n.cs??" .:-=+*#%@",u=n.cm??"grayscale",h=n.ac??"#ffffff",g=n.as??"none",$=n.sp??1,k=n.inv??false,l=n.hs??0,rn=n.hr??.3,E=n.he??"spotlight",T=n.hc??"#ffffff",sn=n.dr??.7,an=n.dots??false,K=n.anim??false,on=parseInt(T.slice(1,3),16)||255,cn=parseInt(T.slice(3,5),16)||255,hn=parseInt(T.slice(5,7),16)||255,I=y/M,w=c/r,N=fn(f),ln=dn(u,h),F=l>0,Q=g!=="none"||K,L=-1,U=-1,v=0,W=.5,X=.5,Y=0,V=0;F&&(s.addEventListener("mousemove",q=>{let P=s.getBoundingClientRect();L=(q.clientX-P.left)/P.width,U=(q.clientY-P.top)/P.height;}),s.addEventListener("mouseleave",()=>{L=-1,U=-1;}));function D(q){let P=q/1e3;K&&q-V>=1e3/a&&(Y=(Y+1)%N.length,V=q);let mn=N[Y];e.clearRect(0,0,y,c),e.fillStyle="#0a0a0a",e.fillRect(0,0,y,c),F&&(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<r;R++)for(let S=0;S<M;S++){let x=Mn(mn,S,R,M);if(x.a<10)continue;let G=bn(g,$,S,R,M,r,P);if(G<.05)continue;let C=1,J=0,j=0,B=0,A=0;if(F&&v>.003){let m=S/M,d=R/r,b=m-W,p=d-X,nn=Math.sqrt(b*b+p*p),tn=.08+rn*.35+l*.04;if(nn<tn){let un=1-nn/tn,i=gn(un)*v,O=Math.atan2(p,b);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,B=i*l*.4,A=i*i*l*.25;}else if(E==="magnify")C=1+i*l*2.5,B=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"?(B=i*l*.8,A=i*l*.4):E==="colorShift"&&(C=1+i*l*.4,B=i*l*.2,A=i*l*.7);}}let Z=S*I+I/2+J,_=R*w+w/2+j,z=ln(x.r,x.g,x.b);if(A>0){let m=z.match(/rgb\((\d+),(\d+),(\d+)\)/);if(m){let d=+m[1],b=+m[2],p=+m[3];z=`rgb(${Math.min(255,Math.round(d+(on-d)*A))},${Math.min(255,Math.round(b+(cn-b)*A))},${Math.min(255,Math.round(p+(hn-p)*A))})`;}}if(e.globalAlpha=Math.min(1,x.a/255*G*(1+B)),e.fillStyle=z,an){let m=x.l/255;if(k&&(m=1-m),m<.02)continue;let d=Math.min(I,w)*.5*sn*m*G*C;if(d<.3)continue;e.beginPath(),e.arc(Z,_,d,0,Math.PI*2),e.fill();}else {let m=x.l/255;k&&(m=1-m);let d=Math.floor(m*(o.length-1)),b=o[Math.max(0,Math.min(o.length-1,d))];if(b===" ")continue;let p=Math.min(I/.55,w)*.9*C;e.font=`${p}px "JetBrains Mono",monospace`,e.textAlign="center",e.textBaseline="middle",e.fillText(b,Z,_);}}e.globalAlpha=1,(Q||F)&&requestAnimationFrame(D);}Q||F?requestAnimationFrame(D):D(0);}window.Asciify=pn;})();
|
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;
|
|
@@ -699,37 +719,30 @@ function renderFrameToCanvas(ctx, frame, options, canvasWidth, canvasHeight, tim
|
|
|
699
719
|
}
|
|
700
720
|
ctx.globalAlpha = 1;
|
|
701
721
|
}
|
|
702
|
-
function serializeFrame(frame,
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
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)+')'}`;
|
|
722
|
+
function serializeFrame(frame, fullColor) {
|
|
723
|
+
const rows = frame.length;
|
|
724
|
+
const cols = rows > 0 ? frame[0].length : 0;
|
|
725
|
+
const stride = fullColor ? 4 : 2;
|
|
726
|
+
const buf = new Uint8Array(1 + rows * cols * stride);
|
|
727
|
+
buf[0] = stride;
|
|
728
|
+
let i = 1;
|
|
729
|
+
for (let y = 0; y < rows; y++) {
|
|
730
|
+
for (let x = 0; x < cols; x++) {
|
|
731
|
+
const cell = frame[y][x];
|
|
732
|
+
if (fullColor) {
|
|
733
|
+
buf[i++] = cell.r;
|
|
734
|
+
buf[i++] = cell.g;
|
|
735
|
+
buf[i++] = cell.b;
|
|
736
|
+
buf[i++] = cell.a;
|
|
737
|
+
} else {
|
|
738
|
+
buf[i++] = Math.round(0.299 * cell.r + 0.587 * cell.g + 0.114 * cell.b);
|
|
739
|
+
buf[i++] = cell.a;
|
|
740
|
+
}
|
|
729
741
|
}
|
|
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
742
|
}
|
|
743
|
+
let binary = "";
|
|
744
|
+
for (let j = 0; j < buf.length; j++) binary += String.fromCharCode(buf[j]);
|
|
745
|
+
return btoa(binary);
|
|
733
746
|
}
|
|
734
747
|
async function asciify(source, canvas, { fontSize = 10, style = "classic", options = {} } = {}) {
|
|
735
748
|
let el;
|
|
@@ -821,188 +834,171 @@ async function asciifyVideo(source, canvas, { fontSize = 10, style = "classic",
|
|
|
821
834
|
cancelAnimationFrame(animId);
|
|
822
835
|
};
|
|
823
836
|
}
|
|
837
|
+
var EMBED_CDN_VERSION = "1.0.7";
|
|
838
|
+
function buildEmbedOpts(options, rows, cols, width, height, fps, animated) {
|
|
839
|
+
const o = {
|
|
840
|
+
r: rows,
|
|
841
|
+
c: cols,
|
|
842
|
+
w: width,
|
|
843
|
+
h: height,
|
|
844
|
+
cs: options.charset,
|
|
845
|
+
cm: options.colorMode,
|
|
846
|
+
as: options.animationStyle,
|
|
847
|
+
sp: options.animationSpeed,
|
|
848
|
+
inv: options.invert,
|
|
849
|
+
hs: options.hoverStrength,
|
|
850
|
+
hr: options.hoverRadius,
|
|
851
|
+
he: options.hoverEffect,
|
|
852
|
+
hc: options.hoverColor,
|
|
853
|
+
dr: options.dotSizeRatio,
|
|
854
|
+
dots: options.renderMode === "dots"
|
|
855
|
+
};
|
|
856
|
+
if (options.colorMode === "accent") o.ac = options.accentColor;
|
|
857
|
+
if (fps !== void 0) o.fps = fps;
|
|
858
|
+
if (animated) o.anim = true;
|
|
859
|
+
return JSON.stringify(o);
|
|
860
|
+
}
|
|
824
861
|
function generateEmbedCode(frame, options, width, height) {
|
|
825
862
|
const rows = frame.length;
|
|
826
863
|
if (rows === 0) return "";
|
|
827
864
|
const cols = frame[0].length;
|
|
828
865
|
const isDots = options.renderMode === "dots";
|
|
829
866
|
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));
|
|
867
|
+
const id = `ar-${Math.random().toString(36).slice(2, 9)}`;
|
|
868
|
+
const opts = buildEmbedOpts(options, rows, cols, width, height);
|
|
838
869
|
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>
|
|
870
|
+
<canvas id="${id}" width="${width}" height="${height}" style="display:block"></canvas>
|
|
871
|
+
<script src="https://cdn.jsdelivr.net/npm/asciify-engine@${EMBED_CDN_VERSION}/dist/embed.js"></script>
|
|
872
|
+
<script>Asciify('${id}','${data}',${opts})</script>
|
|
915
873
|
<!-- /Asciify Embed -->`;
|
|
916
874
|
}
|
|
917
875
|
function generateAnimatedEmbedCode(frames, options, fps, width, height) {
|
|
876
|
+
if (frames.length === 0) return "";
|
|
918
877
|
const rows = frames[0].length;
|
|
919
878
|
const cols = frames[0][0].length;
|
|
920
879
|
const isDots = options.renderMode === "dots";
|
|
921
880
|
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)));
|
|
881
|
+
const id = `ar-${Math.random().toString(36).slice(2, 9)}`;
|
|
882
|
+
const opts = buildEmbedOpts(options, rows, cols, width, height, fps, true);
|
|
929
883
|
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
|
-
|
|
884
|
+
<canvas id="${id}" width="${width}" height="${height}" style="display:block"></canvas>
|
|
885
|
+
<script src="https://cdn.jsdelivr.net/npm/asciify-engine@${EMBED_CDN_VERSION}/dist/embed.js"></script>
|
|
886
|
+
<script>Asciify('${id}',${JSON.stringify(allData)},${opts})</script>
|
|
887
|
+
<!-- /Asciify Animated Embed -->`;
|
|
888
|
+
}
|
|
889
|
+
function _fade(t) {
|
|
890
|
+
return t * t * t * (t * (t * 6 - 15) + 10);
|
|
891
|
+
}
|
|
892
|
+
function _lerp(a, b, t) {
|
|
893
|
+
return a + (b - a) * t;
|
|
894
|
+
}
|
|
895
|
+
function _hash2(ix, iy) {
|
|
896
|
+
let n = ix * 127 + iy * 311;
|
|
897
|
+
n = n >> 13 ^ n;
|
|
898
|
+
return (n * (n * n * 15731 + 789221) + 1376312589 & 2147483647) / 1073741823 - 1;
|
|
899
|
+
}
|
|
900
|
+
function _vnoise(x, y) {
|
|
901
|
+
const ix = Math.floor(x), iy = Math.floor(y);
|
|
902
|
+
const fx = x - ix, fy = y - iy;
|
|
903
|
+
const ux = _fade(fx), uy = _fade(fy);
|
|
904
|
+
const v00 = _hash2(ix, iy);
|
|
905
|
+
const v10 = _hash2(ix + 1, iy);
|
|
906
|
+
const v01 = _hash2(ix, iy + 1);
|
|
907
|
+
const v11 = _hash2(ix + 1, iy + 1);
|
|
908
|
+
return _lerp(_lerp(v00, v10, ux), _lerp(v01, v11, ux), uy);
|
|
909
|
+
}
|
|
910
|
+
function _fbm(x, y) {
|
|
911
|
+
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;
|
|
912
|
+
}
|
|
913
|
+
function renderWaveBackground(ctx, width, height, time, mousePos = { x: 0.5, y: 0.5 }, options = {}) {
|
|
914
|
+
const {
|
|
915
|
+
fontSize = 13,
|
|
916
|
+
charAspect = 0.62,
|
|
917
|
+
lineHeightRatio = 1.4,
|
|
918
|
+
chars = " .:-=+*#%@",
|
|
919
|
+
baseColor = null,
|
|
920
|
+
accentColor = "#d4ff00",
|
|
921
|
+
accentThreshold = 0.52,
|
|
922
|
+
mouseInfluence = 0.55,
|
|
923
|
+
mouseFalloff = 2.8,
|
|
924
|
+
speed = 1,
|
|
925
|
+
vortex = true,
|
|
926
|
+
sparkles = true,
|
|
927
|
+
breathe = true,
|
|
928
|
+
lightMode = false
|
|
929
|
+
} = options;
|
|
930
|
+
const charW = fontSize * charAspect;
|
|
931
|
+
const lineH = fontSize * lineHeightRatio;
|
|
932
|
+
const cols = Math.ceil(width / charW);
|
|
933
|
+
const rows = Math.ceil(height / lineH);
|
|
934
|
+
const mx = mousePos.x;
|
|
935
|
+
const my = mousePos.y;
|
|
936
|
+
let acR = 212, acG = 255, acB = 0;
|
|
937
|
+
if (accentColor) {
|
|
938
|
+
const hex = accentColor.replace("#", "");
|
|
939
|
+
if (hex.length === 6) {
|
|
940
|
+
acR = parseInt(hex.slice(0, 2), 16);
|
|
941
|
+
acG = parseInt(hex.slice(2, 4), 16);
|
|
942
|
+
acB = parseInt(hex.slice(4, 6), 16);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
ctx.clearRect(0, 0, width, height);
|
|
946
|
+
ctx.font = `${fontSize}px "JetBrains Mono", monospace`;
|
|
947
|
+
ctx.textBaseline = "top";
|
|
948
|
+
const t = time * speed;
|
|
949
|
+
const breatheAmp = breathe ? (Math.sin(t * 0.22) * 0.5 + 0.5) * 0.12 : 0;
|
|
950
|
+
for (let row = 0; row < rows; row++) {
|
|
951
|
+
for (let col = 0; col < cols; col++) {
|
|
952
|
+
const nx = col / cols;
|
|
953
|
+
const ny = row / rows;
|
|
954
|
+
const w1 = Math.sin(col * 0.08 + row * 0.05 + t * 0.6) * 0.5 + 0.5;
|
|
955
|
+
const w2 = Math.sin(col * 0.03 - row * 0.07 + t * 0.4) * 0.5 + 0.5;
|
|
956
|
+
const w3 = Math.sin(col * 0.05 + row * 0.03 + t * 0.8) * 0.5 + 0.5;
|
|
957
|
+
const sinePart = (w1 + w2 + w3) / 3;
|
|
958
|
+
const noiseScale = 0.045;
|
|
959
|
+
const noiseShift = t * 0.08;
|
|
960
|
+
const noisePart = _fbm(col * noiseScale + noiseShift, row * noiseScale * 1.4 - noiseShift * 0.7) * 0.5 + 0.5;
|
|
961
|
+
const driftFreq = 0.06;
|
|
962
|
+
const driftPart = Math.sin((col + row * 0.65) * driftFreq + t * 1.1) * 0.5 + 0.5;
|
|
963
|
+
const wavePart = sinePart * 0.45 + noisePart * 0.35 + driftPart * 0.2 + breatheAmp;
|
|
964
|
+
const dxRaw = nx - mx;
|
|
965
|
+
const dyRaw = ny - my;
|
|
966
|
+
const distRaw = Math.sqrt(dxRaw * dxRaw + dyRaw * dyRaw);
|
|
967
|
+
let vortexBump = 0;
|
|
968
|
+
if (vortex && distRaw < 0.35) {
|
|
969
|
+
const angle = Math.atan2(dyRaw, dxRaw);
|
|
970
|
+
const swirl = Math.sin(angle * 4 + t * 2.2 - distRaw * 14);
|
|
971
|
+
const falloff = Math.max(0, 1 - distRaw / 0.35);
|
|
972
|
+
vortexBump = swirl * falloff * falloff * 0.22;
|
|
973
|
+
}
|
|
974
|
+
const proximity = Math.max(0, 1 - distRaw * mouseFalloff);
|
|
975
|
+
const intensity = wavePart * (1 - mouseInfluence) + (proximity + vortexBump * 0.5) * mouseInfluence + vortexBump * 0.15;
|
|
976
|
+
const clamped = Math.min(1, Math.max(0, intensity));
|
|
977
|
+
let finalIntensity = clamped;
|
|
978
|
+
if (sparkles && clamped > 0.72) {
|
|
979
|
+
const bucket = Math.floor(t * 8);
|
|
980
|
+
const sparkleSeed = _hash2(col * 7 + bucket * 3, row * 11 + bucket);
|
|
981
|
+
if (sparkleSeed > 0.88) {
|
|
982
|
+
finalIntensity = Math.min(1, clamped + (sparkleSeed - 0.88) * 4);
|
|
976
983
|
}
|
|
977
984
|
}
|
|
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)
|
|
985
|
+
const charIdx = Math.floor(finalIntensity * (chars.length - 1));
|
|
986
|
+
if (chars[charIdx] === " ") continue;
|
|
987
|
+
const alpha = 0.015 + finalIntensity * 0.07;
|
|
988
|
+
const isAccent = finalIntensity > accentThreshold;
|
|
989
|
+
if (isAccent) {
|
|
990
|
+
const accentAlpha = Math.min(lightMode ? 0.4 : 0.28, alpha * (lightMode ? 4 : 2.8));
|
|
991
|
+
ctx.fillStyle = `rgba(${acR},${acG},${acB},${accentAlpha})`;
|
|
992
|
+
} else if (baseColor) {
|
|
993
|
+
ctx.fillStyle = baseColor.replace("{a}", String(alpha));
|
|
994
|
+
} else if (lightMode) {
|
|
995
|
+
ctx.fillStyle = `rgba(0,0,0,${alpha * 1.3})`;
|
|
996
|
+
} else {
|
|
997
|
+
ctx.fillStyle = `rgba(255,255,255,${alpha})`;
|
|
997
998
|
}
|
|
999
|
+
ctx.fillText(chars[charIdx], col * charW, row * lineH);
|
|
998
1000
|
}
|
|
999
|
-
ctx.globalAlpha=1;
|
|
1000
|
-
requestAnimationFrame(draw);
|
|
1001
1001
|
}
|
|
1002
|
-
requestAnimationFrame(draw);
|
|
1003
|
-
})();
|
|
1004
|
-
</script>
|
|
1005
|
-
<!-- /Asciify Animated Embed -->`;
|
|
1006
1002
|
}
|
|
1007
1003
|
|
|
1008
1004
|
// src/webgl-engine.ts
|
|
@@ -1267,7 +1263,7 @@ function makeTexture(gl, filter = gl.NEAREST) {
|
|
|
1267
1263
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1268
1264
|
return t;
|
|
1269
1265
|
}
|
|
1270
|
-
var ANIM_STYLES = ["none", "wave", "pulse", "rain", "breathe", "sparkle", "glitch", "spiral", "typewriter", "scatter"];
|
|
1266
|
+
var ANIM_STYLES = ["none", "wave", "pulse", "rain", "breathe", "sparkle", "glitch", "spiral", "typewriter", "scatter", "waveField"];
|
|
1271
1267
|
var HOVER_EFFECTS = ["spotlight", "magnify", "repel", "glow", "colorShift"];
|
|
1272
1268
|
var COLOR_MODES = ["grayscale", "fullcolor", "matrix", "accent"];
|
|
1273
1269
|
function tryCreateWebGLRenderer(canvas) {
|
|
@@ -1465,6 +1461,7 @@ exports.generateEmbedCode = generateEmbedCode;
|
|
|
1465
1461
|
exports.gifToAsciiFrames = gifToAsciiFrames;
|
|
1466
1462
|
exports.imageToAsciiFrame = imageToAsciiFrame;
|
|
1467
1463
|
exports.renderFrameToCanvas = renderFrameToCanvas;
|
|
1464
|
+
exports.renderWaveBackground = renderWaveBackground;
|
|
1468
1465
|
exports.tryCreateWebGLRenderer = tryCreateWebGLRenderer;
|
|
1469
1466
|
exports.videoToAsciiFrames = videoToAsciiFrames;
|
|
1470
1467
|
//# sourceMappingURL=index.cjs.map
|