lensfx 0.1.1 → 0.1.3
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/CHANGELOG.md +69 -53
- package/README.md +39 -0
- package/dist/cdn/lensfx.js +1717 -0
- package/dist/cdn/lensfx.js.map +1 -0
- package/dist/cdn/lensfx.min.js +371 -0
- package/dist/cdn/lensfx.min.js.map +1 -0
- package/dist/index.d.mts +3 -368
- package/dist/index.d.ts +3 -368
- package/dist/index.js +413 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +413 -1
- package/dist/index.mjs.map +1 -1
- package/dist/lensfx.css +1 -1
- package/dist/vanilla.d.mts +493 -0
- package/dist/vanilla.d.ts +493 -0
- package/dist/vanilla.js +1694 -0
- package/dist/vanilla.js.map +1 -0
- package/dist/vanilla.mjs +1675 -0
- package/dist/vanilla.mjs.map +1 -0
- package/package.json +29 -4
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"use strict";var lensfx=(()=>{var Ve=Object.defineProperty;var xt=Object.getOwnPropertyDescriptor;var Et=Object.getOwnPropertyNames;var _t=Object.prototype.hasOwnProperty;var Tt=(o,n)=>{for(var e in n)Ve(o,e,{get:n[e],enumerable:!0})},Rt=(o,n,e,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of Et(n))!_t.call(o,r)&&r!==e&&Ve(o,r,{get:()=>n[r],enumerable:!(t=xt(n,r))||t.enumerable});return o};var vt=o=>Rt(Ve({},"__esModule",{value:!0}),o);var Dt={};Tt(Dt,{DEFAULT_LENS_PARAMS:()=>at,QRRefractionRenderer:()=>Ie,SLIDER_DARK_OVERRIDES:()=>ct,SLIDER_GLASS_DEFAULTS:()=>lt,SLIDER_LIGHT_OVERRIDES:()=>mt,SLIDER_SAFARI_OVERRIDES:()=>dt,SWITCH_DARK_OVERRIDES:()=>st,SWITCH_GLASS_DEFAULTS:()=>it,SWITCH_LIGHT_OVERRIDES:()=>ut,VideoRefractionRenderer:()=>Be,colorMatrixValues:()=>Ge,computeDomeConstants:()=>Pe,createDisplacementMapGeneratorSync:()=>Le,createLens:()=>ot,domeGradient:()=>Me,erf:()=>Ce,generateDisplacementMapAsync:()=>nt,getSvgMaskDataUri:()=>Fe});function Ce(o){return Math.tanh(1.7724538509*o)}function tt(o,n){let e=0;for(let t=0;t<=200;t++){let r=t/200*n,s=r/Math.sqrt(o*o-r*r);e+=t===0||t===200?.5*s:s}return e/200}function Pe(o,n,e){let t=Math.max(.01,Math.min(o,Math.min(n,e)-1)),r=(n*n+t*t)/(2*t),s=(e*e+t*t)/(2*t),d=tt(r,n),f=tt(s,e);return{Rx:r,Ry:s,scaleX:d>0?.5/d:1,scaleY:f>0?.5/f:1}}function Me(o,n,e){let t=Math.min(o,.999*n);return t/Math.sqrt(n*n-t*t)*e}function Ge(o,n){return`${o} 0 0 0 ${.5*(1-o)} 0 ${n} 0 0 ${.5*(1-n)} 0 0 1 0 0 0 0 0 1 0`}var rt=new Map;function Fe(o,n,e){let t=Math.max(1,Math.round(o)),r=Math.max(1,Math.round(n)),s=Math.max(0,Math.min(Math.round(e),Math.min(t,r)/2)),d=`${t}|${r}|${s}`,f=rt.get(d);if(f)return{uri:f,key:d};let M=Math.max(0,t-1),m=Math.max(0,r-1),l=Math.max(0,s-.5),W=`<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${t} ${r}' preserveAspectRatio='none'><rect x='0.5' y='0.5' width='${M}' height='${m}' rx='${l}' ry='${l}' fill='black'/></svg>`,a=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(W)}`;return rt.set(d,a),{uri:a,key:d}}function Le(o){let n=null,e=null,t=null,r=null,s=-1/0,d=-1/0,f=-1/0,M=null,m=0,l=!0;return{generate(W){n||(n=document.createElement("canvas"),n.width=o,n.height=o,e=n.getContext("2d"),t=e.createImageData(o,o));let{lensHalfWidth:a,lensHalfHeight:u,borderRadius:k,depth:$,sdfBoundary:ne,edgeFalloff:v,specularRotation:se=45,glowStrength:S=0,glowSpread:H=1,glowExponent:N=1.5,edgeStrength:Q=0,edgeWidth:oe=3,edgeExponent:me=1.5,domeDepth:j=0,splayAmount:Y=1}=W,p=t.data,O=o>>1,ue=Math.min(k,Math.min(a,u)),de=Math.max(0,a-$),B=Math.max(0,u-$),fe=Math.max(0,Math.min(k,Math.min(de,B))),i=$>0?1/($*Math.SQRT2):1e6,g=S>0||Q>0,E=se*Math.PI/180,_=Math.cos(E),y=Math.sin(E),L=(1-H)*Math.SQRT2,z=H*Math.SQRT2,D=z>.001?1/z:0,te=oe>0?1/oe:0,C=2*a/o,P=2*u/o,U=1/a,w=1/u,K=j>0,V=Y<1;if(K&&((!r||Math.abs(j-s)>.5||Math.abs(a-d)>1||Math.abs(u-f)>1)&&(r=Pe(j,a,u),s=j,d=a,f=u,l=!0),m!==O&&(M=new Float32Array(O),m=O,l=!0),l&&M&&r)){let h=r.Rx*r.Rx,b=.999*r.Rx;for(let T=0;T<O;T++){let q=-((T+.5)*C-a),pe=q<b?q:b;M[T]=pe/Math.sqrt(h-pe*pe)*r.scaleX}l=!1}let I=K?M:null,A=.5*Math.min(a,u),c=A>0?1/A:0,x=performance.now();for(let h=0;h<O;h++){let b=o-1-h,T=-((h+.5)*P-u),q=T-u+ue,pe=v?T-B+fe:0,De=K&&r?Me(T,r.Ry,r.scaleY):T*w>1?1:T*w,Ue=T*w>1?1:T*w,gt=V?Math.max(0,1-(u-T)*c):0;for(let he=0;he<O;he++){let We=o-1-he,be=-((he+.5)*C-a),Te=be-a+ue,Ne=Te>0?Te:0,Ye=q>0?q:0,Oe=Ne*Ne+Ye*Ye,Xe=(Oe>0?Math.sqrt(Oe):0)+(Te>q?Te>0?0:Te:q>0?0:q)-ue,Re=(h*o+he)*4,ve=(h*o+We)*4,Se=(b*o+he)*4,Ae=(b*o+We)*4;if(!ne||Xe<0){let ge=128,ze=128,qe=128,$e=128,xe=I?I[he]:be*U>1?1:be*U,Ee=De;if(V){let Z=1-Y,ee=gt*Z,ae=Math.max(0,1-(a-be)*c)*Z;if(ee>.001||ae>.001){let re=xe,le=Ee;xe=re*(1-ee),Ee=le*(1-ae);let we=Math.sqrt(re*re+le*le),ce=Math.sqrt(xe*xe+Ee*Ee);if(ce>.001){let ie=we/ce;xe*=ie,Ee*=ie}}}let ye=1;if(v){let Z=be-de+fe,ee=pe,ae=Z>0?Z:0,re=ee>0?ee:0,le=Math.sqrt(ae*ae+re*re)+(Z>ee?Z>0?0:Z:ee>0?0:ee)-fe;ye=.5*(1+Ce(le*i))}let Qe=.5*xe*ye,je=.5*Ee*ye,Ke=(.5+Qe)*255+.5|0,Je=(.5-Qe)*255+.5|0,Ze=(.5+je)*255+.5|0,et=(.5-je)*255+.5|0;if(g){let Z=(be*U>1?1:be*U)*_,ee=Ue*y,ae=Z+ee,re=Z-ee,le=ae<0?-ae:ae,we=re<0?-re:re,ce=0;Q>0&&(ce=Xe<0?1+Xe*te:0,ce<0&&(ce=0));let ie=0,_e=0;if(S>0){let ke=(le-L)*D;ie+=S*Math.pow(ke<0?0:ke>1?1:ke,N)*ye;let He=(we-L)*D;_e+=S*Math.pow(He<0?0:He>1?1:He,N)*ye}Q>0&&(ie+=Q*ce*Math.pow(le,me),_e+=Q*ce*Math.pow(we,me)),ie>1&&(ie=1),_e>1&&(_e=1),ge=127*ie+128+.5|0,$e=127*ie+128+.5|0,ze=127*_e+128+.5|0,qe=127*_e+128+.5|0}p[Re]=Ke,p[Re+1]=Ze,p[Re+2]=ge,p[Re+3]=255,p[ve]=Je,p[ve+1]=Ze,p[ve+2]=ze,p[ve+3]=255,p[Se]=Ke,p[Se+1]=et,p[Se+2]=qe,p[Se+3]=255,p[Ae]=Je,p[Ae+1]=et,p[Ae+2]=$e,p[Ae+3]=255}else for(let ge of[Re,ve,Se,Ae])p[ge]=128,p[ge+1]=128,p[ge+2]=128,p[ge+3]=255}}let X=performance.now()-x;e.putImageData(t,0,0);let G=performance.now(),F=n.toDataURL(),J=performance.now()-G;return{dataUrl:F,loopMs:X,encodeMs:J}},dispose(){n&&(n.width=0,n.height=0,n=null),e=null,t=null,r=null,s=-1/0,d=-1/0,f=-1/0,l=!0}}}async function nt(o,n){let{canvasSize:e,lensHalfWidth:t,lensHalfHeight:r,borderRadius:s,depth:d,sdfBoundary:f,edgeFalloff:M,specularRotation:m=45,glowStrength:l=0,glowSpread:W=1,glowExponent:a=1.5,edgeStrength:u=0,edgeWidth:k=3,edgeExponent:$=1.5,domeDepth:ne=0,splayAmount:v=1}=n;o.width=e,o.height=e;let se=o.getContext("2d");if(!se)return null;let S=se.createImageData(e,e),H=Math.min(s,Math.min(t,r)),N=Math.max(0,t-d),Q=Math.max(0,r-d),oe=Math.max(0,Math.min(s,Math.min(N,Q))),me=d>0?1/(d*Math.SQRT2):1e6,j=l>0||u>0,Y=m*Math.PI/180,p=Math.cos(Y),O=Math.sin(Y),ue=(1-W)*Math.SQRT2,de=W*Math.SQRT2,B=ne>0?Pe(ne,t,r):null,fe=v<1,i=.5*Math.min(t,r),g=i>0?1/i:0;for(let _=0;_<e;_+=64){let y=Math.min(_+64,e);for(let L=_;L<y;L++)for(let z=0;z<e;z++){let D=(L*e+z)*4,te=(z+.5)/e*(2*t)-t,C=(L+.5)/e*(2*r)-r,P=Math.abs(te),U=Math.abs(C),w=P-t+H,K=U-r+H,V=Math.max(w,0),I=Math.max(K,0),A=V*V+I*I,c=(A>0?Math.sqrt(A):0)+Math.min(Math.max(w,K),0)-H;if(!f||c<0){let x,X;B?(x=Math.sign(te)*Me(P,B.Rx,B.scaleX),X=Math.sign(C)*Me(U,B.Ry,B.scaleY)):(x=Math.max(-1,Math.min(1,te/t)),X=Math.max(-1,Math.min(1,C/r)));let G=x,F=X;if(fe){let h=Math.max(0,1-(r-U)*g)*(1-v),b=Math.max(0,1-(t-P)*g)*(1-v);if(h>.001||b>.001){let T=G,q=F;G=T*(1-h),F=q*(1-b);let pe=Math.sqrt(T*T+q*q),De=Math.sqrt(G*G+F*F);if(De>.001){let Ue=pe/De;G*=Ue,F*=Ue}}}let J=1;if(M){let h=P-N+oe,b=U-Q+oe,T=Math.sqrt(Math.max(h,0)**2+Math.max(b,0)**2)+Math.min(Math.max(h,b),0)-oe;J=.5*(1+Ce(T*me))}if(S.data[D]=Math.round((.5-.5*G*J)*255),S.data[D+1]=Math.round((.5-.5*F*J)*255),j){let h=Math.abs(Math.max(-1,Math.min(1,te/t))*p+Math.max(-1,Math.min(1,C/r))*O),b=0;if(l>0){let T=de>.001?Math.min(1,Math.max(0,h-ue)/de):0;b+=l*Math.pow(T,a)*J}if(u>0){let T=c<0?Math.max(0,1+c/k):0;b+=u*T*Math.pow(h,$)}b=Math.min(1,b),S.data[D+2]=Math.round(127*b+128)}else S.data[D+2]=128}else S.data[D]=128,S.data[D+1]=128,S.data[D+2]=128;S.data[D+3]=255}_+64<e&&await new Promise(L=>setTimeout(L,0))}se.putImageData(S,0,0);let E=await new Promise(_=>o.toBlob(_,"image/png"));return E?URL.createObjectURL(E):null}var R="http://www.w3.org/2000/svg",St=0;function ot(o,n={}){if(typeof document>"u")throw new Error("[lensfx] createLens can only be called in a browser environment.");let e=typeof o=="string"?document.querySelector(o):o;if(!e)throw new Error(`[lensfx] Target element "${o}" was not found.`);let t=e,r={...n},s=t;if(r.refractionTarget){let i=typeof r.refractionTarget=="string"?t.querySelector(r.refractionTarget)||document.querySelector(r.refractionTarget):r.refractionTarget;i&&(s=i)}let d=window.getComputedStyle(t),f=t.style.position;d.position==="static"&&(t.style.position="relative");let m=`${`lensfx-${++St}-${Math.random().toString(36).substring(2,7)}`}-filter`,l=document.createElementNS(R,"svg");l.setAttribute("class","lensfx-svg-root"),l.setAttribute("aria-hidden","true"),l.style.cssText="position:absolute;width:0;height:0;overflow:hidden;pointer-events:none;left:0;top:0;";let W=document.createElementNS(R,"defs"),a=document.createElementNS(R,"filter");a.id=m,a.setAttribute("filterUnits","objectBoundingBox"),a.setAttribute("primitiveUnits","objectBoundingBox"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("x","0"),a.setAttribute("y","0"),a.setAttribute("width","1"),a.setAttribute("height","1"),W.appendChild(a),l.appendChild(W),t.appendChild(l);let u=document.createElement("div");u.className="lensfx-lens-overlay",u.style.cssText="position:absolute;top:0;left:0;pointer-events:none;box-sizing:border-box;will-change:transform;",t.appendChild(u);let k=r.displacementMapUrl||"",$=r.mapSize||256,ne=Le($),v=null,se=null,S=!1,H=r.x??.5,N=r.y??.5;function Q(){let i=r.width??r.lensW??160,g=r.height??r.lensH??100,E=r.radius??r.borderRadius??Math.min(i,g)/4;return{width:i,height:g,radius:E}}function oe(){if(S)return;if(r.displacementMapUrl){k=r.displacementMapUrl,v&&v.setAttribute("href",k),r.onMapChange?.(k);return}let{width:i,height:g,radius:E}=Q(),_=r.mapSize||256;_!==$&&(ne.dispose(),$=_,ne=Le($));let y=r.depth??2;k=ne.generate({lensHalfWidth:i/2,lensHalfHeight:g/2,borderRadius:E,depth:y,sdfBoundary:r.sdfBoundary??!0,edgeFalloff:r.edgeFalloff??!0,specularRotation:r.specularRotation??45,glowStrength:r.glowStrength??.3,glowSpread:r.glowSpread??1,glowExponent:r.glowExponent??1.5,edgeStrength:r.edgeStrength??.4,edgeWidth:r.edgeWidth??3,edgeExponent:1.5,domeDepth:r.domeDepth??6,splayAmount:r.splayAmount??.8}).dataUrl,v&&v.setAttribute("href",k),r.onMapChange?.(k)}function me(){for(;a.firstChild;)a.removeChild(a.firstChild);let i=r.depth??2,g=r.chroma??r.chromaAmount??.6,E=r.scaleX??.25,_=r.scaleY??.25,y=Math.max(E,_),L=y>0?E/y:0,z=y>0?_/y:0,D=L!==1||z!==1,te=Ge(L,z),C=document.createElementNS(R,"feFlood");C.setAttribute("flood-color","rgb(128,128,128)"),C.setAttribute("flood-opacity","1"),C.setAttribute("result","mapBg"),a.appendChild(C),v=document.createElementNS(R,"feImage"),v.setAttribute("href",k),v.setAttribute("preserveAspectRatio","none"),v.setAttribute("result","rawMap"),a.appendChild(v);let P=document.createElementNS(R,"feComposite");if(P.setAttribute("in","rawMap"),P.setAttribute("in2","mapBg"),P.setAttribute("operator","over"),P.setAttribute("result","map"),a.appendChild(P),D){let c=document.createElementNS(R,"feColorMatrix");c.setAttribute("in","map"),c.setAttribute("type","matrix"),c.setAttribute("values",te),c.setAttribute("result","scaledMap"),a.appendChild(c)}let U=D?"scaledMap":"map",w="SourceGraphic";if(r.blur&&r.blur>0){let c=document.createElementNS(R,"feGaussianBlur");c.setAttribute("in","SourceGraphic");let x=t.getBoundingClientRect(),X=x.width>0?r.blur/x.width:.01,G=x.height>0?r.blur/x.height:.01;c.setAttribute("stdDeviation",`${X} ${G}`),c.setAttribute("result","blurred"),a.appendChild(c),w="blurred"}if(g>0){let c=document.createElementNS(R,"feDisplacementMap");c.setAttribute("in",w),c.setAttribute("in2",U),c.setAttribute("scale",String(y*(1+.2*g))),c.setAttribute("xChannelSelector","R"),c.setAttribute("yChannelSelector","G"),a.appendChild(c);let x=document.createElementNS(R,"feColorMatrix");x.setAttribute("type","matrix"),x.setAttribute("values","1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"),x.setAttribute("result","dispR"),a.appendChild(x);let X=document.createElementNS(R,"feDisplacementMap");X.setAttribute("in",w),X.setAttribute("in2",U),X.setAttribute("scale",String(y*(1+.1*g))),X.setAttribute("xChannelSelector","R"),X.setAttribute("yChannelSelector","G"),a.appendChild(X);let G=document.createElementNS(R,"feColorMatrix");G.setAttribute("type","matrix"),G.setAttribute("values","0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0"),G.setAttribute("result","dispG"),a.appendChild(G);let F=document.createElementNS(R,"feDisplacementMap");F.setAttribute("in",w),F.setAttribute("in2",U),F.setAttribute("scale",String(y)),F.setAttribute("xChannelSelector","R"),F.setAttribute("yChannelSelector","G"),a.appendChild(F);let J=document.createElementNS(R,"feColorMatrix");J.setAttribute("type","matrix"),J.setAttribute("values","0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0"),J.setAttribute("result","dispB"),a.appendChild(J);let h=document.createElementNS(R,"feComposite");h.setAttribute("in","dispR"),h.setAttribute("in2","dispG"),h.setAttribute("operator","arithmetic"),h.setAttribute("k1","0"),h.setAttribute("k2","1"),h.setAttribute("k3","1"),h.setAttribute("k4","0"),a.appendChild(h);let b=document.createElementNS(R,"feComposite");b.setAttribute("in2","dispB"),b.setAttribute("operator","arithmetic"),b.setAttribute("k1","0"),b.setAttribute("k2","1"),b.setAttribute("k3","1"),b.setAttribute("k4","0"),b.setAttribute("result","lensResult"),a.appendChild(b)}else{let c=document.createElementNS(R,"feDisplacementMap");c.setAttribute("in",w),c.setAttribute("in2",U),c.setAttribute("scale",String(y)),c.setAttribute("xChannelSelector","R"),c.setAttribute("yChannelSelector","G"),c.setAttribute("result","lensResult"),a.appendChild(c)}let K=r.specularStrength??1;if(K>0){let c=document.createElementNS(R,"feColorMatrix");c.setAttribute("in","map"),c.setAttribute("type","matrix"),c.setAttribute("values","0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 -0.50196"),c.setAttribute("result","specMask"),a.appendChild(c);let x=document.createElementNS(R,"feComposite");x.setAttribute("in","specMask"),x.setAttribute("in2","lensResult"),x.setAttribute("operator","arithmetic"),x.setAttribute("k1","0"),x.setAttribute("k2",String(K)),x.setAttribute("k3","1"),x.setAttribute("k4","0"),x.setAttribute("result","lensResult"),a.appendChild(x)}let V=document.createElementNS(R,"feFlood");V.setAttribute("flood-color","black"),V.setAttribute("flood-opacity","1"),V.setAttribute("result","lensMask"),a.appendChild(V);let I=document.createElementNS(R,"feComposite");I.setAttribute("in","SourceGraphic"),I.setAttribute("in2","lensMask"),I.setAttribute("operator","out"),I.setAttribute("result","holedSG"),a.appendChild(I);let A=document.createElementNS(R,"feComposite");A.setAttribute("in","lensResult"),A.setAttribute("in2","holedSG"),A.setAttribute("operator","over"),a.appendChild(A)}function j(){if(S)return;let i=t.getBoundingClientRect(),g=i.width||t.clientWidth||300,E=i.height||t.clientHeight||200,{width:_,height:y,radius:L}=Q(),z=H<=1&&H>=0?H*g:H,D=N<=1&&N>=0?N*E:te(N,E);function te(A,c){return A<=1&&A>=0?A*c:A}let C=z-_/2,P=D-y/2;v&&g>0&&E>0&&(v.setAttribute("x",String(C/g)),v.setAttribute("y",String(P/E)),v.setAttribute("width",String(_/g)),v.setAttribute("height",String(y/E))),u.style.width=`${_}px`,u.style.height=`${y}px`,u.style.borderRadius=`${L}px`,u.style.transform=`translate3d(${C}px, ${P}px, 0)`,r.shadow===!1?u.style.boxShadow="none":typeof r.shadow=="string"?u.style.boxShadow=r.shadow:u.style.boxShadow="0 8px 32px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.12), inset 0 1px 1px rgba(255, 255, 255, 0.35), inset 0 -1px 1px rgba(0, 0, 0, 0.15)",r.border===!1?u.style.border="none":typeof r.border=="string"?u.style.border=r.border:u.style.border="1px solid rgba(255, 255, 255, 0.2)";let U=r.tintColor??"rgba(255, 255, 255, 0.05)";u.style.background=U;let w=r.tintBlur??0;if(w>0){let A=`blur(${w}px)`;u.style.backdropFilter=A,u.style.setProperty("-webkit-backdrop-filter",A)}else u.style.backdropFilter="none",u.style.setProperty("-webkit-backdrop-filter","none");let{uri:K,key:V}=Fe(_,y,L);if(se!==V){let A=`url("${K}")`;u.style.maskImage=A,u.style.setProperty("-webkit-mask-image",A),u.style.maskSize="100% 100%",u.style.setProperty("-webkit-mask-size","100% 100%"),se=V}let I=`url("#${m}")`;s.style.filter!==I&&(s.style.filter=I)}let Y=!1,p=i=>{if(!r.interactive||S)return;let g=t.getBoundingClientRect(),E=i.clientX-g.left,_=i.clientY-g.top;ue(E,_)};function O(i){r.interactive=i,i&&!Y?(t.addEventListener("pointermove",p),Y=!0):!i&&Y&&(t.removeEventListener("pointermove",p),Y=!1)}function ue(i,g){H=i,N=g,r.onPositionChange?.(i,g),j()}function de(i){if(S)return;let g={...r};r={...r,...i},i.x!==void 0&&(H=i.x),i.y!==void 0&&(N=i.y),i.interactive!==void 0&&O(i.interactive);let E=i.width!==void 0||i.lensW!==void 0||i.height!==void 0||i.lensH!==void 0||i.radius!==void 0||i.borderRadius!==void 0||i.depth!==void 0||i.domeDepth!==void 0||i.specularRotation!==void 0||i.glowStrength!==void 0||i.glowSpread!==void 0||i.edgeStrength!==void 0||i.edgeWidth!==void 0||i.splayAmount!==void 0||i.displacementMapUrl!==void 0||i.mapSize!==void 0;E&&oe(),(i.chroma!==void 0||i.chromaAmount!==void 0||i.scaleX!==void 0||i.scaleY!==void 0||i.specularStrength!==void 0||i.blur!==void 0||E)&&me(),j()}let B=null;typeof ResizeObserver<"u"&&(B=new ResizeObserver(()=>{j()}),B.observe(t)),oe(),me(),j(),r.interactive&&O(!0);function fe(){S||(S=!0,Y&&(t.removeEventListener("pointermove",p),Y=!1),B&&(B.disconnect(),B=null),s.style.filter.includes(m)&&(s.style.filter=""),t.style.position==="relative"&&f===""&&(t.style.position=""),l.parentNode&&l.parentNode.removeChild(l),u.parentNode&&u.parentNode.removeChild(u),ne.dispose())}return{el:t,targetEl:s,svgEl:l,filterEl:a,overlayEl:u,get options(){return r},get mapDataUrl(){return k},setPosition:ue,update:de,setInteractive:O,destroy:fe}}var at={lensW:90,lensH:60,depth:0,chromaAmount:0,scaleX:0,scaleY:0,mapSize:256,borderRadius:0,blurAmount:0,sdfBoundary:!1,edgeFalloff:!1,brightness:0,specularStrength:0,specularRotation:0,glowStrength:0,glowSpread:1,glowExponent:1.5,tint:0,edgeStrength:0,edgeWidth:3,edgeExponent:1.5,specularDark:!1,domeDepth:0,splayAmount:0};var it={lensW:90,lensH:60,borderRadius:30,mapSize:256,depth:2,chromaAmount:1,scaleX:.25,scaleY:.25,sdfBoundary:!0,edgeFalloff:!0,domeDepth:6,splayAmount:.4,blurAmount:0,brightness:.06,specularStrength:1,specularRotation:45,specularDark:!1,tint:0,glowStrength:0,glowSpread:.5,glowExponent:1.5,edgeStrength:0,edgeWidth:2,edgeExponent:1.5,edgeShadow:"0 2px 6px rgba(0, 0, 0, 0.16)",edgeInsetShadow:"0 -4px 10px rgba(0, 0, 0, 0.12)"},st={brightness:.12,glowStrength:.4,edgeStrength:.5},ut={brightness:-.02,specularRotation:30,specularStrength:1.5,glowStrength:.4,glowSpread:.5,glowExponent:2,edgeStrength:1,edgeWidth:1.5,edgeExponent:1},lt={lensW:90,lensH:60,borderRadius:30,mapSize:256,depth:2,chromaAmount:.65,scaleX:.06,scaleY:.06,sdfBoundary:!0,edgeFalloff:!0,domeDepth:5,splayAmount:.5,blurAmount:0,brightness:.06,specularStrength:1.5,specularRotation:45,specularDark:!1,tint:0,glowStrength:.4,glowSpread:.5,glowExponent:1.5,edgeStrength:0,edgeWidth:3,edgeExponent:1.5,edgeShadow:"0 2px 6px rgba(0, 0, 0, 0.16)",edgeInsetShadow:"0 -4px 10px rgba(0, 0, 0, 0.12)",restEdgeShadow:"0 1.333px 5.333px var(--lensfx-shadow-strong, rgba(0,0,0,0.3))"},ct={scaleX:.133,scaleY:.135,brightness:.12,specularRotation:45,glowExponent:1.5,edgeStrength:.5,edgeWidth:1,edgeExponent:1.5},mt={scaleX:.1,scaleY:.1,brightness:-.02,specularRotation:30,glowExponent:2,edgeStrength:1,edgeWidth:1,edgeExponent:1},dt={scaleY:.25};var ft=`
|
|
2
|
+
attribute vec2 a_pos;
|
|
3
|
+
varying vec2 v_uv;
|
|
4
|
+
void main() {
|
|
5
|
+
// Flip Y so UV (0,0) = top-left, matching HTML/CSS coordinates.
|
|
6
|
+
v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
|
|
7
|
+
gl_Position = vec4(a_pos, 0.0, 1.0);
|
|
8
|
+
}
|
|
9
|
+
`,At=`
|
|
10
|
+
precision highp float;
|
|
11
|
+
uniform sampler2D u_source;
|
|
12
|
+
uniform vec2 u_dir;
|
|
13
|
+
varying vec2 v_uv;
|
|
14
|
+
|
|
15
|
+
void main() {
|
|
16
|
+
vec4 c = texture2D(u_source, v_uv) * 0.2042;
|
|
17
|
+
c += (texture2D(u_source, v_uv + 1.0 * u_dir) + texture2D(u_source, v_uv - 1.0 * u_dir)) * 0.1801;
|
|
18
|
+
c += (texture2D(u_source, v_uv + 2.0 * u_dir) + texture2D(u_source, v_uv - 2.0 * u_dir)) * 0.1240;
|
|
19
|
+
c += (texture2D(u_source, v_uv + 3.0 * u_dir) + texture2D(u_source, v_uv - 3.0 * u_dir)) * 0.0663;
|
|
20
|
+
c += (texture2D(u_source, v_uv + 4.0 * u_dir) + texture2D(u_source, v_uv - 4.0 * u_dir)) * 0.0276;
|
|
21
|
+
gl_FragColor = c;
|
|
22
|
+
}
|
|
23
|
+
`,yt=`
|
|
24
|
+
#extension GL_OES_standard_derivatives : enable
|
|
25
|
+
precision highp float;
|
|
26
|
+
|
|
27
|
+
uniform sampler2D u_video;
|
|
28
|
+
uniform sampler2D u_map;
|
|
29
|
+
uniform sampler2D u_blurred;
|
|
30
|
+
uniform float u_baseScale[3];
|
|
31
|
+
uniform float u_ratioX[3];
|
|
32
|
+
uniform float u_ratioY[3];
|
|
33
|
+
uniform float u_chromaAmount;
|
|
34
|
+
uniform float u_specStrength;
|
|
35
|
+
uniform float u_adaptStrength;
|
|
36
|
+
uniform float u_specLumaLow;
|
|
37
|
+
uniform float u_specLumaHigh;
|
|
38
|
+
uniform float u_hasBlur;
|
|
39
|
+
uniform vec4 u_bbox; // (x, y, w, h) normalised, y=0 at top
|
|
40
|
+
uniform vec3 u_circles[3]; // (cx, cy, radius) in bbox pixel space
|
|
41
|
+
uniform float u_scale[3]; // per-circle geometric press scale (1 = unscaled)
|
|
42
|
+
uniform vec4 u_bar; // (cx, cy, w, h) in bbox pixel space; w<=0 means inactive
|
|
43
|
+
uniform float u_barRadius; // corner radius for the rounded-rect bar lens
|
|
44
|
+
uniform float u_barBaseScale;
|
|
45
|
+
uniform float u_barRatioX;
|
|
46
|
+
uniform float u_barRatioY;
|
|
47
|
+
uniform vec2 u_bboxSize; // bbox (width, height) in pixels
|
|
48
|
+
|
|
49
|
+
varying vec2 v_uv;
|
|
50
|
+
|
|
51
|
+
void main() {
|
|
52
|
+
vec2 uv = v_uv;
|
|
53
|
+
vec2 bMin = u_bbox.xy;
|
|
54
|
+
vec2 bSize = u_bbox.zw;
|
|
55
|
+
vec2 bMax = bMin + bSize;
|
|
56
|
+
|
|
57
|
+
// Outside bounding box -> pass-through video
|
|
58
|
+
if (uv.x < bMin.x || uv.x > bMax.x || uv.y < bMin.y || uv.y > bMax.y) {
|
|
59
|
+
gl_FragColor = texture2D(u_video, uv);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Map fragment UV -> displacement texture UV
|
|
64
|
+
vec2 mUV = (uv - bMin) / bSize;
|
|
65
|
+
|
|
66
|
+
// Analytical SDF mask (pixel-perfect at any resolution). Tracks the
|
|
67
|
+
// dominant region so per-region scale/ratio can be picked up via the
|
|
68
|
+
// loop-constant index (safe in WebGL 1). After the circle loop we test the
|
|
69
|
+
// rounded-rect "bar" region (when active) and take whichever has the
|
|
70
|
+
// larger mask value. domCenter/domScale track the dominant lens so the
|
|
71
|
+
// displacement map is sampled in its (press-)scaled space below.
|
|
72
|
+
vec2 pxPos = mUV * u_bboxSize;
|
|
73
|
+
float mask = 0.0;
|
|
74
|
+
float baseScale = 0.0;
|
|
75
|
+
float ratioX = 0.0;
|
|
76
|
+
float ratioY = 0.0;
|
|
77
|
+
|
|
78
|
+
// Map-sample scale assignment, tracked SEPARATELY from the tight SDF mask: a
|
|
79
|
+
// pixel adopts a circle's press scale across the union of its original and
|
|
80
|
+
// scaled radius (R * max(1, s)). That way the annulus a shrunk lens vacates
|
|
81
|
+
// samples empty space instead of leaving the original rim stuck behind.
|
|
82
|
+
// domScale = 1 (bar + background) -> identity sample.
|
|
83
|
+
vec2 domCenter = pxPos;
|
|
84
|
+
float domScale = 1.0;
|
|
85
|
+
float domDist = 1.0; // nearest normalised assignment distance (<1 = inside)
|
|
86
|
+
|
|
87
|
+
for (int i = 0; i < 3; i++) {
|
|
88
|
+
if (u_circles[i].z < 0.1) continue; // skip inactive circles
|
|
89
|
+
float s = max(u_scale[i], 0.001);
|
|
90
|
+
float R = u_circles[i].z;
|
|
91
|
+
float rho = length(pxPos - u_circles[i].xy);
|
|
92
|
+
|
|
93
|
+
// Visible lens SDF at the scaled radius -> blur / specular gating.
|
|
94
|
+
float dist = rho - R * s;
|
|
95
|
+
float aa = fwidth(dist);
|
|
96
|
+
float m = 1.0 - smoothstep(-aa, aa, dist);
|
|
97
|
+
if (m > mask) {
|
|
98
|
+
mask = m;
|
|
99
|
+
baseScale = u_baseScale[i];
|
|
100
|
+
ratioX = u_ratioX[i];
|
|
101
|
+
ratioY = u_ratioY[i];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Scale assignment over max(original, scaled) radius, PLUS a small FIXED
|
|
105
|
+
// pixel margin so the region boundary clears the map's hard content edge at
|
|
106
|
+
// r = R. A *fractional* margin scales with R, so a big lens (play) would
|
|
107
|
+
// swallow its neighbours' regions and drag their rings in. 4px clears the
|
|
108
|
+
// edge's AA band without ever reaching the gap to the next control.
|
|
109
|
+
float nd = rho / (R * max(1.0, s) + 4.0);
|
|
110
|
+
if (nd < domDist) {
|
|
111
|
+
domDist = nd;
|
|
112
|
+
domCenter = u_circles[i].xy;
|
|
113
|
+
domScale = s;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Bar (rounded-rect) SDF - only when u_bar.zw > 0. The bar never scales, so
|
|
118
|
+
// it keeps the identity map sample (domScale stays 1 for bar + background).
|
|
119
|
+
if (u_bar.z > 0.1 && u_bar.w > 0.1) {
|
|
120
|
+
vec2 q = abs(pxPos - u_bar.xy) - u_bar.zw * 0.5 + vec2(u_barRadius);
|
|
121
|
+
float barDist =
|
|
122
|
+
length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - u_barRadius;
|
|
123
|
+
float aaBar = fwidth(barDist);
|
|
124
|
+
float mBar = 1.0 - smoothstep(-aaBar, aaBar, barDist);
|
|
125
|
+
if (mBar > mask) {
|
|
126
|
+
mask = mBar;
|
|
127
|
+
baseScale = u_barBaseScale;
|
|
128
|
+
ratioX = u_barRatioX;
|
|
129
|
+
ratioY = u_barRatioY;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Sample the displacement map at the dominant lens's scaled coordinate, so a
|
|
134
|
+
// per-lens press scale shrinks the baked pattern around its center in
|
|
135
|
+
// lockstep with the SDF radius above. domScale = 1 -> identity (unscaled).
|
|
136
|
+
vec2 scaledPx = domCenter + (pxPos - domCenter) / domScale;
|
|
137
|
+
vec4 d = texture2D(u_map, scaledPx / u_bboxSize);
|
|
138
|
+
|
|
139
|
+
// mapMatrix (feColorMatrix equivalent)
|
|
140
|
+
float sr = d.r * ratioX + 0.5 * (1.0 - ratioX);
|
|
141
|
+
float sg = d.g * ratioY + 0.5 * (1.0 - ratioY);
|
|
142
|
+
|
|
143
|
+
// Displacement offset in full-video UV space
|
|
144
|
+
vec2 off = vec2(sr - 0.5, sg - 0.5) * baseScale;
|
|
145
|
+
|
|
146
|
+
// Choose source: blurred or raw video
|
|
147
|
+
// Inside lens -> blurred (if blur active), outside lens -> raw
|
|
148
|
+
// Blend by mask so the transition at edges is clean
|
|
149
|
+
vec4 color;
|
|
150
|
+
if (u_chromaAmount > 0.001) {
|
|
151
|
+
float sR = 1.0 + u_chromaAmount * 0.2;
|
|
152
|
+
float sG = 1.0 + u_chromaAmount * 0.1;
|
|
153
|
+
if (u_hasBlur > 0.5) {
|
|
154
|
+
color.r = mix(
|
|
155
|
+
texture2D(u_video, clamp(uv + off * sR, 0.0, 1.0)).r,
|
|
156
|
+
texture2D(u_blurred, clamp(uv + off * sR, 0.0, 1.0)).r,
|
|
157
|
+
mask
|
|
158
|
+
);
|
|
159
|
+
color.g = mix(
|
|
160
|
+
texture2D(u_video, clamp(uv + off * sG, 0.0, 1.0)).g,
|
|
161
|
+
texture2D(u_blurred, clamp(uv + off * sG, 0.0, 1.0)).g,
|
|
162
|
+
mask
|
|
163
|
+
);
|
|
164
|
+
color.b = mix(
|
|
165
|
+
texture2D(u_video, clamp(uv + off, 0.0, 1.0)).b,
|
|
166
|
+
texture2D(u_blurred, clamp(uv + off, 0.0, 1.0)).b,
|
|
167
|
+
mask
|
|
168
|
+
);
|
|
169
|
+
} else {
|
|
170
|
+
color.r = texture2D(u_video, clamp(uv + off * sR, 0.0, 1.0)).r;
|
|
171
|
+
color.g = texture2D(u_video, clamp(uv + off * sG, 0.0, 1.0)).g;
|
|
172
|
+
color.b = texture2D(u_video, clamp(uv + off, 0.0, 1.0)).b;
|
|
173
|
+
}
|
|
174
|
+
color.a = 1.0;
|
|
175
|
+
} else {
|
|
176
|
+
vec2 duv = clamp(uv + off, 0.0, 1.0);
|
|
177
|
+
if (u_hasBlur > 0.5) {
|
|
178
|
+
color = mix(texture2D(u_video, duv), texture2D(u_blurred, duv), mask);
|
|
179
|
+
} else {
|
|
180
|
+
color = texture2D(u_video, duv);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Adaptive specular + brightness (Apple-style vibrancy)
|
|
185
|
+
// Compute perceptual luminance of the displaced video sample
|
|
186
|
+
float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));
|
|
187
|
+
|
|
188
|
+
// Specular: blend between additive (dark bg) and multiplicative (bright bg)
|
|
189
|
+
float spec = d.b - 0.502;
|
|
190
|
+
float lumaLo = min(u_specLumaLow, u_specLumaHigh);
|
|
191
|
+
float lumaHi = max(u_specLumaLow, u_specLumaHigh);
|
|
192
|
+
float darkBlend = smoothstep(lumaLo, lumaHi, luma);
|
|
193
|
+
vec3 specAdd = color.rgb + spec * u_specStrength;
|
|
194
|
+
vec3 specMul = color.rgb * (1.0 - spec * u_specStrength);
|
|
195
|
+
color.rgb = mix(specAdd, specMul, darkBlend);
|
|
196
|
+
color.rgb = max(color.rgb, vec3(0.0));
|
|
197
|
+
|
|
198
|
+
// Brightness: pull toward mid-gray - darkens bright areas, brightens dark
|
|
199
|
+
float correction = (0.5 - luma) * u_adaptStrength * mask;
|
|
200
|
+
color.rgb += correction;
|
|
201
|
+
|
|
202
|
+
gl_FragColor = color;
|
|
203
|
+
}
|
|
204
|
+
`;function pt(o,n,e){let t=o.createShader(n);return t?(o.shaderSource(t,e),o.compileShader(t),o.getShaderParameter(t,o.COMPILE_STATUS)?t:(console.error("Shader compile error:",o.getShaderInfoLog(t)),o.deleteShader(t),null)):null}function ht(o,n,e){let t=pt(o,o.VERTEX_SHADER,n),r=pt(o,o.FRAGMENT_SHADER,e);if(!t||!r)return null;let s=o.createProgram();return s?(o.attachShader(s,t),o.attachShader(s,r),o.linkProgram(s),o.detachShader(s,t),o.detachShader(s,r),o.deleteShader(t),o.deleteShader(r),o.getProgramParameter(s,o.LINK_STATUS)?s:(console.error("Program link error:",o.getProgramInfoLog(s)),o.deleteProgram(s),null)):null}var Be=class{constructor(n){this.blurFboA=null;this.blurTexA=null;this.blurFboB=null;this.blurTexB=null;this.fboWidth=0;this.fboHeight=0;let e=n.getContext("webgl",{alpha:!1,antialias:!1,premultipliedAlpha:!1});if(!e)throw new Error("WebGL not supported");this.gl=e,e.getExtension("OES_standard_derivatives");let t=new Float32Array([-1,-1,1,-1,-1,1,1,1]);this.quadBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.quadBuffer),e.bufferData(e.ARRAY_BUFFER,t,e.STATIC_DRAW),this.blurProgram=ht(e,ft,At),this.refractionProgram=ht(e,ft,yt),this.videoTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.videoTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),this.mapTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.mapTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR)}setDisplacementMap(n){let e=this.gl;e.bindTexture(e.TEXTURE_2D,this.mapTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,n)}initBlurFBO(n,e){let t=this.gl,r=n>>1,s=e>>1;if(this.fboWidth===r&&this.fboHeight===s)return;this.fboWidth=r,this.fboHeight=s;let d=()=>{let m=t.createTexture();t.bindTexture(t.TEXTURE_2D,m),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,r,s,0,t.RGBA,t.UNSIGNED_BYTE,null);let l=t.createFramebuffer();return t.bindFramebuffer(t.FRAMEBUFFER,l),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,m,0),{fbo:l,tex:m}},f=d();this.blurFboA=f.fbo,this.blurTexA=f.tex;let M=d();this.blurFboB=M.fbo,this.blurTexB=M.tex,t.bindFramebuffer(t.FRAMEBUFFER,null)}render(n,e){let t=this.gl,r=t.canvas.width,s=t.canvas.height;if(t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.videoTexture),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,n),e.hasBlur){this.initBlurFBO(r,s),t.bindFramebuffer(t.FRAMEBUFFER,this.blurFboA),t.viewport(0,0,this.fboWidth,this.fboHeight),t.useProgram(this.blurProgram);let a=t.getAttribLocation(this.blurProgram,"a_pos");t.bindBuffer(t.ARRAY_BUFFER,this.quadBuffer),t.enableVertexAttribArray(a),t.vertexAttribPointer(a,2,t.FLOAT,!1,0,0),t.uniform1i(t.getUniformLocation(this.blurProgram,"u_source"),0),t.uniform2f(t.getUniformLocation(this.blurProgram,"u_dir"),1/this.fboWidth,0),t.drawArrays(t.TRIANGLE_STRIP,0,4),t.bindFramebuffer(t.FRAMEBUFFER,this.blurFboB),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,this.blurTexA),t.uniform1i(t.getUniformLocation(this.blurProgram,"u_source"),2),t.uniform2f(t.getUniformLocation(this.blurProgram,"u_dir"),0,1/this.fboHeight),t.drawArrays(t.TRIANGLE_STRIP,0,4)}t.bindFramebuffer(t.FRAMEBUFFER,null),t.viewport(0,0,r,s),t.useProgram(this.refractionProgram);let d=t.getAttribLocation(this.refractionProgram,"a_pos");t.bindBuffer(t.ARRAY_BUFFER,this.quadBuffer),t.enableVertexAttribArray(d),t.vertexAttribPointer(d,2,t.FLOAT,!1,0,0),t.uniform1i(t.getUniformLocation(this.refractionProgram,"u_video"),0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.mapTexture),t.uniform1i(t.getUniformLocation(this.refractionProgram,"u_map"),1),e.hasBlur&&this.blurTexB?(t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,this.blurTexB),t.uniform1i(t.getUniformLocation(this.refractionProgram,"u_blurred"),2),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_hasBlur"),1)):t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_hasBlur"),0);let f=new Float32Array(9),M=new Float32Array(3),m=new Float32Array(3),l=new Float32Array(3),W=new Float32Array(3);for(let a=0;a<3;a++)if(a<e.circles.length){let u=e.circles[a];f[a*3+0]=u.cx,f[a*3+1]=u.cy,f[a*3+2]=u.radius,M[a]=u.scale,m[a]=u.baseScale,l[a]=u.ratioX,W[a]=u.ratioY}t.uniform3fv(t.getUniformLocation(this.refractionProgram,"u_circles"),f),t.uniform1fv(t.getUniformLocation(this.refractionProgram,"u_scale"),M),t.uniform1fv(t.getUniformLocation(this.refractionProgram,"u_baseScale"),m),t.uniform1fv(t.getUniformLocation(this.refractionProgram,"u_ratioX"),l),t.uniform1fv(t.getUniformLocation(this.refractionProgram,"u_ratioY"),W),e.bar?(t.uniform4f(t.getUniformLocation(this.refractionProgram,"u_bar"),e.bar.cx,e.bar.cy,e.bar.w,e.bar.h),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_barRadius"),e.bar.radius),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_barBaseScale"),e.bar.baseScale),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_barRatioX"),e.bar.ratioX),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_barRatioY"),e.bar.ratioY)):t.uniform4f(t.getUniformLocation(this.refractionProgram,"u_bar"),0,0,-1,-1),t.uniform4f(t.getUniformLocation(this.refractionProgram,"u_bbox"),e.bbox.x,e.bbox.y,e.bbox.w,e.bbox.h),t.uniform2f(t.getUniformLocation(this.refractionProgram,"u_bboxSize"),e.bboxSize.w,e.bboxSize.h),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_chromaAmount"),e.chromaAmount),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_specStrength"),e.specStrength),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_adaptStrength"),e.adaptStrength),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_specLumaLow"),e.specLumaLow),t.uniform1f(t.getUniformLocation(this.refractionProgram,"u_specLumaHigh"),e.specLumaHigh),t.drawArrays(t.TRIANGLE_STRIP,0,4)}dispose(){let n=this.gl;n.deleteBuffer(this.quadBuffer),n.deleteProgram(this.blurProgram),n.deleteProgram(this.refractionProgram),n.deleteTexture(this.videoTexture),n.deleteTexture(this.mapTexture),this.blurFboA&&n.deleteFramebuffer(this.blurFboA),this.blurTexA&&n.deleteTexture(this.blurTexA),this.blurFboB&&n.deleteFramebuffer(this.blurFboB),this.blurTexB&&n.deleteTexture(this.blurTexB)}};var Mt=`#version 300 es
|
|
205
|
+
in vec2 a_position;
|
|
206
|
+
out vec2 v_uv;
|
|
207
|
+
|
|
208
|
+
void main() {
|
|
209
|
+
v_uv = (a_position * 0.5) + 0.5;
|
|
210
|
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
211
|
+
}
|
|
212
|
+
`,Lt=`#version 300 es
|
|
213
|
+
precision highp float;
|
|
214
|
+
precision highp sampler2D;
|
|
215
|
+
|
|
216
|
+
in vec2 v_uv;
|
|
217
|
+
out vec4 fragColor;
|
|
218
|
+
|
|
219
|
+
uniform float u_dotRadius;
|
|
220
|
+
uniform vec3 u_backgroundColor;
|
|
221
|
+
uniform sampler2D u_PaintingTexture;
|
|
222
|
+
|
|
223
|
+
// QR dot grid for the O(1) occupancy lookup (replaces a per-pixel scan over
|
|
224
|
+
// every dot). Occupancy is matrixLength x matrixLength, R8, 0/1 per module.
|
|
225
|
+
uniform sampler2D u_occupancyTexture;
|
|
226
|
+
uniform float u_gridOriginUV; // padding / size, in UV
|
|
227
|
+
uniform float u_cellUV; // cellSize / size, in UV
|
|
228
|
+
uniform float u_invCellUV; // 1 / cellUV - avoids a per-pixel divide
|
|
229
|
+
uniform int u_matrixLength;
|
|
230
|
+
|
|
231
|
+
uniform sampler2D u_displacementMap;
|
|
232
|
+
uniform sampler2D u_paintingColorTexture;
|
|
233
|
+
uniform int u_displacementActive;
|
|
234
|
+
uniform vec2 u_lensOrigin;
|
|
235
|
+
uniform vec2 u_lensSize;
|
|
236
|
+
uniform vec2 u_displacementScale;
|
|
237
|
+
uniform float u_chromaAmount;
|
|
238
|
+
|
|
239
|
+
// Eye uniforms (3 corner finder groups)
|
|
240
|
+
uniform vec2 u_eyeCenter[3];
|
|
241
|
+
uniform vec3 u_eyeHalf[3]; // x=outer, y=mid, z=inner half-size
|
|
242
|
+
uniform vec3 u_eyeRadius[3]; // x=outer, y=mid, z=inner corner radius
|
|
243
|
+
uniform vec3 u_eyeColor[3]; // fill color per group (animated)
|
|
244
|
+
uniform float u_eyeScale[3]; // hover scale per group
|
|
245
|
+
uniform float u_eyeRefractionScale; // 0-1 multiplier for eye displacement
|
|
246
|
+
|
|
247
|
+
// QR dots sit on a uniform grid, and the radius (~0.35 of a cell) never
|
|
248
|
+
// spills past a cell boundary, so the nearest dot is always the one in pos's
|
|
249
|
+
// own cell. Map pos -> module (i,j), check occupancy, then test distance to
|
|
250
|
+
// that module's center.
|
|
251
|
+
float testDot(vec2 pos, float r2) {
|
|
252
|
+
int i = int(floor((pos.x - u_gridOriginUV) * u_invCellUV));
|
|
253
|
+
int j = int(floor((pos.y - u_gridOriginUV) * u_invCellUV));
|
|
254
|
+
if (i < 0 || i >= u_matrixLength || j < 0 || j >= u_matrixLength)
|
|
255
|
+
return 1.0;
|
|
256
|
+
if (texelFetch(u_occupancyTexture, ivec2(i, j), 0).r < 0.5)
|
|
257
|
+
return 1.0;
|
|
258
|
+
vec2 c = vec2(u_gridOriginUV) + (vec2(float(i), float(j)) + 0.5) * u_cellUV;
|
|
259
|
+
vec2 d = pos - c;
|
|
260
|
+
return dot(d, d) < r2 ? 0.0 : 1.0;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
float roundedRectSDF(vec2 p, float half_, float radius) {
|
|
264
|
+
vec2 d = abs(p) - vec2(half_) + vec2(radius);
|
|
265
|
+
return length(max(d, vec2(0.0))) + min(max(d.x, d.y), 0.0) - radius;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Test all eye groups. Returns vec4(color, 1.0) if inside an eye, vec4(0) if not.
|
|
269
|
+
vec4 testEyes(vec2 pos) {
|
|
270
|
+
for (int g = 0; g < 3; g++) {
|
|
271
|
+
vec2 local = (pos - u_eyeCenter[g]) / u_eyeScale[g];
|
|
272
|
+
if (roundedRectSDF(local, u_eyeHalf[g].z, u_eyeRadius[g].z) < 0.0)
|
|
273
|
+
return vec4(u_eyeColor[g], 1.0);
|
|
274
|
+
if (roundedRectSDF(local, u_eyeHalf[g].y, u_eyeRadius[g].y) < 0.0)
|
|
275
|
+
return vec4(u_backgroundColor, 1.0);
|
|
276
|
+
if (roundedRectSDF(local, u_eyeHalf[g].x, u_eyeRadius[g].x) < 0.0)
|
|
277
|
+
return vec4(u_eyeColor[g], 1.0);
|
|
278
|
+
}
|
|
279
|
+
return vec4(0.0);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Test scene (eyes + dots) at a position, returning color for a non-displaced pixel.
|
|
283
|
+
// Returns vec4(color, 1.0) for solid, vec4(0, 0, 0, -1.0) for dot hole (discard).
|
|
284
|
+
vec4 sampleStatic(vec2 pos, float r2) {
|
|
285
|
+
vec4 eye = testEyes(pos);
|
|
286
|
+
if (eye.a > 0.5) return eye;
|
|
287
|
+
float hole = testDot(pos, r2);
|
|
288
|
+
if (hole < 0.5) return vec4(0.0, 0.0, 0.0, -1.0);
|
|
289
|
+
return vec4(u_backgroundColor, 1.0);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
void main() {
|
|
293
|
+
vec2 uv = vec2(v_uv.x, 1.0 - v_uv.y);
|
|
294
|
+
float paint = texture(u_PaintingTexture, uv).r;
|
|
295
|
+
float r2 = pow(u_dotRadius * (1.0 - paint), 2.0);
|
|
296
|
+
|
|
297
|
+
if (u_displacementActive == 0) {
|
|
298
|
+
vec4 s = sampleStatic(uv, r2);
|
|
299
|
+
if (s.a < 0.0) discard;
|
|
300
|
+
fragColor = s;
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
vec2 lensUV = (uv - u_lensOrigin) / u_lensSize;
|
|
305
|
+
bool insideLens = lensUV.x >= 0.0 && lensUV.x <= 1.0 &&
|
|
306
|
+
lensUV.y >= 0.0 && lensUV.y <= 1.0;
|
|
307
|
+
|
|
308
|
+
if (!insideLens) {
|
|
309
|
+
vec4 s = sampleStatic(uv, r2);
|
|
310
|
+
if (s.a < 0.0) discard;
|
|
311
|
+
fragColor = s;
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
vec4 dispSample = texture(u_displacementMap, lensUV);
|
|
316
|
+
if (dispSample.a < 0.01) {
|
|
317
|
+
vec4 s = sampleStatic(uv, r2);
|
|
318
|
+
if (s.a < 0.0) discard;
|
|
319
|
+
fragColor = s;
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
vec2 disp = (dispSample.rg - 0.5) * u_displacementScale;
|
|
323
|
+
|
|
324
|
+
float scaleR = 1.0 + u_chromaAmount * 2.0;
|
|
325
|
+
float scaleG = 1.0 + u_chromaAmount * 1.0;
|
|
326
|
+
|
|
327
|
+
vec2 uvR = uv + disp * scaleR;
|
|
328
|
+
vec2 uvG = uv + disp * scaleG;
|
|
329
|
+
vec2 uvB = uv + disp;
|
|
330
|
+
|
|
331
|
+
// Attenuated displacement for eyes
|
|
332
|
+
vec2 eyeDisp = disp * u_eyeRefractionScale;
|
|
333
|
+
vec2 eyeUvR = uv + eyeDisp * scaleR;
|
|
334
|
+
vec2 eyeUvG = uv + eyeDisp * scaleG;
|
|
335
|
+
vec2 eyeUvB = uv + eyeDisp;
|
|
336
|
+
|
|
337
|
+
// Per-channel: test eyes at attenuated displacement, dots at full displacement
|
|
338
|
+
vec4 eyeR = testEyes(eyeUvR);
|
|
339
|
+
vec4 eyeG = testEyes(eyeUvG);
|
|
340
|
+
vec4 eyeB = testEyes(eyeUvB);
|
|
341
|
+
|
|
342
|
+
float r, g, b;
|
|
343
|
+
|
|
344
|
+
if (eyeR.a > 0.5) {
|
|
345
|
+
r = eyeR.r;
|
|
346
|
+
} else {
|
|
347
|
+
float holeR = testDot(uvR, r2);
|
|
348
|
+
float paintR = texture(u_paintingColorTexture, uvR).r;
|
|
349
|
+
r = mix(paintR, u_backgroundColor.r, holeR);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (eyeG.a > 0.5) {
|
|
353
|
+
g = eyeG.g;
|
|
354
|
+
} else {
|
|
355
|
+
float holeG = testDot(uvG, r2);
|
|
356
|
+
float paintG = texture(u_paintingColorTexture, uvG).g;
|
|
357
|
+
g = mix(paintG, u_backgroundColor.g, holeG);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (eyeB.a > 0.5) {
|
|
361
|
+
b = eyeB.b;
|
|
362
|
+
} else {
|
|
363
|
+
float holeB = testDot(uvB, r2);
|
|
364
|
+
float paintB = texture(u_paintingColorTexture, uvB).b;
|
|
365
|
+
b = mix(paintB, u_backgroundColor.b, holeB);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
fragColor = vec4(r, g, b, 1.0);
|
|
369
|
+
}
|
|
370
|
+
`;function bt(o,n,e){let t=o.createShader(n);if(!t)throw new Error("Failed to create shader");if(o.shaderSource(t,e),o.compileShader(t),!o.getShaderParameter(t,o.COMPILE_STATUS)){let r=o.getShaderInfoLog(t);throw o.deleteShader(t),new Error(`Shader compilation error: ${r??""}`)}return t}var Ie=class{constructor(n){let e=n.canvas.getContext("webgl2",{alpha:!0,antialias:!1,premultipliedAlpha:!1});if(!e)throw new Error("WebGL 2 not supported");this.gl=e,this.matrixLength=n.matrixLength,this.gridOriginUV=n.gridOriginUV,this.cellUV=n.cellUV,this.dotRadius=n.dotRadius,this.backgroundColor=n.backgroundColor??[1,1,1];let t=bt(e,e.VERTEX_SHADER,Mt),r=bt(e,e.FRAGMENT_SHADER,Lt),s=e.createProgram();if(e.attachShader(s,t),e.attachShader(s,r),e.linkProgram(s),!e.getProgramParameter(s,e.LINK_STATUS))throw new Error(`QR Program link error: ${e.getProgramInfoLog(s)??""}`);this.program=s;let d=new Float32Array([-1,-1,1,-1,-1,1,1,1]);this.quadBuffer=e.createBuffer(),e.bindBuffer(e.ARRAY_BUFFER,this.quadBuffer),e.bufferData(e.ARRAY_BUFFER,d,e.STATIC_DRAW),this.occupancyTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.occupancyTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.R8,this.matrixLength,this.matrixLength,0,e.RED,e.UNSIGNED_BYTE,n.occupancyMatrix),this.displacementTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.displacementTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR);let f=new Uint8Array([0,0,0,0]);this.paintingTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.paintingTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,f),this.paintingColorTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.paintingColorTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,f)}setDisplacementMap(n){let e=this.gl;e.bindTexture(e.TEXTURE_2D,this.displacementTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,n)}render(n){let e=this.gl;e.viewport(0,0,e.canvas.width,e.canvas.height),e.useProgram(this.program);let t=e.getAttribLocation(this.program,"a_position");e.bindBuffer(e.ARRAY_BUFFER,this.quadBuffer),e.enableVertexAttribArray(t),e.vertexAttribPointer(t,2,e.FLOAT,!1,0,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.occupancyTexture),e.uniform1i(e.getUniformLocation(this.program,"u_occupancyTexture"),0),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.displacementTexture),e.uniform1i(e.getUniformLocation(this.program,"u_displacementMap"),1),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.paintingTexture),e.uniform1i(e.getUniformLocation(this.program,"u_PaintingTexture"),2),e.activeTexture(e.TEXTURE3),e.bindTexture(e.TEXTURE_2D,this.paintingColorTexture),e.uniform1i(e.getUniformLocation(this.program,"u_paintingColorTexture"),3),e.uniform1f(e.getUniformLocation(this.program,"u_dotRadius"),this.dotRadius),e.uniform3fv(e.getUniformLocation(this.program,"u_backgroundColor"),this.backgroundColor),e.uniform1f(e.getUniformLocation(this.program,"u_gridOriginUV"),this.gridOriginUV),e.uniform1f(e.getUniformLocation(this.program,"u_cellUV"),this.cellUV),e.uniform1f(e.getUniformLocation(this.program,"u_invCellUV"),1/this.cellUV),e.uniform1i(e.getUniformLocation(this.program,"u_matrixLength"),this.matrixLength),e.uniform1i(e.getUniformLocation(this.program,"u_displacementActive"),n.displacementActive?1:0),e.uniform2f(e.getUniformLocation(this.program,"u_lensOrigin"),n.lensOrigin[0],n.lensOrigin[1]),e.uniform2f(e.getUniformLocation(this.program,"u_lensSize"),n.lensSize[0],n.lensSize[1]),e.uniform2f(e.getUniformLocation(this.program,"u_displacementScale"),n.displacementScale[0],n.displacementScale[1]),e.uniform1f(e.getUniformLocation(this.program,"u_chromaAmount"),n.chromaAmount),e.uniform1f(e.getUniformLocation(this.program,"u_eyeRefractionScale"),n.eyeRefractionScale??.2);let r=new Float32Array(6),s=new Float32Array(9),d=new Float32Array(9),f=new Float32Array(9),M=new Float32Array(3);for(let m=0;m<3;m++)if(m<n.eyes.length){let l=n.eyes[m];r[m*2+0]=l.center[0],r[m*2+1]=l.center[1],s[m*3+0]=l.half[0],s[m*3+1]=l.half[1],s[m*3+2]=l.half[2],d[m*3+0]=l.radius[0],d[m*3+1]=l.radius[1],d[m*3+2]=l.radius[2],f[m*3+0]=l.color[0],f[m*3+1]=l.color[1],f[m*3+2]=l.color[2],M[m]=l.scale}e.uniform2fv(e.getUniformLocation(this.program,"u_eyeCenter"),r),e.uniform3fv(e.getUniformLocation(this.program,"u_eyeHalf"),s),e.uniform3fv(e.getUniformLocation(this.program,"u_eyeRadius"),d),e.uniform3fv(e.getUniformLocation(this.program,"u_eyeColor"),f),e.uniform1fv(e.getUniformLocation(this.program,"u_eyeScale"),M),e.drawArrays(e.TRIANGLE_STRIP,0,4)}dispose(){let n=this.gl;n.deleteBuffer(this.quadBuffer),n.deleteProgram(this.program),n.deleteTexture(this.occupancyTexture),n.deleteTexture(this.displacementTexture),n.deleteTexture(this.paintingTexture),n.deleteTexture(this.paintingColorTexture)}};return vt(Dt);})();
|
|
371
|
+
//# sourceMappingURL=lensfx.min.js.map
|