/**
* Effect Card - Vanilla JavaScript
* A unified visual effects library for cards
* Includes: Electric Border, Lightning, Light Pillar, Floating Lines
* by Mahedi Amin
* @version 1.0.0
* @license MIT
*
* Note: For Light Pillar and Floating Lines effects, include Three.js:
* <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"><\/script>
*/
!(function (e){
"use strict";
const t={
parseColor(e){
if(!e||"string"!=typeof e) return null;
if((e=e.trim().toLowerCase()).startsWith("#"))
return this.hexToRgb(e);
if(e.startsWith("rgb")){
const t=e.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
if(t)
return {
r: parseInt(t[1], 10),
g: parseInt(t[2], 10),
b: parseInt(t[3], 10),
};}
if(e.startsWith("hsl")){
const t=e.match(/hsla?\s*\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%/i,
);
if(t)
return this.hslToRgb(parseFloat(t[1]),
parseFloat(t[2]),
parseFloat(t[3]),
);
}
if("undefined"!=typeof document){
const t=document.createElement("div");
(t.style.color=e), document.body.appendChild(t);
const i=getComputedStyle(t).color;
document.body.removeChild(t);
const n=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
if(n)
return {
r: parseInt(n[1], 10),
g: parseInt(n[2], 10),
b: parseInt(n[3], 10),
};}
return null;
},
hexToRgb(e){
if(((3!==(e=e.replace(/^#/, "")).length&&4!==e.length) ||
(e=e
.split("")
.map((e)=> e + e)
.join("")),
8===e.length&&(e=e.substring(0, 6)),
6!==e.length)
)
return null;
const t=parseInt(e, 16);
return isNaN(t)
? null
: { r: (t >> 16) & 255, g: (t >> 8) & 255, b: 255 & t };},
hslToRgb(e, t, i){
(t /=100), (i /=100);
const n=(1 - Math.abs(2 * i - 1)) * t,
o=n * (1 - Math.abs(((e / 60) % 2) - 1)),
s=i - n / 2;
let a=0,
r=0,
l=0;
return (
e >=0&&e < 60
? ((a=n), (r=o), (l=0))
: e >=60&&e < 120
? ((a=o), (r=n), (l=0))
: e >=120&&e < 180
? ((a=0), (r=n), (l=o))
: e >=180&&e < 240
? ((a=0), (r=o), (l=n))
: e >=240&&e < 300
? ((a=o), (r=0), (l=n))
: e >=300&&e < 360&&((a=n), (r=0), (l=o)),
{
r: Math.round(255 * (a + s)),
g: Math.round(255 * (r + s)),
b: Math.round(255 * (l + s)),
}
);
},
rgbToHsl(e, t, i){
(e /=255), (t /=255), (i /=255);
const n=Math.max(e, t, i),
o=Math.min(e, t, i);
let s=0,
a=0;
const r=(n + o) / 2;
if(n!==o){
const l=n - o;
switch (((a=r > 0.5 ? l / (2 - n - o):l / (n + o)), n)){
case e:
s=((t - i) / l + (t < i ? 6:0)) / 6;
break;
case t:
s=((i - e) / l + 2) / 6;
break;
case i:
s=((e - t) / l + 4) / 6;
}}
return {
h: Math.round(360 * s),
s: Math.round(100 * a),
l: Math.round(100 * r),
};},
toHslString(e){
const t=this.parseColor(e);
if(!t) return null;
const i=this.rgbToHsl(t.r, t.g, t.b);
return `${i.h}, ${i.s}%, ${i.l}%`;
},
toRgbNormalized(e){
const t=this.parseColor(e);
return t
? { r: t.r / 255, g: t.g / 255, b: t.b / 255 }
: { r: 1, g: 1, b: 1 };},
toRgbaString(e, t=1){
const i=this.parseColor(e);
return i ? `rgba(${i.r}, ${i.g}, ${i.b}, ${t})`:`rgba(0,0,0,${t})`;
},
toHue(e){
const t=this.parseColor(e);
if(!t) return 230;
return this.rgbToHsl(t.r, t.g, t.b).h;
},
},
i={
random: (e)=> (43758.5453 * Math.sin(12.9898 * e)) % 1,
noise2D(e, t){
const i=Math.floor(e),
n=Math.floor(t),
o=e - i,
s=t - n,
a=o * o * (3 - 2 * o),
r=s * s * (3 - 2 * s);
return (
this.random(i + 57 * n) * (1 - a) * (1 - r) +
this.random(i + 1 + 57 * n) * a * (1 - r) +
this.random(i + 57 * (n + 1)) * (1 - a) * r +
this.random(i + 1 + 57 * (n + 1)) * a * r
);
},
octavedNoise(e, t, i, n, o, s, a, r, l){
let h=0,
u=o,
d=s;
for (let o=0; o < t; o++){
let t=u;
0===o&&(t *=l),
(h +=t * this.noise2D(d * e + 100 * r, a * d * 0.3)),
(d *=i),
(u *=n);
}
return h;
},
},
n={
compileShader(e, t, i){
const n=e.createShader(i);
return n
? (e.shaderSource(n, t),
e.compileShader(n),
e.getShaderParameter(n, e.COMPILE_STATUS)
? n
: (console.error("Shader compile error:", e.getShaderInfoLog(n)),
e.deleteShader(n),
null))
: null;
},
createProgram(e, t, i){
const n=this.compileShader(e, t, e.VERTEX_SHADER),
o=this.compileShader(e, i, e.FRAGMENT_SHADER);
if(!n||!o) return null;
const s=e.createProgram();
return s
? (e.attachShader(s, n),
e.attachShader(s, o),
e.linkProgram(s),
e.getProgramParameter(s, e.LINK_STATUS)
? s
: (console.error("Program linking error:",
e.getProgramInfoLog(s),
),
null))
: null;
},
createFullscreenQuad(e, t){
const i=new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]),
n=e.createBuffer();
e.bindBuffer(e.ARRAY_BUFFER, n),
e.bufferData(e.ARRAY_BUFFER, i, e.STATIC_DRAW);
const o=e.getAttribLocation(t, "aPosition");
return (
e.enableVertexAttribArray(o),
e.vertexAttribPointer(o, 2, e.FLOAT, !1, 0, 0),
n
);
},
},
o=()=> "undefined"!=typeof THREE,
s={
basicVertex:
"\n      attribute vec2 aPosition;\n      void main(){\n        gl_Position=vec4(aPosition, 0.0, 1.0);\n      }\n    ",
lightning:
"\n      precision mediump float;\n      uniform vec2 iResolution;\n      uniform float iTime;\n      uniform float uHue;\n      uniform float uXOffset;\n      uniform float uSpeed;\n      uniform float uIntensity;\n      uniform float uSize;\n      \n      #define OCTAVE_COUNT 10\n\n      vec3 hsv2rgb(vec3 c){\n        vec3 rgb=clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n        return c.z * mix(vec3(1.0), rgb, c.y);\n      }\n\n      float hash11(float p){\n        p=fract(p * .1031);\n        p *=p + 33.33;\n        p *=p + p;\n        return fract(p);\n      }\n\n      float hash12(vec2 p){\n        vec3 p3=fract(vec3(p.xyx) * .1031);\n        p3 +=dot(p3, p3.yzx + 33.33);\n        return fract((p3.x + p3.y) * p3.z);\n      }\n\n      mat2 rotate2d(float theta){\n        float c=cos(theta);\n        float s=sin(theta);\n        return mat2(c, -s, s, c);\n      }\n\n      float noise(vec2 p){\n        vec2 ip=floor(p);\n        vec2 fp=fract(p);\n        float a=hash12(ip);\n        float b=hash12(ip + vec2(1.0, 0.0));\n        float c=hash12(ip + vec2(0.0, 1.0));\n        float d=hash12(ip + vec2(1.0, 1.0));\n        vec2 t=smoothstep(0.0, 1.0, fp);\n        return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n      }\n\n      float fbm(vec2 p){\n        float value=0.0;\n        float amplitude=0.5;\n        for (int i=0; i < OCTAVE_COUNT; ++i){\n          value +=amplitude * noise(p);\n          p *=rotate2d(0.45);\n          p *=2.0;\n          amplitude *=0.5;\n        }\n        return value;\n      }\n\n      void main(){\n        vec2 uv=gl_FragCoord.xy / iResolution.xy;\n        uv=2.0 * uv - 1.0;\n        uv.x *=iResolution.x / iResolution.y;\n        uv.x +=uXOffset;\n        \n        uv +=2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n        \n        float dist=abs(uv.x);\n        vec3 baseColor=hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n        vec3 col=baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n        float a=clamp(length(col) * 2.0, 0.0, 1.0);\n        gl_FragColor=vec4(col, a);\n      }\n    ",
laserFlowVertex:
"\n      precision highp float;\n      attribute vec3 position;\n      void main(){\n        gl_Position=vec4(position, 1.0);\n      }\n    ",
laserFlow:
"\n      #ifdef GL_ES\n      #extension GL_OES_standard_derivatives:enable\n      #endif\n      precision highp float;\n      precision mediump int;\n\n      uniform float iTime;\n      uniform vec3 iResolution;\n      uniform vec4 iMouse;\n      uniform float uWispDensity;\n      uniform float uTiltScale;\n      uniform float uFlowTime;\n      uniform float uFogTime;\n      uniform float uBeamXFrac;\n      uniform float uBeamYFrac;\n      uniform float uFlowSpeed;\n      uniform float uVLenFactor;\n      uniform float uHLenFactor;\n      uniform float uFogIntensity;\n      uniform float uFogScale;\n      uniform float uWSpeed;\n      uniform float uWIntensity;\n      uniform float uFlowStrength;\n      uniform float uDecay;\n      uniform float uFalloffStart;\n      uniform float uFogFallSpeed;\n      uniform vec3 uColor;\n      uniform float uFade;\n\n      #define PI 3.14159265359\n      #define TWO_PI 6.28318530718\n      #define EPS 1e-6\n      #define EDGE_SOFT (DT_LOCAL*4.0)\n      #define DT_LOCAL 0.0038\n      #define TAP_RADIUS 6\n      #define R_H 150.0\n      #define R_V 150.0\n      #define FLARE_HEIGHT 16.0\n      #define FLARE_AMOUNT 8.0\n      #define FLARE_EXP 2.0\n      #define TOP_FADE_START 0.1\n      #define TOP_FADE_EXP 1.0\n      #define FLOW_PERIOD 0.5\n      #define FLOW_SHARPNESS 1.5\n\n      #define W_BASE_X 1.5\n      #define W_LAYER_GAP 0.25\n      #define W_LANES 10\n      #define W_SIDE_DECAY 0.5\n      #define W_HALF 0.01\n      #define W_AA 0.15\n      #define W_CELL 20.0\n      #define W_SEG_MIN 0.01\n      #define W_SEG_MAX 0.55\n      #define W_CURVE_AMOUNT 15.0\n      #define W_CURVE_RANGE (FLARE_HEIGHT - 3.0)\n      #define W_BOTTOM_EXP 10.0\n\n      #define FOG_ON 1\n      #define FOG_CONTRAST 1.2\n      #define FOG_SPEED_U 0.1\n      #define FOG_SPEED_V -0.1\n      #define FOG_OCTAVES 5\n      #define FOG_BOTTOM_BIAS 0.8\n      #define FOG_TILT_TO_MOUSE 0.05\n      #define FOG_TILT_DEADZONE 0.01\n      #define FOG_TILT_MAX_X 0.35\n      #define FOG_TILT_SHAPE 1.5\n      #define FOG_BEAM_MIN 0.0\n      #define FOG_BEAM_MAX 0.75\n      #define FOG_MASK_GAMMA 0.5\n      #define FOG_EXPAND_SHAPE 12.2\n      #define FOG_EDGE_MIX 0.5\n\n      #define HFOG_EDGE_START 0.20\n      #define HFOG_EDGE_END 0.98\n      #define HFOG_EDGE_GAMMA 1.4\n      #define HFOG_Y_RADIUS 25.0\n      #define HFOG_Y_SOFT 60.0\n\n      #define EDGE_X0 0.22\n      #define EDGE_X1 0.995\n      #define EDGE_X_GAMMA 1.25\n      #define EDGE_LUMA_T0 0.0\n      #define EDGE_LUMA_T1 2.0\n      #define DITHER_STRENGTH 1.0\n\n      float g(float x){return x<=0.00031308?12.92*x:1.055*pow(x,1.0/2.4)-0.055;}\n      float bs(vec2 p,vec2 q,float powr){\n        float d=distance(p,q),f=powr*uFalloffStart,r=(f*f)/(d*d+EPS);\n        return powr*min(1.0,r);\n      }\n      float bsa(vec2 p,vec2 q,float powr,vec2 s){\n        vec2 d=p-q; float dd=(d.x*d.x)/(s.x*s.x)+(d.y*d.y)/(s.y*s.y),f=powr*uFalloffStart,r=(f*f)/(dd+EPS);\n        return powr*min(1.0,r);\n      }\n      float tri01(float x){float f=fract(x);return 1.0-abs(f*2.0-1.0);}\n      float tauWf(float t,float tmin,float tmax){float a=smoothstep(tmin,tmin+EDGE_SOFT,t),b=1.0-smoothstep(tmax-EDGE_SOFT,tmax,t);return max(0.0,a*b);} \n      float h21(vec2 p){p=fract(p*vec2(123.34,456.21));p+=dot(p,p+34.123);return fract(p.x*p.y);}\n      float vnoise(vec2 p){\n        vec2 i=floor(p),f=fract(p);\n        float a=h21(i),b=h21(i+vec2(1,0)),c=h21(i+vec2(0,1)),d=h21(i+vec2(1,1));\n        vec2 u=f*f*(3.0-2.0*f);\n        return mix(mix(a,b,u.x),mix(c,d,u.x),u.y);\n      }\n      float fbm2(vec2 p){\n        float v=0.0,amp=0.6; mat2 m=mat2(0.86,0.5,-0.5,0.86);\n        for(int i=0;i<FOG_OCTAVES;++i){v+=amp*vnoise(p); p=m*p*2.03+17.1; amp*=0.52;}\n        return v;\n      }\n      float rGate(float x,float l){float a=smoothstep(0.0,W_AA,x),b=1.0-smoothstep(l,l+W_AA,x);return max(0.0,a*b);}\n      float flareY(float y){float t=clamp(1.0-(clamp(y,0.0,FLARE_HEIGHT)/max(FLARE_HEIGHT,EPS)),0.0,1.0);return pow(t,FLARE_EXP);}\n\n      float vWisps(vec2 uv,float topF){\n        float y=uv.y,yf=(y+uFlowTime*uWSpeed)/W_CELL;\n        float dRaw=clamp(uWispDensity,0.0,2.0),d=dRaw<=0.0?1.0:dRaw;\n        float lanesF=floor(float(W_LANES)*min(d,1.0)+0.5);\n        int lanes=int(max(1.0,lanesF));\n        float sp=min(d,1.0),ep=max(d-1.0,0.0);\n        float fm=flareY(max(y,0.0)),rm=clamp(1.0-(y/max(W_CURVE_RANGE,EPS)),0.0,1.0),cm=fm*rm;\n        const float G=0.05; float xS=1.0+(FLARE_AMOUNT*W_CURVE_AMOUNT*G)*cm;\n        float sPix=clamp(y/R_V,0.0,1.0),bGain=pow(1.0-sPix,W_BOTTOM_EXP),sum=0.0;\n        for(int s=0;s<2;++s){\n          float sgn=s==0?-1.0:1.0;\n          for(int i=0;i<W_LANES;++i){\n            if(i>=lanes) break;\n            float off=W_BASE_X+float(i)*W_LAYER_GAP,xc=sgn*(off*xS);\n            float dx=abs(uv.x-xc),lat=1.0-smoothstep(W_HALF,W_HALF+W_AA,dx),amp=exp(-off*W_SIDE_DECAY);\n            float seed=h21(vec2(off,sgn*17.0)),yf2=yf+seed*7.0,ci=floor(yf2),fy=fract(yf2);\n            float seg=mix(W_SEG_MIN,W_SEG_MAX,h21(vec2(ci,off*2.3)));\n            float spR=h21(vec2(ci,off+sgn*31.0)),seg1=rGate(fy,seg)*step(spR,sp);\n            if(ep>0.0){float spR2=h21(vec2(ci*3.1+7.0,off*5.3+sgn*13.0)); float f2=fract(fy+0.5); seg1+=rGate(f2,seg*0.9)*step(spR2,ep);}\n            sum+=amp*lat*seg1;\n          }\n        }\n        float span=smoothstep(-3.0,0.0,y)*(1.0-smoothstep(R_V-6.0,R_V,y));\n        return uWIntensity*sum*topF*bGain*span;\n      }\n\n      void mainImage(out vec4 fc,in vec2 frag){\n        vec2 C=iResolution.xy*.5; float invW=1.0/max(C.x,1.0);\n        float sc=512.0/iResolution.x*.4;\n        vec2 uv=(frag-C)*sc,off=vec2(uBeamXFrac*iResolution.x*sc,uBeamYFrac*iResolution.y*sc);\n        vec2 uvc=uv - off;\n        float a=0.0,b=0.0;\n        float basePhase=1.5*PI+uDecay*.5; float tauMin=basePhase-uDecay; float tauMax=basePhase;\n        float cx=clamp(uvc.x/(R_H*uHLenFactor),-1.0,1.0),tH=clamp(TWO_PI-acos(cx),tauMin,tauMax);\n        for(int k=-TAP_RADIUS;k<=TAP_RADIUS;++k){\n          float tu=tH+float(k)*DT_LOCAL,wt=tauWf(tu,tauMin,tauMax); if(wt<=0.0) continue;\n          float spd=max(abs(sin(tu)),0.02),u=clamp((basePhase-tu)/max(uDecay,EPS),0.0,1.0),env=pow(1.0-abs(u*2.0-1.0),0.8);\n          vec2 p=vec2((R_H*uHLenFactor)*cos(tu),0.0);\n          a+=wt*bs(uvc,p,env*spd);\n        }\n        float yPix=uvc.y,cy=clamp(-yPix/(R_V*uVLenFactor),-1.0,1.0),tV=clamp(TWO_PI-acos(cy),tauMin,tauMax);\n        for(int k=-TAP_RADIUS;k<=TAP_RADIUS;++k){\n          float tu=tV+float(k)*DT_LOCAL,wt=tauWf(tu,tauMin,tauMax); if(wt<=0.0) continue;\n          float yb=(-R_V)*cos(tu),s=clamp(yb/R_V,0.0,1.0),spd=max(abs(sin(tu)),0.02);\n          float env=pow(1.0-s,0.6)*spd;\n          float cap=1.0-smoothstep(TOP_FADE_START,1.0,s); cap=pow(cap,TOP_FADE_EXP); env*=cap;\n          float ph=s/max(FLOW_PERIOD,EPS)+uFlowTime*uFlowSpeed;\n          float fl=pow(tri01(ph),FLOW_SHARPNESS);\n          env*=mix(1.0-uFlowStrength,1.0,fl);\n          float yp=(-R_V*uVLenFactor)*cos(tu),m=pow(smoothstep(FLARE_HEIGHT,0.0,yp),FLARE_EXP),wx=1.0+FLARE_AMOUNT*m;\n          vec2 sig=vec2(wx,1.0),p=vec2(0.0,yp);\n          float mask=step(0.0,yp);\n          b+=wt*bsa(uvc,p,mask*env,sig);\n        }\n        float sPix=clamp(yPix/R_V,0.0,1.0),topA=pow(1.0-smoothstep(TOP_FADE_START,1.0,sPix),TOP_FADE_EXP);\n        float L=a+b*topA;\n        float w=vWisps(vec2(uvc.x,yPix),topA);\n        float fog=0.0;\n      #if FOG_ON\n        vec2 fuv=uvc*uFogScale;\n        float mAct=step(1.0,length(iMouse.xy)),nx=((iMouse.x-C.x)*invW)*mAct;\n        float ax=abs(nx);\n        float stMag=mix(ax, pow(ax, FOG_TILT_SHAPE), 0.35);\n        float st=sign(nx) * stMag * uTiltScale;\n        st=clamp(st, -FOG_TILT_MAX_X, FOG_TILT_MAX_X);\n        vec2 dir=normalize(vec2(st,1.0));\n        fuv+=uFogTime*uFogFallSpeed*dir;\n        vec2 prp=vec2(-dir.y,dir.x);\n        fuv+=prp*(0.08*sin(dot(uvc,prp)*0.08+uFogTime*0.9));\n        float n=fbm2(fuv+vec2(fbm2(fuv+vec2(7.3,2.1)),fbm2(fuv+vec2(-3.7,5.9)))*0.6);\n        n=pow(clamp(n,0.0,1.0),FOG_CONTRAST);\n        float pixW=1.0 / max(iResolution.y, 1.0);\n      #ifdef GL_OES_standard_derivatives\n        float wL=max(fwidth(L), pixW);\n      #else\n        float wL=pixW;\n      #endif\n        float m0=pow(smoothstep(FOG_BEAM_MIN - wL, FOG_BEAM_MAX + wL, L),FOG_MASK_GAMMA);\n        float bm=1.0-pow(1.0-m0,FOG_EXPAND_SHAPE); bm=mix(bm*m0,bm,FOG_EDGE_MIX);\n        float yP=1.0-smoothstep(HFOG_Y_RADIUS,HFOG_Y_RADIUS+HFOG_Y_SOFT,abs(yPix));\n        float nxF=abs((frag.x-C.x)*invW),hE=1.0-smoothstep(HFOG_EDGE_START,HFOG_EDGE_END,nxF); hE=pow(clamp(hE,0.0,1.0),HFOG_EDGE_GAMMA);\n        float hW=mix(1.0,hE,clamp(yP,0.0,1.0));\n        float bBias=mix(1.0,1.0-sPix,FOG_BOTTOM_BIAS);\n        float browserFogIntensity=uFogIntensity;\n        browserFogIntensity *=1.8;\n        float radialFade=1.0 - smoothstep(0.0, 0.7, length(uvc) / 120.0);\n        float safariFog=n * browserFogIntensity * bBias * bm * hW * radialFade;\n        fog=safariFog;\n      #endif\n        float LF=L+fog;\n        float dith=(h21(frag)-0.5)*(DITHER_STRENGTH/255.0);\n        float tone=g(LF+w);\n        vec3 col=tone*uColor+dith;\n        float alpha=clamp(g(L+w*0.6)+dith*0.6,0.0,1.0);\n        float nxE=abs((frag.x-C.x)*invW),xF=pow(clamp(1.0-smoothstep(EDGE_X0,EDGE_X1,nxE),0.0,1.0),EDGE_X_GAMMA);\n        float scene=LF+max(0.0,w)*0.5,hi=smoothstep(EDGE_LUMA_T0,EDGE_LUMA_T1,scene);\n        float eM=mix(xF,1.0,hi);\n        col*=eM; alpha*=eM;\n        col*=uFade; alpha*=uFade;\n        fc=vec4(col,alpha);\n      }\n\n      void main(){\n        vec4 fc;\n        mainImage(fc, gl_FragCoord.xy);\n        gl_FragColor=fc;\n      }\n    ",
floatingLines:
"\n      precision highp float;\n      \n      uniform float iTime;\n      uniform vec3 iResolution;\n      uniform float uAnimationSpeed;\n      uniform bool uEnableTop;\n      uniform bool uEnableMiddle;\n      uniform bool uEnableBottom;\n      uniform int uTopLineCount;\n      uniform int uMiddleLineCount;\n      uniform int uBottomLineCount;\n      uniform float uTopLineDistance;\n      uniform float uMiddleLineDistance;\n      uniform float uBottomLineDistance;\n      uniform vec3 uTopWavePosition;\n      uniform vec3 uMiddleWavePosition;\n      uniform vec3 uBottomWavePosition;\n      uniform vec2 iMouse;\n      uniform bool uInteractive;\n      uniform float uBendRadius;\n      uniform float uBendStrength;\n      uniform float uBendInfluence;\n      uniform bool uParallax;\n      uniform float uParallaxStrength;\n      uniform vec2 uParallaxOffset;\n      uniform vec3 uLineGradient[8];\n      uniform int uLineGradientCount;\n      \n      const vec3 BLACK=vec3(0.0);\n      const vec3 PINK=vec3(233.0, 71.0, 245.0) / 255.0;\n      const vec3 BLUE=vec3(47.0, 75.0, 162.0) / 255.0;\n\n      mat2 rotate(float r){\n        return mat2(cos(r), sin(r), -sin(r), cos(r));\n      }\n\n      vec3 background_color(vec2 uv){\n        vec3 col=vec3(0.0);\n        float y=sin(uv.x - 0.2) * 0.3 - 0.1;\n        float m=uv.y - y;\n        col +=mix(BLUE, BLACK, smoothstep(0.0, 1.0, abs(m)));\n        col +=mix(PINK, BLACK, smoothstep(0.0, 1.0, abs(m - 0.8)));\n        return col * 0.5;\n      }\n\n      vec3 getLineColor(float t, vec3 baseColor){\n        if(uLineGradientCount <=0){\n          return baseColor;\n        }\n        \n        vec3 gradientColor;\n        \n        if(uLineGradientCount==1){\n          gradientColor=uLineGradient[0];\n        }else{\n          float clampedT=clamp(t, 0.0, 0.9999);\n          float scaled=clampedT * float(uLineGradientCount - 1);\n          int idx=int(floor(scaled));\n          float f=fract(scaled);\n          int idx2=min(idx + 1, uLineGradientCount - 1);\n          \n          vec3 c1=uLineGradient[idx];\n          vec3 c2=uLineGradient[idx2];\n          \n          gradientColor=mix(c1, c2, f);\n        }\n        \n        return gradientColor * 0.5;\n      }\n\n      float wave(vec2 uv, float offset, vec2 screenUv, vec2 mouseUv, bool shouldBend){\n        float time=iTime * uAnimationSpeed;\n        float x_offset=offset;\n        float x_movement=time * 0.1;\n        float amp=sin(offset + time * 0.2) * 0.3;\n        float y=sin(uv.x + x_offset + x_movement) * amp;\n\n        if(shouldBend){\n          vec2 d=screenUv - mouseUv;\n          float influence=exp(-dot(d, d) * uBendRadius);\n          float bendOffset=(mouseUv.y - screenUv.y) * influence * uBendStrength * uBendInfluence;\n          y +=bendOffset;\n        }\n\n        float m=uv.y - y;\n        return 0.0175 / max(abs(m) + 0.01, 1e-3) + 0.01;\n      }\n\n      void main(){\n        vec2 baseUv=(2.0 * gl_FragCoord.xy - iResolution.xy) / iResolution.y;\n        baseUv.y *=-1.0;\n        \n        if(uParallax){\n          baseUv +=uParallaxOffset;\n        }\n\n        vec3 col=vec3(0.0);\n        vec3 b=vec3(0.0);\n\n        vec2 mouseUv=vec2(0.0);\n        if(uInteractive){\n          mouseUv=(2.0 * iMouse - iResolution.xy) / iResolution.y;\n          mouseUv.y *=-1.0;\n        }\n        \n        if(uEnableBottom){\n          for (int i=0; i < 10; ++i){\n            if(i >=uBottomLineCount) break;\n            float fi=float(i);\n            float t=fi / max(float(uBottomLineCount - 1), 1.0);\n            vec3 lineCol=getLineColor(t, b);\n            \n            float angle=uBottomWavePosition.z * log(length(baseUv) + 1.0);\n            vec2 ruv=baseUv * rotate(angle);\n            col +=lineCol * wave(\n              ruv + vec2(uBottomLineDistance * fi + uBottomWavePosition.x, uBottomWavePosition.y),\n              1.5 + 0.2 * fi,\n              baseUv,\n              mouseUv,\n              uInteractive\n) * 0.2;\n          }\n        }\n\n        if(uEnableMiddle){\n          for (int i=0; i < 10; ++i){\n            if(i >=uMiddleLineCount) break;\n            float fi=float(i);\n            float t=fi / max(float(uMiddleLineCount - 1), 1.0);\n            vec3 lineCol=getLineColor(t, b);\n            \n            float angle=uMiddleWavePosition.z * log(length(baseUv) + 1.0);\n            vec2 ruv=baseUv * rotate(angle);\n            col +=lineCol * wave(\n              ruv + vec2(uMiddleLineDistance * fi + uMiddleWavePosition.x, uMiddleWavePosition.y),\n              2.0 + 0.15 * fi,\n              baseUv,\n              mouseUv,\n              uInteractive\n);\n          }\n        }\n\n        if(uEnableTop){\n          for (int i=0; i < 10; ++i){\n            if(i >=uTopLineCount) break;\n            float fi=float(i);\n            float t=fi / max(float(uTopLineCount - 1), 1.0);\n            vec3 lineCol=getLineColor(t, b);\n            \n            float angle=uTopWavePosition.z * log(length(baseUv) + 1.0);\n            vec2 ruv=baseUv * rotate(angle);\n            ruv.x *=-1.0;\n            col +=lineCol * wave(\n              ruv + vec2(uTopLineDistance * fi + uTopWavePosition.x, uTopWavePosition.y),\n              1.0 + 0.2 * fi,\n              baseUv,\n              mouseUv,\n              uInteractive\n) * 0.1;\n          }\n        }\n\n        float a=clamp(length(col) * 2.0, 0.0, 1.0);\n        gl_FragColor=vec4(col, a);\n      }\n    ",
};
class a {
constructor(e, t){
(this.container=e),
(this.options=t),
(this.canvas=null),
(this.ctx=null),
(this.animationId=null),
(this.time=0),
(this.lastFrameTime=0),
this._init();
}
_init(){
(this.canvas=document.createElement("canvas")),
(this.canvas.className =
"effect-card-canvas effect-card-electric-border"),
(this.canvas.style.cssText =
"position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);pointer-events:none;z-index:2;"),
this.container.appendChild(this.canvas),
(this.ctx=this.canvas.getContext("2d")),
this._updateSize(),
this._startAnimation(),
(this._resizeObserver=new ResizeObserver(()=> this._updateSize())),
this._resizeObserver.observe(this.container);
}
_updateSize(){
const e=this.container.getBoundingClientRect(),
t=e.width + 120,
i=e.height + 120,
n=Math.min(window.devicePixelRatio||1, 2);
(this.canvas.width=t * n),
(this.canvas.height=i * n),
(this.canvas.style.width=`${t}px`),
(this.canvas.style.height=`${i}px`),
this.ctx.scale(n, n),
(this._width=t),
(this._height=i),
(this._borderOffset=60);
}
_getCornerPoint(e, t, i, n, o, s){
const a=n + s * o;
return { x: e + i * Math.cos(a), y: t + i * Math.sin(a) };}
_getRoundedRectPoint(e, t, i, n, o, s){
const a=n - 2 * s,
r=o - 2 * s,
l=(Math.PI * s) / 2,
h=e * (2 * a + 2 * r + 4 * l);
let u=0;
if(h <=u + a){
return { x: t + s + ((h - u) / a) * a, y: i };}
if(((u +=a), h <=u + l)){
const e=(h - u) / l;
return this._getCornerPoint(t + n - s,
i + s,
s,
-Math.PI / 2,
Math.PI / 2,
e,
);
}
if(((u +=l), h <=u + r)){
return { x: t + n, y: i + s + ((h - u) / r) * r };}
if(((u +=r), h <=u + l)){
const e=(h - u) / l;
return this._getCornerPoint(t + n - s, i + o - s, s, 0, Math.PI / 2, e);
}
if(((u +=l), h <=u + a)){
return { x: t + n - s - ((h - u) / a) * a, y: i + o };}
if(((u +=a), h <=u + l)){
const e=(h - u) / l;
return this._getCornerPoint(t + s,
i + o - s,
s,
Math.PI / 2,
Math.PI / 2,
e,
);
}
if(((u +=l), h <=u + r)){
return { x: t, y: i + o - s - ((h - u) / r) * r };}
u +=r;
const d=(h - u) / l;
return this._getCornerPoint(t + s, i + s, s, Math.PI, Math.PI / 2, d);
}
_draw(e){
if(!this.canvas||!this.ctx) return;
const t=(e - this.lastFrameTime) / 1e3;
(this.time +=t * this.options.speed), (this.lastFrameTime=e);
const { color: n, chaos: o, borderRadius: s }=this.options,
a=Math.min(window.devicePixelRatio||1, 2);
this.ctx.setTransform(1, 0, 0, 1, 0, 0),
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height),
this.ctx.scale(a, a),
(this.ctx.strokeStyle=n),
(this.ctx.lineWidth=1),
(this.ctx.lineCap="round"),
(this.ctx.lineJoin="round");
const r=this._borderOffset,
l=this._borderOffset,
h=this._width - 2 * this._borderOffset,
u=this._height - 2 * this._borderOffset,
d=Math.min(h, u) / 2,
f=Math.min(s, d),
c=2 * (h + u) + 2 * Math.PI * f,
m=Math.floor(c / 2);
this.ctx.beginPath();
for (let e=0; e <=m; e++){
const t=e / m,
n=this._getRoundedRectPoint(t, r, l, h, u, f),
s=i.octavedNoise(8 * t, 10, 1.6, 0.7, o, 10, this.time, 0, 0),
a=i.octavedNoise(8 * t, 10, 1.6, 0.7, o, 10, this.time, 1, 0),
d=n.x + 60 * s,
c=n.y + 60 * a;
0===e ? this.ctx.moveTo(d, c):this.ctx.lineTo(d, c);
}
this.ctx.closePath(),
this.ctx.stroke(),
(this.animationId=requestAnimationFrame((e)=> this._draw(e)));
}
_startAnimation(){
(this.lastFrameTime=performance.now()),
(this.animationId=requestAnimationFrame((e)=> this._draw(e)));
}
update(e){
this.options={ ...this.options, ...e };}
destroy(){
this.animationId&&cancelAnimationFrame(this.animationId),
this._resizeObserver&&this._resizeObserver.disconnect(),
this.canvas &&
this.canvas.parentNode &&
this.canvas.parentNode.removeChild(this.canvas);
}}
class r {
constructor(e, t){
(this.container=e),
(this.options=t),
(this.canvas=null),
(this.gl=null),
(this.program=null),
(this.uniforms={}),
(this.animationId=null),
(this.startTime=performance.now()),
this._init();
}
_init(){
(this.canvas=document.createElement("canvas")),
(this.canvas.className="effect-card-canvas effect-card-webgl"),
(this.canvas.style.cssText =
"position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1;border-radius:inherit;"),
this.container.appendChild(this.canvas),
(this.gl=this.canvas.getContext("webgl", {
antialias: !1,
alpha: !0,
depth: !1,
stencil: !1,
powerPreference: "high-performance",
})),
this.gl
? ((this.program=n.createProgram(this.gl,
s.basicVertex,
s.lightning,
)),
this.program &&
(this.gl.useProgram(this.program),
n.createFullscreenQuad(this.gl, this.program),
this._setupUniforms(),
this._updateSize(),
this._startAnimation(),
(this._resizeObserver=new ResizeObserver(()=>
this._updateSize(),
)),
this._resizeObserver.observe(this.container)))
: console.warn("WebGL not supported");
}
_setupUniforms(){
const e=this.gl;
this.uniforms={
iResolution: e.getUniformLocation(this.program, "iResolution"),
iTime: e.getUniformLocation(this.program, "iTime"),
uHue: e.getUniformLocation(this.program, "uHue"),
uXOffset: e.getUniformLocation(this.program, "uXOffset"),
uSpeed: e.getUniformLocation(this.program, "uSpeed"),
uIntensity: e.getUniformLocation(this.program, "uIntensity"),
uSize: e.getUniformLocation(this.program, "uSize"),
};}
_updateSize(){
const e=this.container.getBoundingClientRect(),
t=Math.min(window.devicePixelRatio||1, 2);
(this.canvas.width=e.width * t),
(this.canvas.height=e.height * t),
this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
}
_render(){
if(!this.gl||!this.program) return;
const e=(performance.now() - this.startTime) / 1e3,
t=this.gl,
{ hue: i, xOffset: n, speed: o, intensity: s, size: a }=this.options;
t.uniform2f(
this.uniforms.iResolution,
this.canvas.width,
this.canvas.height,
),
t.uniform1f(this.uniforms.iTime, e),
t.uniform1f(this.uniforms.uHue, i),
t.uniform1f(this.uniforms.uXOffset, n),
t.uniform1f(this.uniforms.uSpeed, o),
t.uniform1f(this.uniforms.uIntensity, s),
t.uniform1f(this.uniforms.uSize, a),
t.drawArrays(t.TRIANGLES, 0, 6),
(this.animationId=requestAnimationFrame(()=> this._render()));
}
_startAnimation(){
this.animationId=requestAnimationFrame(()=> this._render());
}
update(e){
this.options={ ...this.options, ...e };}
destroy(){
this.animationId&&cancelAnimationFrame(this.animationId),
this._resizeObserver&&this._resizeObserver.disconnect(),
this.canvas &&
this.canvas.parentNode &&
this.canvas.parentNode.removeChild(this.canvas);
}}
class l {
constructor(e, t){
if(((this.container=e),
(this.options=t),
(this.renderer=null),
(this.scene=null),
(this.camera=null),
(this.material=null),
(this.geometry=null),
(this.mesh=null),
(this.animationId=null),
(this.clock=null),
(this.flowTime=0),
(this.fogTime=0),
(this.fade=0),
(this.mouseX=0),
(this.mouseY=0),
(this.mouseSmooth={ x: 0, y: 0 }),
(this.mouseTarget={ x: 0, y: 0 }),
(this.prevTime=0),
!o())
)
return (
console.warn('EffectCard: Three.js is required for Laser Flow effect. Please include: <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>',
),
void this._createFallback()
);
this._init();
}
_createFallback(){
const e=document.createElement("div");
(e.className="effect-card-fallback"),
(e.style.cssText =
"position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:transparent;color:#888;font-size:12px;text-align:center;padding:20px;border-radius:inherit;"),
(e.textContent="Laser Flow requires Three.js"),
this.container.appendChild(e),
(this._fallback=e);
}
_init(){
const e=this.container.getBoundingClientRect();
(this.clock=new THREE.Clock()),
(this.scene=new THREE.Scene()),
(this.camera=new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1)),
(this.renderer=new THREE.WebGLRenderer({
antialias: !1,
alpha: !0,
depth: !1,
stencil: !1,
powerPreference: "high-performance",
premultipliedAlpha: !1,
preserveDrawingBuffer: !1,
})),
this.renderer.setSize(e.width, e.height),
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio||1, 2)),
this.renderer.setClearColor(0, 0),
(this.renderer.domElement.style.cssText =
"position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:-1;border-radius:inherit;"),
this.container.appendChild(this.renderer.domElement);
const i=t.toRgbNormalized(this.options.color);
(this.material=new THREE.RawShaderMaterial({
vertexShader: s.laserFlowVertex,
fragmentShader: s.laserFlow,
uniforms: {
iTime: { value: 0 },
iResolution: {
value: new THREE.Vector3(
e.width * this.renderer.getPixelRatio(),
e.height * this.renderer.getPixelRatio(),
1,
),
},
iMouse: { value: new THREE.Vector4(0, 0, 0, 0) },
uWispDensity: { value: this.options.wispDensity },
uTiltScale: { value: this.options.mouseTiltStrength },
uFlowTime: { value: 0 },
uFogTime: { value: 0 },
uBeamXFrac: { value: this.options.horizontalBeamOffset },
uBeamYFrac: { value: this.options.verticalBeamOffset },
uFlowSpeed: { value: this.options.flowSpeed },
uVLenFactor: { value: this.options.verticalSizing },
uHLenFactor: { value: this.options.horizontalSizing },
uFogIntensity: { value: this.options.fogIntensity },
uFogScale: { value: this.options.fogScale },
uWSpeed: { value: this.options.wispSpeed },
uWIntensity: { value: this.options.wispIntensity },
uFlowStrength: { value: this.options.flowStrength },
uDecay: { value: this.options.decay },
uFalloffStart: { value: this.options.falloffStart },
uFogFallSpeed: { value: this.options.fogFallSpeed },
uColor: { value: new THREE.Vector3(i.r, i.g, i.b) },
uFade: { value: 0 },
},
transparent: !1,
depthTest: !1,
depthWrite: !1,
blending: THREE.NormalBlending,
})),
(this.geometry=new THREE.BufferGeometry()),
this.geometry.setAttribute("position",
new THREE.BufferAttribute(new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]),
3,
),
),
(this.mesh=new THREE.Mesh(this.geometry, this.material)),
(this.mesh.frustumCulled = !1),
this.scene.add(this.mesh),
(this._rect=this.renderer.domElement.getBoundingClientRect()),
(this._onMouseMove=(e)=> {
const t=this._rect;
if(!t) return;
const i=e.clientX - t.left,
n=e.clientY - t.top,
o=this.renderer.getPixelRatio(),
s=t.height * o;
(this.mouseTarget.x=i * o), (this.mouseTarget.y=s - n * o);
}),
(this._onMouseLeave=()=> {
(this.mouseTarget.x=0), (this.mouseTarget.y=0);
}),
(this.renderer.domElement.style.pointerEvents="auto"),
this.renderer.domElement.addEventListener("pointermove",
this._onMouseMove,
{ passive: !0 },
),
this.renderer.domElement.addEventListener("pointerdown",
this._onMouseMove,
{ passive: !0 },
),
this.renderer.domElement.addEventListener("pointerenter",
this._onMouseMove,
{ passive: !0 },
),
this.renderer.domElement.addEventListener("pointerleave",
this._onMouseLeave,
{ passive: !0 },
),
(this._resizeObserver=new ResizeObserver(()=> this._updateSize())),
this._resizeObserver.observe(this.container),
this._startAnimation();
}
_updateSize(){
if(!this.renderer) return;
const e=this.container.getBoundingClientRect(),
t=this.renderer.getPixelRatio();
this.renderer.setSize(e.width, e.height),
this.material.uniforms.iResolution.value.set(e.width * t,
e.height * t,
t,
),
(this._rect=this.renderer.domElement.getBoundingClientRect());
}
_render(){
if(!this.renderer||!this.scene||!this.camera) return;
const e=this.clock.getElapsedTime(),
t=Math.max(0, e - this.prevTime);
this.prevTime=e;
const i=Math.min(0.033, Math.max(0.001, t));
(this.material.uniforms.iTime.value=e),
(this.flowTime +=i),
(this.fogTime +=i),
(this.material.uniforms.uFlowTime.value=this.flowTime),
(this.material.uniforms.uFogTime.value=this.fogTime),
this.fade < 1 &&
((this.fade=Math.min(1, this.fade + i)),
(this.material.uniforms.uFade.value=this.fade));
const n=Math.max(0.001, this.options.mouseSmoothTime||0.05),
o=1 - Math.exp(-i / n);
(this.mouseSmooth.x +=(this.mouseTarget.x - this.mouseSmooth.x) * o),
(this.mouseSmooth.y +=(this.mouseTarget.y - this.mouseSmooth.y) * o),
this.material.uniforms.iMouse.value.set(this.mouseSmooth.x,
this.mouseSmooth.y,
0,
0,
),
this.renderer.render(this.scene, this.camera),
(this.animationId=requestAnimationFrame(()=> this._render()));
}
_startAnimation(){
this.animationId=requestAnimationFrame(()=> this._render());
}
update(e){
if(((this.options={ ...this.options, ...e }), this.material)){
const e=t.toRgbNormalized(this.options.color);
(this.material.uniforms.uWispDensity.value=this.options.wispDensity),
(this.material.uniforms.uTiltScale.value =
this.options.mouseTiltStrength),
(this.material.uniforms.uBeamXFrac.value =
this.options.horizontalBeamOffset),
(this.material.uniforms.uBeamYFrac.value =
this.options.verticalBeamOffset),
(this.material.uniforms.uFlowSpeed.value=this.options.flowSpeed),
(this.material.uniforms.uVLenFactor.value =
this.options.verticalSizing),
(this.material.uniforms.uHLenFactor.value =
this.options.horizontalSizing),
(this.material.uniforms.uFogIntensity.value =
this.options.fogIntensity),
(this.material.uniforms.uFogScale.value=this.options.fogScale),
(this.material.uniforms.uWSpeed.value=this.options.wispSpeed),
(this.material.uniforms.uWIntensity.value =
this.options.wispIntensity),
(this.material.uniforms.uFlowStrength.value =
this.options.flowStrength),
(this.material.uniforms.uDecay.value=this.options.decay),
(this.material.uniforms.uFalloffStart.value =
this.options.falloffStart),
(this.material.uniforms.uFogFallSpeed.value =
this.options.fogFallSpeed),
this.material.uniforms.uColor.value.set(e.r, e.g, e.b);
}}
destroy(){
this.animationId&&cancelAnimationFrame(this.animationId),
this._resizeObserver&&this._resizeObserver.disconnect(),
this._onMouseMove &&
this.renderer &&
(this.renderer.domElement.removeEventListener("pointermove",
this._onMouseMove,
),
this.renderer.domElement.removeEventListener("pointerdown",
this._onMouseMove,
),
this.renderer.domElement.removeEventListener("pointerenter",
this._onMouseMove,
)),
this._onMouseLeave &&
this.renderer &&
this.renderer.domElement.removeEventListener("pointerleave",
this._onMouseLeave,
),
this.renderer &&
(this.renderer.dispose(),
this.renderer.forceContextLoss(),
this.renderer.domElement &&
this.renderer.domElement.parentNode &&
this.renderer.domElement.parentNode.removeChild(this.renderer.domElement,
)),
this.material&&this.material.dispose(),
this.geometry&&this.geometry.dispose(),
this._fallback &&
this._fallback.parentNode &&
this._fallback.parentNode.removeChild(this._fallback);
}}
class h {
constructor(e, t){
if(((this.container=e),
(this.options=t),
(this.renderer=null),
(this.scene=null),
(this.camera=null),
(this.material=null),
(this.geometry=null),
(this.mesh=null),
(this.animationId=null),
(this.clock=null),
(this.mouseX=0),
(this.mouseY=0),
(this.targetMouseX=0),
(this.targetMouseY=0),
(this.bendInfluence=0),
(this.targetBendInfluence=0),
!o())
)
return (
console.warn('EffectCard: Three.js is required for Floating Lines effect. Please include: <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>',
),
void this._createFallback()
);
this._init();
}
_createFallback(){
const e=document.createElement("div");
(e.className="effect-card-fallback"),
(e.style.cssText =
"position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:transparent;color:#888;font-size:12px;text-align:center;padding:20px;border-radius:inherit;"),
(e.textContent="Floating Lines requires Three.js"),
this.container.appendChild(e),
(this._fallback=e);
}
_init(){
const e=this.container.getBoundingClientRect();
(this.clock=new THREE.Clock()),
(this.scene=new THREE.Scene()),
(this.camera=new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1)),
(this.camera.position.z=1),
(this.renderer=new THREE.WebGLRenderer({ antialias: !0, alpha: !0 })),
this.renderer.setSize(e.width, e.height),
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)),
this.renderer.setClearColor(0, 0),
(this.renderer.domElement.style.cssText =
"position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:-1;border-radius:inherit;"),
this.container.appendChild(this.renderer.domElement);
const i=[],
n=this.options.linesGradient||[
this.options.color1,
this.options.color2,
];
for (let e=0; e < 8; e++)
if(e < n.length){
const o=t.toRgbNormalized(n[e]);
i.push(new THREE.Vector3(o.r, o.g, o.b));
} else i.push(new THREE.Vector3(1, 1, 1));
(this.material=new THREE.ShaderMaterial({
vertexShader:
"\n          precision highp float;\n          void main(){\n            gl_Position=projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n          }\n        ",
fragmentShader: s.floatingLines,
uniforms: {
iTime: { value: 0 },
iResolution: { value: new THREE.Vector3(e.width, e.height, 1) },
uAnimationSpeed: { value: this.options.animationSpeed },
uEnableTop: { value: this.options.enabledWaves.includes("top") },
uEnableMiddle: {
value: this.options.enabledWaves.includes("middle"),
},
uEnableBottom: {
value: this.options.enabledWaves.includes("bottom"),
},
uTopLineCount: { value: this.options.topLineCount },
uMiddleLineCount: { value: this.options.middleLineCount },
uBottomLineCount: { value: this.options.bottomLineCount },
uTopLineDistance: {
value: 0.01 * (this.options.topLineDistance||5),
},
uMiddleLineDistance: {
value: 0.01 * (this.options.middleLineDistance||5),
},
uBottomLineDistance: {
value: 0.01 * (this.options.bottomLineDistance||5),
},
uTopWavePosition: {
value: new THREE.Vector3(
this.options.topWaveX||10,
this.options.topWaveY||0.5,
this.options.topWaveRotate||-0.4,
),
},
uMiddleWavePosition: {
value: new THREE.Vector3(
this.options.middleWaveX||5,
this.options.middleWaveY||0,
this.options.middleWaveRotate||0.2,
),
},
uBottomWavePosition: {
value: new THREE.Vector3(
this.options.bottomWaveX||2,
this.options.bottomWaveY||-0.7,
this.options.bottomWaveRotate||0.4,
),
},
iMouse: { value: new THREE.Vector2(-1e3, -1e3) },
uInteractive: { value: this.options.interactive },
uBendRadius: { value: this.options.bendRadius },
uBendStrength: { value: this.options.bendStrength },
uBendInfluence: { value: 0 },
uParallax: { value: this.options.parallax||!1 },
uParallaxStrength: { value: this.options.parallaxStrength||0.2 },
uParallaxOffset: { value: new THREE.Vector2(0, 0) },
uLineGradient: { value: i },
uLineGradientCount: { value: n.length },
},
})),
(this.geometry=new THREE.PlaneGeometry(2, 2)),
(this.mesh=new THREE.Mesh(this.geometry, this.material)),
this.scene.add(this.mesh),
this.options.interactive &&
((this._onMouseMove=(e)=> {
const t=this.renderer.domElement.getBoundingClientRect(),
i=e.clientX - t.left,
n=e.clientY - t.top,
o=this.renderer.getPixelRatio();
(this.targetMouseX=i * o),
(this.targetMouseY=(t.height - n) * o),
(this.targetBendInfluence=1);
}),
(this._onMouseLeave=()=> {
this.targetBendInfluence=0;
}),
this.renderer.domElement.addEventListener("pointermove",
this._onMouseMove,
{ passive: !0 },
),
this.renderer.domElement.addEventListener("pointerleave",
this._onMouseLeave,
{ passive: !0 },
)),
(this._resizeObserver=new ResizeObserver(()=> this._updateSize())),
this._resizeObserver.observe(this.container),
this._startAnimation();
}
_updateSize(){
if(!this.renderer) return;
const e=this.container.getBoundingClientRect();
this.renderer.setSize(e.width, e.height);
const t=this.renderer.domElement.width,
i=this.renderer.domElement.height;
this.material.uniforms.iResolution.value.set(t, i, 1);
}
_render(){
if(!this.renderer||!this.scene||!this.camera) return;
this.material.uniforms.iTime.value=this.clock.getElapsedTime();
const e=0.05;
(this.mouseX +=(this.targetMouseX - this.mouseX) * e),
(this.mouseY +=(this.targetMouseY - this.mouseY) * e),
(this.bendInfluence +=
(this.targetBendInfluence - this.bendInfluence) * e),
this.material.uniforms.iMouse.value.set(this.mouseX, this.mouseY),
(this.material.uniforms.uBendInfluence.value=this.bendInfluence),
this.renderer.render(this.scene, this.camera),
(this.animationId=requestAnimationFrame(()=> this._render()));
}
_startAnimation(){
this.animationId=requestAnimationFrame(()=> this._render());
}
update(e){
(this.options={ ...this.options, ...e }),
this.material &&
((this.material.uniforms.uAnimationSpeed.value =
this.options.animationSpeed),
(this.material.uniforms.uEnableTop.value =
this.options.enabledWaves.includes("top")),
(this.material.uniforms.uEnableMiddle.value =
this.options.enabledWaves.includes("middle")),
(this.material.uniforms.uEnableBottom.value =
this.options.enabledWaves.includes("bottom")),
(this.material.uniforms.uTopLineCount.value =
this.options.topLineCount),
(this.material.uniforms.uMiddleLineCount.value =
this.options.middleLineCount),
(this.material.uniforms.uBottomLineCount.value =
this.options.bottomLineCount),
(this.material.uniforms.uBendRadius.value=this.options.bendRadius),
(this.material.uniforms.uBendStrength.value =
this.options.bendStrength),
(this.material.uniforms.uInteractive.value =
this.options.interactive));
}
destroy(){
this.animationId&&cancelAnimationFrame(this.animationId),
this._resizeObserver&&this._resizeObserver.disconnect(),
this._onMouseMove &&
this.renderer.domElement.removeEventListener("pointermove",
this._onMouseMove,
),
this._onMouseLeave &&
this.renderer.domElement.removeEventListener("pointerleave",
this._onMouseLeave,
),
this.renderer &&
(this.renderer.dispose(),
this.renderer.domElement &&
this.renderer.domElement.parentNode &&
this.renderer.domElement.parentNode.removeChild(this.renderer.domElement,
)),
this.material&&this.material.dispose(),
this.geometry&&this.geometry.dispose(),
this._fallback &&
this._fallback.parentNode &&
this._fallback.parentNode.removeChild(this._fallback);
}}
const u={
ELECTRIC_BORDER: "electric-border",
LIGHTNING: "lightning",
LASER_FLOW: "laser-flow",
FLOATING_LINES: "floating-lines",
},
d={
type: u.ELECTRIC_BORDER,
color: "#FF79C6",
intensity: 1,
speed: 1,
interactive: !1,
disabled: !1,
chaos: 0.12,
borderRadius: 24,
hue: 230,
xOffset: 0,
size: 1,
wispDensity: 1,
mouseTiltStrength: 0.01,
mouseSmoothTime: 0.05,
horizontalBeamOffset: 0.1,
verticalBeamOffset: 0,
flowSpeed: 0.35,
verticalSizing: 2,
horizontalSizing: 0.5,
fogIntensity: 0.45,
fogScale: 0.3,
wispSpeed: 15,
wispIntensity: 5,
flowStrength: 0.25,
decay: 1.1,
falloffStart: 1.2,
fogFallSpeed: 0.6,
color1: "#e947f5",
color2: "#2f4ba2",
animationSpeed: 1,
enabledWaves: ["top", "middle", "bottom"],
topLineCount: 6,
middleLineCount: 6,
bottomLineCount: 6,
topLineDistance: 5,
middleLineDistance: 5,
bottomLineDistance: 5,
bendRadius: 5,
bendStrength: -0.5,
parallax: !0,
parallaxStrength: 0.2,
};
class f {
constructor(e, t={}){
(this.element="string"==typeof e ? document.querySelector(e):e),
this.element
? ((this.options={ ...d, ...t }),
(this.renderer=null),
this._init())
: console.warn("EffectCard: Element not found");
}
_init(){
this.element.classList.add("effect-card"),
(this.element.style.position="relative"),
(this.element.style.overflow="visible"),
(this.element.style.isolation="isolate"),
this.options.disabled||this._createRenderer(),
this._applyDataAttributes();
}
_applyDataAttributes(){
this.element.setAttribute("data-effect-type", this.options.type),
this.element.setAttribute("data-effect-disabled",
this.options.disabled,
);
}
_createRenderer(){
switch ((this._destroyRenderer(), this.options.type)){
case u.ELECTRIC_BORDER:
this.renderer=new a(this.element, {
color: this.options.color,
speed: this.options.speed,
chaos: this.options.chaos,
borderRadius: this.options.borderRadius,
});
break;
case u.LIGHTNING:
this.renderer=new r(this.element, {
hue: this.options.hue||t.toHue(this.options.color),
xOffset: this.options.xOffset,
speed: this.options.speed,
intensity: this.options.intensity,
size: this.options.size,
});
break;
case u.LASER_FLOW:
this.renderer=new l(this.element, {
color: this.options.color,
wispDensity: this.options.wispDensity,
mouseTiltStrength: this.options.mouseTiltStrength,
mouseSmoothTime: this.options.mouseSmoothTime,
horizontalBeamOffset: this.options.horizontalBeamOffset,
verticalBeamOffset: this.options.verticalBeamOffset,
flowSpeed: this.options.flowSpeed,
verticalSizing: this.options.verticalSizing,
horizontalSizing: this.options.horizontalSizing,
fogIntensity: this.options.fogIntensity,
fogScale: this.options.fogScale,
wispSpeed: this.options.wispSpeed,
wispIntensity: this.options.wispIntensity,
flowStrength: this.options.flowStrength,
decay: this.options.decay,
falloffStart: this.options.falloffStart,
fogFallSpeed: this.options.fogFallSpeed,
});
break;
case u.FLOATING_LINES:
this.renderer=new h(this.element, {
color1: this.options.color1||this.options.color,
color2: this.options.color2,
animationSpeed: this.options.animationSpeed||this.options.speed,
interactive: this.options.interactive,
enabledWaves: this.options.enabledWaves,
topLineCount: this.options.topLineCount,
middleLineCount: this.options.middleLineCount,
bottomLineCount: this.options.bottomLineCount,
topLineDistance: this.options.topLineDistance,
middleLineDistance: this.options.middleLineDistance,
bottomLineDistance: this.options.bottomLineDistance,
topWaveX: this.options.topWaveX,
topWaveY: this.options.topWaveY,
topWaveRotate: this.options.topWaveRotate,
middleWaveX: this.options.middleWaveX,
middleWaveY: this.options.middleWaveY,
middleWaveRotate: this.options.middleWaveRotate,
bottomWaveX: this.options.bottomWaveX,
bottomWaveY: this.options.bottomWaveY,
bottomWaveRotate: this.options.bottomWaveRotate,
bendRadius: this.options.bendRadius,
bendStrength: this.options.bendStrength,
parallax: this.options.parallax,
parallaxStrength: this.options.parallaxStrength,
linesGradient: this.options.linesGradient,
});
}}
_destroyRenderer(){
this.renderer&&(this.renderer.destroy(), (this.renderer=null));
}
setOptions(e){
const t=e.type&&e.type!==this.options.type;
(this.options={ ...this.options, ...e }),
this._applyDataAttributes(),
t
? this._createRenderer()
: this.renderer&&this.renderer.update(this.options);
}
setType(e){
this.setOptions({ type: e });
}
setColor(e){
(this.options.color=e),
this.renderer&&this.renderer.update({ color: e, hue: t.toHue(e) });
}
setSpeed(e){
(this.options.speed=e),
this.renderer&&this.renderer.update({ speed: e });
}
setIntensity(e){
(this.options.intensity=e),
this.renderer&&this.renderer.update({ intensity: e });
}
enable(){
(this.options.disabled = !1),
this.element.setAttribute("data-effect-disabled", "false"),
this.renderer||this._createRenderer();
}
disable(){
(this.options.disabled = !0),
this.element.setAttribute("data-effect-disabled", "true"),
this._destroyRenderer();
}
toggle(){
return (
this.options.disabled ? this.enable():this.disable(),
this.options.disabled
);
}
destroy(){
this._destroyRenderer(),
this.element.classList.remove("effect-card"),
this.element.removeAttribute("data-effect-type"),
this.element.removeAttribute("data-effect-disabled");
}}
class c {
constructor(){
this.cards=new Map();
}
init(e="[data-effect-card]", t={}){
const i=document.querySelectorAll(e),
n=[];
return (
i.forEach((e)=> {
if(this.cards.has(e)) return void n.push(this.cards.get(e));
const i=this._parseDataAttributes(e),
o={ ...t, ...i },
s=new f(e, o);
this.cards.set(e, s), n.push(s);
}),
n
);
}
_parseDataAttributes(e){
const t={},
i=e.getAttribute("data-effect-type");
i&&(t.type=i);
const n=e.getAttribute("data-effect-color");
n&&(t.color=n);
const o=e.getAttribute("data-effect-intensity");
o&&(t.intensity=parseFloat(o));
const s=e.getAttribute("data-effect-speed");
s&&(t.speed=parseFloat(s));
const a=e.getAttribute("data-effect-interactive");
a&&(t.interactive="true"===a);
const r=e.getAttribute("data-effect-disabled");
r&&(t.disabled="true"===r);
const l=e.getAttribute("data-effect-chaos");
l&&(t.chaos=parseFloat(l));
const h=e.getAttribute("data-effect-border-radius");
h&&(t.borderRadius=parseFloat(h));
const u=e.getAttribute("data-effect-hue");
u&&(t.hue=parseFloat(u));
const d=e.getAttribute("data-effect-x-offset");
d&&(t.xOffset=parseFloat(d));
const f=e.getAttribute("data-effect-size");
f&&(t.size=parseFloat(f));
const c=e.getAttribute("data-effect-wisp-density");
c&&(t.wispDensity=parseFloat(c));
const m=e.getAttribute("data-effect-mouse-tilt");
m&&(t.mouseTiltStrength=parseFloat(m));
const p=e.getAttribute("data-effect-horizontal-offset");
p&&(t.horizontalBeamOffset=parseFloat(p));
const v=e.getAttribute("data-effect-vertical-offset");
v&&(t.verticalBeamOffset=parseFloat(v));
const g=e.getAttribute("data-effect-flow-speed");
g&&(t.flowSpeed=parseFloat(g));
const _=e.getAttribute("data-effect-vertical-sizing");
_&&(t.verticalSizing=parseFloat(_));
const b=e.getAttribute("data-effect-horizontal-sizing");
b&&(t.horizontalSizing=parseFloat(b));
const E=e.getAttribute("data-effect-fog-intensity");
E&&(t.fogIntensity=parseFloat(E));
const x=e.getAttribute("data-effect-fog-scale");
x&&(t.fogScale=parseFloat(x));
const S=e.getAttribute("data-effect-wisp-speed");
S&&(t.wispSpeed=parseFloat(S));
const T=e.getAttribute("data-effect-wisp-intensity");
T&&(t.wispIntensity=parseFloat(T));
const F=e.getAttribute("data-effect-flow-strength");
F&&(t.flowStrength=parseFloat(F));
const y=e.getAttribute("data-effect-decay");
y&&(t.decay=parseFloat(y));
const A=e.getAttribute("data-effect-falloff-start");
A&&(t.falloffStart=parseFloat(A));
const w=e.getAttribute("data-effect-fog-fall-speed");
w&&(t.fogFallSpeed=parseFloat(w));
const L=e.getAttribute("data-effect-color1");
L&&(t.color1=L);
const R=e.getAttribute("data-effect-color2");
R&&(t.color2=R);
const M=e.getAttribute("data-effect-animation-speed");
M&&(t.animationSpeed=parseFloat(M));
const C=e.getAttribute("data-effect-enabled-waves");
C&&(t.enabledWaves=C.split(",").map((e)=> e.trim()));
const O=e.getAttribute("data-effect-line-count");
if(O){
const e=parseInt(O);
(t.topLineCount=e), (t.middleLineCount=e), (t.bottomLineCount=e);
}
const I=e.getAttribute("data-effect-bend-radius");
I&&(t.bendRadius=parseFloat(I));
const P=e.getAttribute("data-effect-bend-strength");
P&&(t.bendStrength=parseFloat(P));
const W=e.getAttribute("data-effect-lines-gradient");
return W&&(t.linesGradient=W.split(",").map((e)=> e.trim())), t;
}
get(e){
return this.cards.get(e);
}
has(e){
return this.cards.has(e);
}
remove(e){
const t=this.cards.get(e);
t&&(t.destroy(), this.cards.delete(e));
}
getAll(){
return Array.from(this.cards.values());
}
destroyAll(){
this.cards.forEach((e)=> e.destroy()), this.cards.clear();
}
setAllOptions(e){
this.cards.forEach((t)=> t.setOptions(e));
}
setAllType(e){
this.cards.forEach((t)=> t.setType(e));
}}
function m(){
const t=new c();
t.init(), (e.effectCardManager=t);
}
(e.EffectCard=f),
(e.EffectCardManager=c),
(e.EffectCardTypes=u),
(e.EffectCardColorUtils=t),
"loading"===document.readyState
? document.addEventListener("DOMContentLoaded", m)
: m();
})("undefined"!=typeof window ? window:this);