@liiift-studio/threadtext 0.1.1 → 0.2.1

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/README.md CHANGED
@@ -75,8 +75,9 @@ import { ThreadText } from '@liiift-studio/threadtext'
75
75
  ```
76
76
 
77
77
  Thread colour, `fill` (size — the word re-fits to the container width on load/resize),
78
- `weight`, `font`, `sewRate`, `sheen`, `animate`, and `editable` (type straight on the
79
- artwork backed by a real input, so touch keyboards and IME work) with an `onTextChange`
78
+ `weight`, `font`, `sewStyle` (`'machine'` satin rows in parallel, or `'hand'` one letter at
79
+ a time, longest threads first), `sewRate`, `sheen`, `animate`, and `editable` (type straight on
80
+ the artwork — backed by a real input, so touch keyboards and IME work) with an `onTextChange`
80
81
  callback are all options — see `ThreadTextOptions`. Change any of them live with
81
82
  `instance.update(...)` — it redraws instantly, never re-running the sew-in. `react`/`react-dom`
82
83
  are optional peers; the core is framework-free.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const V=require("react"),At=require("react/jsx-runtime"),Te={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function W(h,t){let n=Math.imul(h|0,374761393)+Math.imul(t|0,668265263)|0;return n=Math.imul(n^n>>>13,1274126177),((n^n>>>16)>>>0)/4294967295}function tt(h,t){const n=Math.floor(h),r=Math.floor(t),i=h-n,a=t-r,u=i*i*(3-2*i),b=a*a*(3-2*a),S=W(n,r),E=W(n+1,r),c=W(n,r+1),m=W(n+1,r+1);return S+(E-S)*u+(c-S)*b+(S-E-c+m)*u*b}const Ee=1e20;function nt(h,t,n,r,i){let a=0;r[0]=0,i[0]=-Ee,i[1]=Ee;for(let u=1;u<t;u++){let b=(h[u]+u*u-(h[r[a]]+r[a]*r[a]))/(2*u-2*r[a]);for(;b<=i[a];)a--,b=(h[u]+u*u-(h[r[a]]+r[a]*r[a]))/(2*u-2*r[a]);a++,r[a]=u,i[a]=b,i[a+1]=Ee}a=0;for(let u=0;u<t;u++){for(;i[a+1]<u;)a++;n[u]=(u-r[a])*(u-r[a])+h[r[a]]}}function St(h,t,n){const r=new Float64Array(t*n);for(let c=0;c<t*n;c++)r[c]=h[c]?Ee:0;const i=Math.max(t,n),a=new Float64Array(i),u=new Float64Array(i),b=new Int32Array(i),S=new Float64Array(i+1);for(let c=0;c<t;c++){for(let m=0;m<n;m++)a[m]=r[m*t+c];nt(a,n,u,b,S);for(let m=0;m<n;m++)r[m*t+c]=u[m]}for(let c=0;c<n;c++){for(let m=0;m<t;m++)a[m]=r[c*t+m];nt(a,t,u,b,S);for(let m=0;m<t;m++)r[c*t+m]=u[m]}const E=new Float32Array(t*n);for(let c=0;c<t*n;c++)E[c]=Math.sqrt(r[c]);return E}function ot(h,t,n,r,i){let a=Float32Array.from(h);const u=new Float32Array(t*n),b=1/(2*r+1),S=(E,c)=>E<0?0:E>c?c:E;for(let E=0;E<i;E++){for(let c=0;c<n;c++){const m=c*t;let I=0;for(let N=-r;N<=r;N++)I+=a[m+S(N,t-1)];for(let N=0;N<t;N++)u[m+N]=I*b,I+=a[m+S(N+r+1,t-1)]-a[m+S(N-r,t-1)]}for(let c=0;c<t;c++){let m=0;for(let I=-r;I<=r;I++)m+=u[S(I,n-1)*t+c];for(let I=0;I<n;I++)a[I*t+c]=m*b,m+=u[S(I+r+1,n-1)*t+c]-u[S(I-r,n-1)*t+c]}}return a}function rt(h,t){if(!h)return t;const n=h.trim();if(n[0]==="#"){let i=n.slice(1);if(i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),i.length>=6){const a=parseInt(i.slice(0,2),16),u=parseInt(i.slice(2,4),16),b=parseInt(i.slice(4,6),16);if(!Number.isNaN(a)&&!Number.isNaN(u)&&!Number.isNaN(b))return[a,u,b]}return t}const r=n.match(/rgba?\(([^)]+)\)/i);if(r){const i=r[1].split(",").map(a=>parseFloat(a));if(i.length>=3&&i.slice(0,3).every(a=>!Number.isNaN(a)))return[Math.round(i[0]),Math.round(i[1]),Math.round(i[2])]}return t}function K(h){return h<0?0:h>255?255:Math.round(h)}function be(h,t,n){return h<t?t:h>n?n:h}function it(h){return(h.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function at(h,t){if(typeof window>"u"||typeof document>"u"||!h)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return t.text??""}};let n=t.text??"",r=t.font??"Georgia, serif",i=be(t.weight??680,1,1e3),a=be(t.fill??.9,.05,1),u=Math.max(1,t.sewRate??110),b=t.sheen??!0,S=t.animate??!0,E=t.editable??!1,c=t.pitch,m=t.onTextChange,I=it(r);const N=t.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let B=rt(t.threadColor??"#fffbf3",[255,251,243]),ae=[0,0,0],D=[0,0,0];function le(e){B=rt(e,[255,251,243]),ae=[B[0]*.585,B[1]*.585,B[2]*.585],D=[B[0]*.47,B[1]*.47,B[2]*.47]}le(t.threadColor??"#fffbf3");const G=[];let O,L;h instanceof HTMLCanvasElement?(O=h,L=h.parentElement??h):(L=h,O=document.createElement("canvas"),G.push(O),L.appendChild(O)),O.classList.add(Te.bg);const j=document.createElement("canvas");G.push(j),j.classList.add(Te.fx),L.appendChild(j),getComputedStyle(L).position==="static"&&(L.style.position="relative"),O.style.display="block",O.style.width="100%",Object.assign(j.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let y=null,A=null,Q=!1,s=0,x=0,ee=0,Ae=0,te=4,ne=[],se=0,ce=0,je=-1,qe="",ze=-1,_e=-1,Se=new Uint8Array(0),Fe=new Float32Array(0),me=new Float32Array(0),xe=new Float32Array(0),Y=null,oe=null,ye=null,ge=[],pe=3;const $={rows:[],idx:0,acc:0,rate:0,on:!1},U={x:0,y:0,set:!1};let Z=!0,Re=0,fe=!1,ue=0,q=!1,H=!1;function ct(){const e=L.getBoundingClientRect(),o=Math.max(1,Math.round(e.width||Math.min(window.innerWidth*.95,1240))),l=n||"Ag",f=O.getContext("2d");f&&(f.textBaseline="middle");let T=100;f&&(f.font=`${i} 100px ${r}`,T=f.measureText(l).width||100);const C=Math.max(8,100*(o*a)/T);let v=C*.62,F=C*.62,P=o*a;if(f){f.font=`${i} ${C}px ${r}`;const w=f.measureText(l);P=w.width||P,w.actualBoundingBoxAscent>0&&(v=w.actualBoundingBoxAscent),w.actualBoundingBoxDescent>0&&(F=w.actualBoundingBoxDescent)}const p=Math.max(1,Math.round(2*Math.max(v,F)*1.1));let d=Math.min(window.devicePixelRatio||1,1.7);for(;o*d*p*d>9e5&&d>.4;)d-=.1;s=Math.max(1,Math.round(o*d)),x=Math.max(1,Math.round(p*d)),ee=Math.max(4,Math.round(C*d)),Ae=Math.round(s/2-P*d/2);for(const w of[O,j])w.width=s,w.height=x,w.style.height=p+"px";L.style.height=p+"px",te=c??Math.max(3,x*.0095)}function ft(){oe&&ze===s&&_e===x||(oe=document.createElement("canvas"),oe.width=s,oe.height=x,ye=oe.getContext("2d",{willReadFrequently:!0}),ze=s,_e=x)}function Xe(){const e=Math.max(7,te*2.5),o=Math.max(3.2,te*1.3);se=Math.ceil(e)+2,ce=Math.ceil(o)+2,ne=[];for(let l=0;l<20;l++){const f=.34+l/19*.82,T=document.createElement("canvas");T.width=se,T.height=ce;const C=T.getContext("2d");if(!C){ne.push(T);continue}const v=se/2,F=ce/2,P=C.createLinearGradient(0,F-o/2,0,F+o/2),p=(k,z)=>`rgba(${K(k[0]*f)},${K(k[1]*f)},${K(k[2]*f)},${z})`;P.addColorStop(0,p(D,0)),P.addColorStop(.16,p(ae,1)),P.addColorStop(.5,p(B,1)),P.addColorStop(.84,p(ae,1)),P.addColorStop(1,p(D,0)),C.fillStyle=P,C.beginPath();const d=o/2;C.moveTo(v-e/2+d,F-d),C.lineTo(v+e/2-d,F-d),C.arc(v+e/2-d,F,d,-Math.PI/2,Math.PI/2),C.lineTo(v-e/2+d,F+d),C.arc(v-e/2+d,F,d,Math.PI/2,-Math.PI/2),C.closePath(),C.fill(),C.globalCompositeOperation="destination-in";const w=C.createLinearGradient(v-e/2,0,v+e/2,0);w.addColorStop(0,"rgba(0,0,0,0)"),w.addColorStop(.22,"rgba(0,0,0,1)"),w.addColorStop(.78,"rgba(0,0,0,1)"),w.addColorStop(1,"rgba(0,0,0,0)"),C.fillStyle=w,C.fillRect(0,0,se,ce),ne.push(T)}je=te,qe=B.join(",")}function ut(){ne.length&&je===te&&qe===B.join(",")||Xe()}function dt(){if(!ye)return;const e=ye;e.clearRect(0,0,s,x),e.fillStyle="#fff",e.textAlign="left",e.textBaseline="middle",e.font=`${i} ${ee}px ${r}`,e.fillText(n,Ae,x*.5);const o=e.getImageData(0,0,s,x).data,l=new Uint8Array(s*x);for(let g=0;g<x;g++)for(let M=0;M<s;M++){const R=g*s+M,_=o[R*4+3]/255,X=tt(M*.5,g*.5)*.22+tt(M*1.8,g*1.8)*.1;l[R]=_>.5+(X-.16)?1:0}Se=l;const f=St(l,s,x),T=new Float32Array(s*x);for(let g=1;g<x-1;g++)for(let M=1;M<s-1;M++){const R=g*s+M;T[R]=(f[R]*4+f[R-1]+f[R+1]+f[R-s]+f[R+s])/8}const C=new Float32Array(s*x),v=new Float32Array(s*x),F=new Float32Array(s*x),P=new Float32Array(s*x);for(let g=1;g<x-1;g++)for(let M=1;M<s-1;M++){const R=g*s+M;if(!l[R])continue;const _=(T[R+1]-T[R-1])*.5,X=(T[R+s]-T[R-s])*.5;F[R]=_,P[R]=X,C[R]=_*_-X*X,v[R]=2*_*X}const p=Math.max(7,Math.round(x*.05)),d=ot(C,s,x,p,2),w=ot(v,s,x,p,2);me=new Float32Array(s*x),xe=new Float32Array(s*x);for(let g=0;g<s*x;g++){if(!l[g])continue;const M=.5*Math.atan2(w[g],d[g]);me[g]=Math.cos(M),xe[g]=Math.sin(M)}const k=Math.max(9,x*.04),z=new Float32Array(s*x),de=-.45,he=-.62,ve=.64;for(let g=1;g<x-1;g++)for(let M=1;M<s-1;M++){const R=g*s+M;if(!l[R])continue;let _=F[R],X=P[R];const Qe=Math.hypot(_,X)||1;_/=Qe,X/=Qe;const Ze=T[R],We=(1-Math.min(Ze/k,1))*1.25;let Oe=-_*We,ke=-X*We;const et=1.5,Ne=Math.hypot(Oe,ke,et);Oe/=Ne,ke/=Ne;let De=Oe*de+ke*he+et/Ne*ve;De<0&&(De=0);const Et=Math.min(1,.45+.55*Math.min(Ze/(k*.7),1));z[R]=Math.min(1.12,(.5+.75*De)*Et)}Fe=z,Y=document.createElement("canvas"),Y.width=s,Y.height=x;const J=Y.getContext("2d");if(J){const g=J.createImageData(s,x);for(let M=0;M<s*x;M++)l[M]&&(g.data[M*4]=255,g.data[M*4+1]=255,g.data[M*4+2]=255,g.data[M*4+3]=255);J.putImageData(g,0,0)}}function ht(){const e=Math.max(1.6,te*.6);pe=e;const o=[];for(let l=0;l<x;l+=e)for(let f=0;f<s;f+=e){const T=(W(Math.floor(f),Math.floor(l))-.5)*e*.9,C=(W(Math.floor(l),Math.floor(f))-.5)*e*.9,v=Math.round(f+T),F=Math.round(l+C);if(v<1||F<1||v>=s-1||F>=x-1)continue;const P=F*s+v;if(!Se[P])continue;const p=Math.atan2(xe[P],me[P]),d=.86+W(v*7,F*13)*.18;let w=Fe[P]*d;w=w<0?0:w>1.12?1.12:w,o.push({x:v,y:F,ang:p,idx:Math.min(19,Math.max(0,Math.round(w/1.12*19)))})}ge=o}function Ge(e,o){e.save(),e.translate(o.x,o.y),e.rotate(o.ang),e.drawImage(ne[o.idx],-se/2,-ce/2),e.restore()}function Le(){const e=O.getContext("2d");if(e)for(const o of ge)Ge(e,o)}function $e(){const e=O.getContext("2d");e&&e.clearRect(0,0,s,x)}function mt(e){if(!e.length)return[];const o=Math.max(4,pe*1.5),l=new Map,f=(p,d)=>p+","+d;e.forEach((p,d)=>{const w=f(Math.floor(p.x/o),Math.floor(p.y/o));let k=l.get(w);k||l.set(w,k=[]),k.push(d)});const T=pe*1.8*(pe*1.8);function C(p){const d=e[p],w=Math.floor(d.x/o),k=Math.floor(d.y/o),z=[];for(let de=-1;de<=1;de++)for(let he=-1;he<=1;he++){const ve=l.get(f(w+de,k+he));if(ve)for(const J of ve){if(J===p)continue;const g=e[J].x-d.x,M=e[J].y-d.y;g*g+M*M<=T&&z.push(J)}}return z}const v=new Uint8Array(e.length),F=[],P=e.map((p,d)=>d).sort((p,d)=>e[p].x+e[p].y-(e[d].x+e[d].y));for(const p of P){if(v[p])continue;let d=[p];for(v[p]=1;d.length;){F.push(d.map(k=>e[k]));const w=[];for(const k of d)for(const z of C(k))v[z]||(v[z]=1,w.push(z));d=w}}return F}function xt(){if($e(),N||!S){Le(),$.on=!1;return}$.rows=mt(ge),$.idx=0,$.acc=0,$.rate=u,$.on=$.rows.length>0}function yt(e){const o=O.getContext("2d");if(o)for(e>$.rows.length&&(e=$.rows.length);$.idx<e;){const l=$.rows[$.idx++];for(const f of l)Ge(o,f)}}function gt(e,o){const l=j.getContext("2d");if(!l||(l.clearRect(0,0,s,x),!b||!Y))return;const f=s*.32,T=l.createRadialGradient(e,o,0,e,o,f);T.addColorStop(0,"rgba(255,250,238,0.18)"),T.addColorStop(.5,"rgba(255,250,238,0.055)"),T.addColorStop(1,"rgba(255,250,238,0)"),l.fillStyle=T,l.fillRect(0,0,s,x),l.globalCompositeOperation="destination-in",l.drawImage(Y,0,0),l.globalCompositeOperation="source-over"}function pt(){A||!E||(A=document.createElement("span"),A.className=Te.caret,A.setAttribute("aria-hidden","true"),Object.assign(A.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${K(B[0])},${K(B[1])},${K(B[2])})`}),L.appendChild(A),G.push(A))}function Ie(){if(!E||!A)return;const e=O.getContext("2d");if(!e)return;e.font=`${i} ${ee}px ${r}`;const o=e.measureText(n).width,l=(O.clientWidth||s)/s,f=ee*.7;A.style.left=(Ae+o+ee*.05)*l+"px",A.style.top=.5*(O.clientHeight||x)-f*l/2+"px",A.style.height=f*l+"px",A.style.width=Math.max(2,Math.round(ee*.02*l))+"px",A.style.background=`rgb(${K(B[0])},${K(B[1])},${K(B[2])})`}function re(){q||fe||(fe=!0,ue=0,Re=requestAnimationFrame(Ue))}function Ue(e){if(q){fe=!1;return}ue||(ue=e);const o=Math.min(.25,(e-ue)/1e3);ue=e,$.on&&($.acc+=$.rate*o,yt($.acc),$.idx>=$.rows.length&&($.on=!1)),Z&&Y&&(gt(U.set?U.x:s*.5,U.set?U.y:x*.45),Z=!1);const l=E&&Q;if(A&&(A.style.opacity=l&&Math.floor(e/530)%2===0?"1":"0"),!$.on&&!Z&&!l){fe=!1;return}Re=requestAnimationFrame(Ue)}function we(e){const o=L.getBoundingClientRect();U.x=(e.clientX-o.left)/(o.width||1)*s,U.y=(e.clientY-o.top)/(o.height||1)*x,U.set=!0,Z=!0,re()}function Me(){U.set=!1,Z=!0,re()}function wt(){y&&Ve(y.value,!0)}function Mt(e){e.key==="Enter"&&(e.preventDefault(),Be.replay())}function Ct(){Q=!0,re()}function vt(){Q=!1,A&&(A.style.opacity="0")}function Ke(e){e===E&&y||(E=e,e?(y||(y=document.createElement("input"),y.type="text",y.value=n,y.maxLength=64,y.setAttribute("aria-label","Embroidered text — type to change it"),y.setAttribute("autocomplete","off"),y.setAttribute("autocapitalize","off"),y.spellcheck=!1,Object.assign(y.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),y.addEventListener("input",wt),y.addEventListener("keydown",Mt),y.addEventListener("focus",Ct),y.addEventListener("blur",vt),L.appendChild(y),G.push(y)),pt(),Ie()):(y&&(y.remove(),y=null),Q=!1,A&&(A.style.opacity="0")))}function bt(e){if(e!==b)if(b=e,e)L.addEventListener("pointermove",we,{passive:!0}),L.addEventListener("pointerleave",Me,{passive:!0}),U.set=!1,Z=!0,re();else{L.removeEventListener("pointermove",we),L.removeEventListener("pointerleave",Me);const o=j.getContext("2d");o&&o.clearRect(0,0,s,x)}}function ie(e){ct(),ft(),ut(),dt(),ht(),e?xt():($e(),Le(),$.on=!1),y&&y.value!==n&&(y.value=n),Ie(),Z=!0,re()}function Ve(e,o){e=e??"",!(e===n&&H)&&(n=e,H&&(ie(!1),o&&m&&m(n)))}const Ce=new Set;function Ye(e,o,l){const f=`${o} 200px ${e}`;let T=!1;try{T=!!document.fonts&&document.fonts.check(f)}catch{T=!0}if(!document.fonts||T){l();return}let C=!1,v;const F=()=>{C||(C=!0,clearTimeout(v),Ce.delete(v),q||l())};document.fonts.load(f,n).then(()=>document.fonts.ready).then(F,F),v=setTimeout(F,1500),Ce.add(v)}function Tt(){q||(ie(!0),H=!0)}E&&(E=!1,Ke(!0)),b&&(L.addEventListener("pointermove",we,{passive:!0}),L.addEventListener("pointerleave",Me,{passive:!0})),Ye(I,i,Tt);let Pe,He=-1;function Je(){clearTimeout(Pe),Pe=setTimeout(()=>{if(q||!H)return;const e=Math.round(L.getBoundingClientRect().width);e!==He&&(He=e,ie(!1))},200)}window.addEventListener("resize",Je);const Be={get text(){return n},setText(e){if(!q){if(!H){n=e??"",y&&(y.value=n);return}Ve(e,!1)}},replay(){q||!H||ie(!0)},resize(){q||!H||ie(!1)},update(e){if(q)return;e.text!==void 0&&Be.setText(e.text);let o=!1,l=!1;if(e.font!==void 0&&e.font!==r&&(r=e.font,I=it(r),o=!0),e.weight!==void 0){const f=be(e.weight,1,1e3);f!==i&&(i=f,o=!0)}if(e.fill!==void 0){const f=be(e.fill,.05,1);f!==a&&(a=f,o=!0)}e.pitch!==void 0&&e.pitch!==c&&(c=e.pitch,o=!0),e.threadColor!==void 0&&(le(e.threadColor),l=!0),e.sewRate!==void 0&&(u=Math.max(1,e.sewRate)),e.animate!==void 0&&(S=e.animate),e.onTextChange!==void 0&&(m=e.onTextChange),e.sheen!==void 0&&bt(e.sheen),e.editable!==void 0&&Ke(e.editable),H&&(o?Ye(I,i,()=>{q||ie(!1)}):l&&(Xe(),$e(),Le(),Ie(),re()))},focus(){!q&&E&&(y==null||y.focus())},destroy(){if(!q){q=!0,fe=!1,cancelAnimationFrame(Re),clearTimeout(Pe);for(const e of Ce)clearTimeout(e);Ce.clear(),window.removeEventListener("resize",Je),L.removeEventListener("pointermove",we),L.removeEventListener("pointerleave",Me);for(const e of G)e.remove();ne=[],ge=[],$.rows=[],Se=new Uint8Array(0),Fe=new Float32Array(0),me=new Float32Array(0),xe=new Float32Array(0),Y=oe=null,ye=null,A=null,y=null}}};return Be}function lt(h){const t=V.useRef(null),n=V.useRef(null),r=V.useRef(h);r.current=h;const i=V.useRef(h.onTextChange);i.current=h.onTextChange;const{text:a,font:u,weight:b,threadColor:S,pitch:E,fill:c,animate:m,sewRate:I,sheen:N,editable:B,reducedMotion:ae}=h;return V.useLayoutEffect(()=>{const D=t.current;if(!D)return;const le=at(D,{...r.current,onTextChange:y=>{var A;return(A=i.current)==null?void 0:A.call(i,y)}});n.current=le;let G=0,O=0,L=!0,j;return typeof ResizeObserver<"u"&&(j=new ResizeObserver(y=>{const A=Math.round(y[0].contentRect.width);if(L){L=!1,O=A;return}A!==O&&(O=A,cancelAnimationFrame(G),G=requestAnimationFrame(()=>{var Q;return(Q=n.current)==null?void 0:Q.resize()}))}),j.observe(D)),()=>{j==null||j.disconnect(),cancelAnimationFrame(G),le.destroy(),n.current=null}},[ae]),V.useEffect(()=>{var D;(D=n.current)==null||D.update({font:u,weight:b,threadColor:S,pitch:E,fill:c,animate:m,sewRate:I,sheen:N,editable:B})},[u,b,S,E,c,m,I,N,B]),V.useEffect(()=>{var D;(D=n.current)==null||D.setText(a)},[a]),t}const st=V.forwardRef(function({className:t,style:n,as:r="div","aria-label":i,role:a,"aria-describedby":u,...b},S){const E=lt(b),c=V.useCallback(m=>{E.current=m,typeof S=="function"?S(m):S&&(S.current=m)},[E,S]);return At.jsx(r,{ref:c,className:t,style:n,role:b.editable?a:a??"img","aria-label":b.editable?i:i??b.text,"aria-describedby":u})});st.displayName="ThreadText";exports.THREAD_TEXT_CLASSES=Te;exports.ThreadText=st;exports.createThreadText=at;exports.useThreadText=lt;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const J=require("react"),Re=require("react/jsx-runtime"),St={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function ot(x,n){let o=Math.imul(x|0,374761393)+Math.imul(n|0,668265263)|0;return o=Math.imul(o^o>>>13,1274126177),((o^o>>>16)>>>0)/4294967295}function oe(x,n){const o=Math.floor(x),i=Math.floor(n),a=x-o,l=n-i,h=a*a*(3-2*a),F=l*l*(3-2*l),E=ot(o,i),P=ot(o+1,i),c=ot(o,i+1),m=ot(o+1,i+1);return E+(P-E)*h+(c-E)*F+(E-P-c+m)*h*F}const Et=1e20;function re(x,n,o,i,a){let l=0;i[0]=0,a[0]=-Et,a[1]=Et;for(let h=1;h<n;h++){let F=(x[h]+h*h-(x[i[l]]+i[l]*i[l]))/(2*h-2*i[l]);for(;F<=a[l];)l--,F=(x[h]+h*h-(x[i[l]]+i[l]*i[l]))/(2*h-2*i[l]);l++,i[l]=h,a[l]=F,a[l+1]=Et}l=0;for(let h=0;h<n;h++){for(;a[l+1]<h;)l++;o[h]=(h-i[l])*(h-i[l])+x[i[l]]}}function Le(x,n,o){const i=new Float64Array(n*o);for(let c=0;c<n*o;c++)i[c]=x[c]?Et:0;const a=Math.max(n,o),l=new Float64Array(a),h=new Float64Array(a),F=new Int32Array(a),E=new Float64Array(a+1);for(let c=0;c<n;c++){for(let m=0;m<o;m++)l[m]=i[m*n+c];re(l,o,h,F,E);for(let m=0;m<o;m++)i[m*n+c]=h[m]}for(let c=0;c<o;c++){for(let m=0;m<n;m++)l[m]=i[c*n+m];re(l,n,h,F,E);for(let m=0;m<n;m++)i[c*n+m]=h[m]}const P=new Float32Array(n*o);for(let c=0;c<n*o;c++)P[c]=Math.sqrt(i[c]);return P}function ie(x,n,o,i,a){let l=Float32Array.from(x);const h=new Float32Array(n*o),F=1/(2*i+1),E=(P,c)=>P<0?0:P>c?c:P;for(let P=0;P<a;P++){for(let c=0;c<o;c++){const m=c*n;let k=0;for(let j=-i;j<=i;j++)k+=l[m+E(j,n-1)];for(let j=0;j<n;j++)h[m+j]=k*F,k+=l[m+E(j+i+1,n-1)]-l[m+E(j-i,n-1)]}for(let c=0;c<n;c++){let m=0;for(let k=-i;k<=i;k++)m+=h[E(k,o-1)*n+c];for(let k=0;k<o;k++)l[k*n+c]=m*F,m+=h[E(k+i+1,o-1)*n+c]-h[E(k-i,o-1)*n+c]}}return l}function ae(x,n){if(!x)return n;const o=x.trim();if(o[0]==="#"){let a=o.slice(1);if(a.length===3&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]),a.length>=6){const l=parseInt(a.slice(0,2),16),h=parseInt(a.slice(2,4),16),F=parseInt(a.slice(4,6),16);if(!Number.isNaN(l)&&!Number.isNaN(h)&&!Number.isNaN(F))return[l,h,F]}return n}const i=o.match(/rgba?\(([^)]+)\)/i);if(i){const a=i[1].split(",").map(l=>parseFloat(l));if(a.length>=3&&a.slice(0,3).every(l=>!Number.isNaN(l)))return[Math.round(a[0]),Math.round(a[1]),Math.round(a[2])]}return n}function H(x){return x<0?0:x>255?255:Math.round(x)}function bt(x,n,o){return x<n?n:x>o?o:x}function le(x){return(x.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function se(x,n){if(typeof window>"u"||typeof document>"u"||!x)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let o=n.text??"",i=n.font??"Georgia, serif",a=bt(n.weight??680,1,1e3),l=bt(n.fill??.9,.05,1),h=Math.max(1,n.sewRate??110),F=n.sewStyle==="hand"?"hand":"machine",E=n.sheen??!0,P=n.animate??!0,c=n.editable??!1,m=n.pitch,k=n.onTextChange,j=le(i);const gt=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let O=ae(n.threadColor??"#fffbf3",[255,251,243]),ft=[0,0,0],D=[0,0,0];function ut(t){O=ae(t,[255,251,243]),ft=[O[0]*.585,O[1]*.585,O[2]*.585],D=[O[0]*.47,O[1]*.47,O[2]*.47]}ut(n.threadColor??"#fffbf3");const G=[];let B,L;x instanceof HTMLCanvasElement?(B=x,L=x.parentElement??x):(L=x,B=document.createElement("canvas"),G.push(B),L.appendChild(B)),B.classList.add(St.bg);const q=document.createElement("canvas");G.push(q),q.classList.add(St.fx),L.appendChild(q),getComputedStyle(L).position==="static"&&(L.style.position="relative"),B.style.display="block",B.style.width="100%",Object.assign(q.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let v=null,A=null,tt=!1,u=0,p=0,rt=0,At=0,it=4,at=[],dt=0,ht=0,qt=-1,zt="",_t=-1,Xt=-1,Ft=new Uint8Array(0),Rt=new Float32Array(0),pt=new Float32Array(0),wt=new Float32Array(0),Q=null,lt=null,Mt=null,mt=[],et=3;const $={rows:[],idx:0,acc:0,rate:0,on:!1},K={x:0,y:0,set:!1};let nt=!0,Lt=0,xt=!1,yt=0,z=!1,Z=!1;function ue(){const t=L.getBoundingClientRect(),e=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),r=o||"Ag",f=B.getContext("2d");f&&(f.textBaseline="middle");let C=100;f&&(f.font=`${a} 100px ${i}`,C=f.measureText(r).width||100);const y=Math.max(8,100*(e*l)/C);let g=y*.62,b=y*.62,T=e*l;if(f){f.font=`${a} ${y}px ${i}`;const w=f.measureText(r);T=w.width||T,w.actualBoundingBoxAscent>0&&(g=w.actualBoundingBoxAscent),w.actualBoundingBoxDescent>0&&(b=w.actualBoundingBoxDescent)}const d=Math.max(1,Math.round(2*Math.max(g,b)*1.1));let s=Math.min(window.devicePixelRatio||1,1.7);for(;e*s*d*s>9e5&&s>.4;)s-=.1;u=Math.max(1,Math.round(e*s)),p=Math.max(1,Math.round(d*s)),rt=Math.max(4,Math.round(y*s)),At=Math.round(u/2-T*s/2);for(const w of[B,q])w.width=u,w.height=p,w.style.height=d+"px";L.style.height=d+"px",it=m??Math.max(3,p*.0095)}function de(){lt&&_t===u&&Xt===p||(lt=document.createElement("canvas"),lt.width=u,lt.height=p,Mt=lt.getContext("2d",{willReadFrequently:!0}),_t=u,Xt=p)}function Ut(){const t=Math.max(7,it*2.5),e=Math.max(3.2,it*1.3);dt=Math.ceil(t)+2,ht=Math.ceil(e)+2,at=[];for(let r=0;r<20;r++){const f=.34+r/19*.82,C=document.createElement("canvas");C.width=dt,C.height=ht;const y=C.getContext("2d");if(!y){at.push(C);continue}const g=dt/2,b=ht/2,T=y.createLinearGradient(0,b-e/2,0,b+e/2),d=(I,N)=>`rgba(${H(I[0]*f)},${H(I[1]*f)},${H(I[2]*f)},${N})`;T.addColorStop(0,d(D,0)),T.addColorStop(.16,d(ft,1)),T.addColorStop(.5,d(O,1)),T.addColorStop(.84,d(ft,1)),T.addColorStop(1,d(D,0)),y.fillStyle=T,y.beginPath();const s=e/2;y.moveTo(g-t/2+s,b-s),y.lineTo(g+t/2-s,b-s),y.arc(g+t/2-s,b,s,-Math.PI/2,Math.PI/2),y.lineTo(g-t/2+s,b+s),y.arc(g-t/2+s,b,s,Math.PI/2,-Math.PI/2),y.closePath(),y.fill(),y.globalCompositeOperation="destination-in";const w=y.createLinearGradient(g-t/2,0,g+t/2,0);w.addColorStop(0,"rgba(0,0,0,0)"),w.addColorStop(.22,"rgba(0,0,0,1)"),w.addColorStop(.78,"rgba(0,0,0,1)"),w.addColorStop(1,"rgba(0,0,0,0)"),y.fillStyle=w,y.fillRect(0,0,dt,ht),at.push(C)}qt=it,zt=O.join(",")}function he(){at.length&&qt===it&&zt===O.join(",")||Ut()}function me(){if(!Mt)return;const t=Mt;t.clearRect(0,0,u,p),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${a} ${rt}px ${i}`,t.fillText(o,At,p*.5);const e=t.getImageData(0,0,u,p).data,r=new Uint8Array(u*p);for(let M=0;M<p;M++)for(let S=0;S<u;S++){const R=M*u+S,X=e[R*4+3]/255,U=oe(S*.5,M*.5)*.22+oe(S*1.8,M*1.8)*.1;r[R]=X>.5+(U-.16)?1:0}Ft=r;const f=Le(r,u,p),C=new Float32Array(u*p);for(let M=1;M<p-1;M++)for(let S=1;S<u-1;S++){const R=M*u+S;C[R]=(f[R]*4+f[R-1]+f[R+1]+f[R-u]+f[R+u])/8}const y=new Float32Array(u*p),g=new Float32Array(u*p),b=new Float32Array(u*p),T=new Float32Array(u*p);for(let M=1;M<p-1;M++)for(let S=1;S<u-1;S++){const R=M*u+S;if(!r[R])continue;const X=(C[R+1]-C[R-1])*.5,U=(C[R+u]-C[R-u])*.5;b[R]=X,T[R]=U,y[R]=X*X-U*U,g[R]=2*X*U}const d=Math.max(7,Math.round(p*.05)),s=ie(y,u,p,d,2),w=ie(g,u,p,d,2);pt=new Float32Array(u*p),wt=new Float32Array(u*p);for(let M=0;M<u*p;M++){if(!r[M])continue;const S=.5*Math.atan2(w[M],s[M]);pt[M]=Math.cos(S),wt[M]=Math.sin(S)}const I=Math.max(9,p*.04),N=new Float32Array(u*p),V=-.45,W=-.62,Y=.64;for(let M=1;M<p-1;M++)for(let S=1;S<u-1;S++){const R=M*u+S;if(!r[R])continue;let X=b[R],U=T[R];const Wt=Math.hypot(X,U)||1;X/=Wt,U/=Wt;const te=C[R],ee=(1-Math.min(te/I,1))*1.25;let Bt=-X*ee,Nt=-U*ee;const ne=1.5,jt=Math.hypot(Bt,Nt,ne);Bt/=jt,Nt/=jt;let Dt=Bt*V+Nt*W+ne/jt*Y;Dt<0&&(Dt=0);const Fe=Math.min(1,.45+.55*Math.min(te/(I*.7),1));N[R]=Math.min(1.12,(.5+.75*Dt)*Fe)}Rt=N,Q=document.createElement("canvas"),Q.width=u,Q.height=p;const _=Q.getContext("2d");if(_){const M=_.createImageData(u,p);for(let S=0;S<u*p;S++)r[S]&&(M.data[S*4]=255,M.data[S*4+1]=255,M.data[S*4+2]=255,M.data[S*4+3]=255);_.putImageData(M,0,0)}}function xe(){const t=Math.max(1.6,it*.6);et=t;const e=[];for(let r=0;r<p;r+=t)for(let f=0;f<u;f+=t){const C=(ot(Math.floor(f),Math.floor(r))-.5)*t*.9,y=(ot(Math.floor(r),Math.floor(f))-.5)*t*.9,g=Math.round(f+C),b=Math.round(r+y);if(g<1||b<1||g>=u-1||b>=p-1)continue;const T=b*u+g;if(!Ft[T])continue;const d=Math.atan2(wt[T],pt[T]),s=.86+ot(g*7,b*13)*.18;let w=Rt[T]*s;w=w<0?0:w>1.12?1.12:w,e.push({x:g,y:b,ang:d,idx:Math.min(19,Math.max(0,Math.round(w/1.12*19)))})}mt=e}function Gt(t,e){t.save(),t.translate(e.x,e.y),t.rotate(e.ang),t.drawImage(at[e.idx],-dt/2,-ht/2),t.restore()}function $t(){const t=B.getContext("2d");if(t)for(const e of mt)Gt(t,e)}function It(){const t=B.getContext("2d");t&&t.clearRect(0,0,u,p)}function Kt(t){if(!t.length)return[];const e=Math.max(4,et*1.5),r=new Map,f=(d,s)=>d+","+s;t.forEach((d,s)=>{const w=f(Math.floor(d.x/e),Math.floor(d.y/e));let I=r.get(w);I||r.set(w,I=[]),I.push(s)});const C=et*1.8*(et*1.8);function y(d){const s=t[d],w=Math.floor(s.x/e),I=Math.floor(s.y/e),N=[];for(let V=-1;V<=1;V++)for(let W=-1;W<=1;W++){const Y=r.get(f(w+V,I+W));if(Y)for(const _ of Y){if(_===d)continue;const M=t[_].x-s.x,S=t[_].y-s.y;M*M+S*S<=C&&N.push(_)}}return N}const g=new Uint8Array(t.length),b=[],T=t.map((d,s)=>s).sort((d,s)=>t[d].x+t[d].y-(t[s].x+t[s].y));for(const d of T){if(g[d])continue;let s=[d];for(g[d]=1;s.length;){b.push(s.map(I=>t[I]));const w=[];for(const I of s)for(const N of y(I))g[N]||(g[N]=1,w.push(N));s=w}}return b}function ye(t){const e=Math.max(4,et*1.5),r=new Map,f=(T,d)=>T+","+d;t.forEach((T,d)=>{const s=f(Math.floor(T.x/e),Math.floor(T.y/e));let w=r.get(s);w||r.set(s,w=[]),w.push(d)});const C=et*1.8*(et*1.8),y=T=>{const d=t[T],s=Math.floor(d.x/e),w=Math.floor(d.y/e),I=[];for(let N=-1;N<=1;N++)for(let V=-1;V<=1;V++){const W=r.get(f(s+N,w+V));if(W)for(const Y of W){if(Y===T)continue;const _=t[Y].x-d.x,M=t[Y].y-d.y;_*_+M*M<=C&&I.push(Y)}}return I},g=new Uint8Array(t.length),b=[];for(let T=0;T<t.length;T++){if(g[T])continue;const d=[];let s=[T];for(g[T]=1;s.length;){const w=[];for(const I of s){d.push(t[I]);for(const N of y(I))g[N]||(g[N]=1,w.push(N))}s=w}b.push(d)}return b}function ge(t){if(!t.length)return[];const e=C=>{let y=1/0;for(const g of C)g.x<y&&(y=g.x);return y},r=ye(t).sort((C,y)=>e(C)-e(y)),f=[];for(const C of r){const y=Kt(C);y.sort((g,b)=>b.length-g.length);for(const g of y)f.push(g)}return f}function pe(){if(It(),gt||!P){$t(),$.on=!1;return}$.rows=F==="hand"?ge(mt):Kt(mt),$.idx=0,$.acc=0,$.rate=h,$.on=$.rows.length>0}function we(t){const e=B.getContext("2d");if(e)for(t>$.rows.length&&(t=$.rows.length);$.idx<t;){const r=$.rows[$.idx++];for(const f of r)Gt(e,f)}}function Me(t,e){const r=q.getContext("2d");if(!r||(r.clearRect(0,0,u,p),!E||!Q))return;const f=u*.32,C=r.createRadialGradient(t,e,0,t,e,f);C.addColorStop(0,"rgba(255,250,238,0.18)"),C.addColorStop(.5,"rgba(255,250,238,0.055)"),C.addColorStop(1,"rgba(255,250,238,0)"),r.fillStyle=C,r.fillRect(0,0,u,p),r.globalCompositeOperation="destination-in",r.drawImage(Q,0,0),r.globalCompositeOperation="source-over"}function Ce(){A||!c||(A=document.createElement("span"),A.className=St.caret,A.setAttribute("aria-hidden","true"),Object.assign(A.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${H(O[0])},${H(O[1])},${H(O[2])})`}),L.appendChild(A),G.push(A))}function Pt(){if(!c||!A)return;const t=B.getContext("2d");if(!t)return;t.font=`${a} ${rt}px ${i}`;const e=t.measureText(o).width,r=(B.clientWidth||u)/u,f=rt*.7;A.style.left=(At+e+rt*.05)*r+"px",A.style.top=.5*(B.clientHeight||p)-f*r/2+"px",A.style.height=f*r+"px",A.style.width=Math.max(2,Math.round(rt*.02*r))+"px",A.style.background=`rgb(${H(O[0])},${H(O[1])},${H(O[2])})`}function st(){z||xt||(xt=!0,yt=0,Lt=requestAnimationFrame(Vt))}function Vt(t){if(z){xt=!1;return}yt||(yt=t);const e=Math.min(.25,(t-yt)/1e3);yt=t,$.on&&($.acc+=$.rate*e,we($.acc),$.idx>=$.rows.length&&($.on=!1)),nt&&Q&&(Me(K.set?K.x:u*.5,K.set?K.y:p*.45),nt=!1);const r=c&&tt;if(A&&(A.style.opacity=r&&Math.floor(t/530)%2===0?"1":"0"),!$.on&&!nt&&!r){xt=!1;return}Lt=requestAnimationFrame(Vt)}function Ct(t){const e=L.getBoundingClientRect();K.x=(t.clientX-e.left)/(e.width||1)*u,K.y=(t.clientY-e.top)/(e.height||1)*p,K.set=!0,nt=!0,st()}function vt(){K.set=!1,nt=!0,st()}function ve(){v&&Ht(v.value,!0)}function Te(t){t.key==="Enter"&&(t.preventDefault(),Ot.replay())}function be(){tt=!0,st()}function Se(){tt=!1,A&&(A.style.opacity="0")}function Yt(t){t===c&&v||(c=t,t?(v||(v=document.createElement("input"),v.type="text",v.value=o,v.maxLength=64,v.setAttribute("aria-label","Embroidered text — type to change it"),v.setAttribute("autocomplete","off"),v.setAttribute("autocapitalize","off"),v.spellcheck=!1,Object.assign(v.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),v.addEventListener("input",ve),v.addEventListener("keydown",Te),v.addEventListener("focus",be),v.addEventListener("blur",Se),L.appendChild(v),G.push(v)),Ce(),Pt()):(v&&(v.remove(),v=null),tt=!1,A&&(A.style.opacity="0")))}function Ee(t){if(t!==E)if(E=t,t)L.addEventListener("pointermove",Ct,{passive:!0}),L.addEventListener("pointerleave",vt,{passive:!0}),K.set=!1,nt=!0,st();else{L.removeEventListener("pointermove",Ct),L.removeEventListener("pointerleave",vt);const e=q.getContext("2d");e&&e.clearRect(0,0,u,p)}}function ct(t){ue(),de(),he(),me(),xe(),t?pe():(It(),$t(),$.on=!1),v&&v.value!==o&&(v.value=o),Pt(),nt=!0,st()}function Ht(t,e){t=t??"",!(t===o&&Z)&&(o=t,Z&&(ct(!1),e&&k&&k(o)))}const Tt=new Set;function Jt(t,e,r){const f=`${e} 200px ${t}`;let C=!1;try{C=!!document.fonts&&document.fonts.check(f)}catch{C=!0}if(!document.fonts||C){r();return}let y=!1,g;const b=()=>{y||(y=!0,clearTimeout(g),Tt.delete(g),z||r())};document.fonts.load(f,o).then(()=>document.fonts.ready).then(b,b),g=setTimeout(b,1500),Tt.add(g)}function Ae(){z||(ct(!0),Z=!0)}c&&(c=!1,Yt(!0)),E&&(L.addEventListener("pointermove",Ct,{passive:!0}),L.addEventListener("pointerleave",vt,{passive:!0})),Jt(j,a,Ae);let kt,Qt=-1;function Zt(){clearTimeout(kt),kt=setTimeout(()=>{if(z||!Z)return;const t=Math.round(L.getBoundingClientRect().width);t!==Qt&&(Qt=t,ct(!1))},200)}window.addEventListener("resize",Zt);const Ot={get text(){return o},setText(t){if(!z){if(!Z){o=t??"",v&&(v.value=o);return}Ht(t,!1)}},replay(){z||!Z||ct(!0)},resize(){z||!Z||ct(!1)},update(t){if(z)return;t.text!==void 0&&Ot.setText(t.text);let e=!1,r=!1;if(t.font!==void 0&&t.font!==i&&(i=t.font,j=le(i),e=!0),t.weight!==void 0){const f=bt(t.weight,1,1e3);f!==a&&(a=f,e=!0)}if(t.fill!==void 0){const f=bt(t.fill,.05,1);f!==l&&(l=f,e=!0)}t.pitch!==void 0&&t.pitch!==m&&(m=t.pitch,e=!0),t.threadColor!==void 0&&(ut(t.threadColor),r=!0),t.sewRate!==void 0&&(h=Math.max(1,t.sewRate)),t.sewStyle!==void 0&&(F=t.sewStyle==="hand"?"hand":"machine"),t.animate!==void 0&&(P=t.animate),t.onTextChange!==void 0&&(k=t.onTextChange),t.sheen!==void 0&&Ee(t.sheen),t.editable!==void 0&&Yt(t.editable),Z&&(e?Jt(j,a,()=>{z||ct(!1)}):r&&(Ut(),It(),$t(),Pt(),st()))},focus(){!z&&c&&(v==null||v.focus())},destroy(){if(!z){z=!0,xt=!1,cancelAnimationFrame(Lt),clearTimeout(kt);for(const t of Tt)clearTimeout(t);Tt.clear(),window.removeEventListener("resize",Zt),L.removeEventListener("pointermove",Ct),L.removeEventListener("pointerleave",vt);for(const t of G)t.remove();at=[],mt=[],$.rows=[],Ft=new Uint8Array(0),Rt=new Float32Array(0),pt=new Float32Array(0),wt=new Float32Array(0),Q=lt=null,Mt=null,A=null,v=null}}};return Ot}function ce(x){const n=J.useRef(null),o=J.useRef(null),i=J.useRef(x);i.current=x;const a=J.useRef(x.onTextChange);a.current=x.onTextChange;const{text:l,font:h,weight:F,threadColor:E,pitch:P,fill:c,animate:m,sewStyle:k,sewRate:j,sheen:gt,editable:O,reducedMotion:ft}=x;return J.useLayoutEffect(()=>{const D=n.current;if(!D)return;const ut=se(D,{...i.current,onTextChange:v=>{var A;return(A=a.current)==null?void 0:A.call(a,v)}});o.current=ut;let G=0,B=0,L=!0,q;return typeof ResizeObserver<"u"&&(q=new ResizeObserver(v=>{const A=Math.round(v[0].contentRect.width);if(L){L=!1,B=A;return}A!==B&&(B=A,cancelAnimationFrame(G),G=requestAnimationFrame(()=>{var tt;return(tt=o.current)==null?void 0:tt.resize()}))}),q.observe(D)),()=>{q==null||q.disconnect(),cancelAnimationFrame(G),ut.destroy(),o.current=null}},[ft]),J.useEffect(()=>{var D;(D=o.current)==null||D.update({font:h,weight:F,threadColor:E,pitch:P,fill:c,animate:m,sewStyle:k,sewRate:j,sheen:gt,editable:O})},[h,F,E,P,c,m,k,j,gt,O]),J.useEffect(()=>{var D;(D=o.current)==null||D.setText(l)},[l]),n}const fe=J.forwardRef(function({className:n,style:o,as:i="div","aria-label":a,role:l,"aria-describedby":h,...F},E){const P=ce(F),c=J.useCallback(m=>{P.current=m,typeof E=="function"?E(m):E&&(E.current=m)},[P,E]);return Re.jsx(i,{ref:c,className:n,style:o,role:F.editable?l:l??"img","aria-label":F.editable?a:a??F.text,"aria-describedby":h})});fe.displayName="ThreadText";exports.THREAD_TEXT_CLASSES=St;exports.ThreadText=fe;exports.createThreadText=se;exports.useThreadText=ce;
package/dist/index.d.ts CHANGED
@@ -77,7 +77,16 @@ export declare interface ThreadTextOptions {
77
77
  fill?: number;
78
78
  /** Play the sew-in animation on mount and on `replay()`. (default: true) */
79
79
  animate?: boolean;
80
- /** Satin cross-rows laid per second during the sew-in. (default: 110) */
80
+ /**
81
+ * How the word is sewn in:
82
+ * - **'machine'** (default) — satin cross-rows appear in parallel across each stroke, like
83
+ * machine embroidery (a BFS over the stitch graph).
84
+ * - **'hand'** — works one letter at a time (left to right), laying the longest threads
85
+ * (the widest satin cross-rows) first, then the thin serifs and terminals — the way a
86
+ * person establishes the body of a shape before the details.
87
+ */
88
+ sewStyle?: 'machine' | 'hand';
89
+ /** Satin cross-rows (machine) or stitches (hand) laid per second during the sew-in. (default: 110) */
81
90
  sewRate?: number;
82
91
  /** Enable the cursor-following radial sheen on the overlay canvas. (default: true) */
83
92
  sheen?: boolean;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { useRef as vt, useLayoutEffect as Te, useEffect as ee, forwardRef as Ae, useCallback as Ee } from "react";
2
- import { jsx as Se } from "react/jsx-runtime";
1
+ import { useRef as bt, useLayoutEffect as Ae, useEffect as oe, forwardRef as Fe, useCallback as Le } from "react";
2
+ import { jsx as Re } from "react/jsx-runtime";
3
3
  const Dt = {
4
4
  /** Base canvas: the baked satin stitches (transparent ground). */
5
5
  bg: "tt-bg",
@@ -8,98 +8,98 @@ const Dt = {
8
8
  /** Blinking text caret shown in editable mode. */
9
9
  caret: "tt-caret"
10
10
  };
11
- function H(h, e) {
12
- let n = Math.imul(h | 0, 374761393) + Math.imul(e | 0, 668265263) | 0;
13
- return n = Math.imul(n ^ n >>> 13, 1274126177), ((n ^ n >>> 16) >>> 0) / 4294967295;
11
+ function nt(x, n) {
12
+ let o = Math.imul(x | 0, 374761393) + Math.imul(n | 0, 668265263) | 0;
13
+ return o = Math.imul(o ^ o >>> 13, 1274126177), ((o ^ o >>> 16) >>> 0) / 4294967295;
14
14
  }
15
- function ne(h, e) {
16
- const n = Math.floor(h), r = Math.floor(e), i = h - n, a = e - r, u = i * i * (3 - 2 * i), b = a * a * (3 - 2 * a), S = H(n, r), A = H(n + 1, r), c = H(n, r + 1), m = H(n + 1, r + 1);
17
- return S + (A - S) * u + (c - S) * b + (S - A - c + m) * u * b;
15
+ function re(x, n) {
16
+ const o = Math.floor(x), i = Math.floor(n), a = x - o, l = n - i, h = a * a * (3 - 2 * a), F = l * l * (3 - 2 * l), S = nt(o, i), P = nt(o + 1, i), s = nt(o, i + 1), m = nt(o + 1, i + 1);
17
+ return S + (P - S) * h + (s - S) * F + (S - P - s + m) * h * F;
18
18
  }
19
- const Tt = 1e20;
20
- function oe(h, e, n, r, i) {
21
- let a = 0;
22
- r[0] = 0, i[0] = -Tt, i[1] = Tt;
23
- for (let u = 1; u < e; u++) {
24
- let b = (h[u] + u * u - (h[r[a]] + r[a] * r[a])) / (2 * u - 2 * r[a]);
25
- for (; b <= i[a]; )
26
- a--, b = (h[u] + u * u - (h[r[a]] + r[a] * r[a])) / (2 * u - 2 * r[a]);
27
- a++, r[a] = u, i[a] = b, i[a + 1] = Tt;
28
- }
29
- a = 0;
30
- for (let u = 0; u < e; u++) {
31
- for (; i[a + 1] < u; ) a++;
32
- n[u] = (u - r[a]) * (u - r[a]) + h[r[a]];
19
+ const Et = 1e20;
20
+ function ie(x, n, o, i, a) {
21
+ let l = 0;
22
+ i[0] = 0, a[0] = -Et, a[1] = Et;
23
+ for (let h = 1; h < n; h++) {
24
+ let F = (x[h] + h * h - (x[i[l]] + i[l] * i[l])) / (2 * h - 2 * i[l]);
25
+ for (; F <= a[l]; )
26
+ l--, F = (x[h] + h * h - (x[i[l]] + i[l] * i[l])) / (2 * h - 2 * i[l]);
27
+ l++, i[l] = h, a[l] = F, a[l + 1] = Et;
28
+ }
29
+ l = 0;
30
+ for (let h = 0; h < n; h++) {
31
+ for (; a[l + 1] < h; ) l++;
32
+ o[h] = (h - i[l]) * (h - i[l]) + x[i[l]];
33
33
  }
34
34
  }
35
- function Fe(h, e, n) {
36
- const r = new Float64Array(e * n);
37
- for (let c = 0; c < e * n; c++) r[c] = h[c] ? Tt : 0;
38
- const i = Math.max(e, n), a = new Float64Array(i), u = new Float64Array(i), b = new Int32Array(i), S = new Float64Array(i + 1);
39
- for (let c = 0; c < e; c++) {
40
- for (let m = 0; m < n; m++) a[m] = r[m * e + c];
41
- oe(a, n, u, b, S);
42
- for (let m = 0; m < n; m++) r[m * e + c] = u[m];
43
- }
44
- for (let c = 0; c < n; c++) {
45
- for (let m = 0; m < e; m++) a[m] = r[c * e + m];
46
- oe(a, e, u, b, S);
47
- for (let m = 0; m < e; m++) r[c * e + m] = u[m];
48
- }
49
- const A = new Float32Array(e * n);
50
- for (let c = 0; c < e * n; c++) A[c] = Math.sqrt(r[c]);
51
- return A;
35
+ function $e(x, n, o) {
36
+ const i = new Float64Array(n * o);
37
+ for (let s = 0; s < n * o; s++) i[s] = x[s] ? Et : 0;
38
+ const a = Math.max(n, o), l = new Float64Array(a), h = new Float64Array(a), F = new Int32Array(a), S = new Float64Array(a + 1);
39
+ for (let s = 0; s < n; s++) {
40
+ for (let m = 0; m < o; m++) l[m] = i[m * n + s];
41
+ ie(l, o, h, F, S);
42
+ for (let m = 0; m < o; m++) i[m * n + s] = h[m];
43
+ }
44
+ for (let s = 0; s < o; s++) {
45
+ for (let m = 0; m < n; m++) l[m] = i[s * n + m];
46
+ ie(l, n, h, F, S);
47
+ for (let m = 0; m < n; m++) i[s * n + m] = h[m];
48
+ }
49
+ const P = new Float32Array(n * o);
50
+ for (let s = 0; s < n * o; s++) P[s] = Math.sqrt(i[s]);
51
+ return P;
52
52
  }
53
- function re(h, e, n, r, i) {
54
- let a = Float32Array.from(h);
55
- const u = new Float32Array(e * n), b = 1 / (2 * r + 1), S = (A, c) => A < 0 ? 0 : A > c ? c : A;
56
- for (let A = 0; A < i; A++) {
57
- for (let c = 0; c < n; c++) {
58
- const m = c * e;
59
- let I = 0;
60
- for (let O = -r; O <= r; O++) I += a[m + S(O, e - 1)];
61
- for (let O = 0; O < e; O++)
62
- u[m + O] = I * b, I += a[m + S(O + r + 1, e - 1)] - a[m + S(O - r, e - 1)];
53
+ function ae(x, n, o, i, a) {
54
+ let l = Float32Array.from(x);
55
+ const h = new Float32Array(n * o), F = 1 / (2 * i + 1), S = (P, s) => P < 0 ? 0 : P > s ? s : P;
56
+ for (let P = 0; P < a; P++) {
57
+ for (let s = 0; s < o; s++) {
58
+ const m = s * n;
59
+ let k = 0;
60
+ for (let j = -i; j <= i; j++) k += l[m + S(j, n - 1)];
61
+ for (let j = 0; j < n; j++)
62
+ h[m + j] = k * F, k += l[m + S(j + i + 1, n - 1)] - l[m + S(j - i, n - 1)];
63
63
  }
64
- for (let c = 0; c < e; c++) {
64
+ for (let s = 0; s < n; s++) {
65
65
  let m = 0;
66
- for (let I = -r; I <= r; I++) m += u[S(I, n - 1) * e + c];
67
- for (let I = 0; I < n; I++)
68
- a[I * e + c] = m * b, m += u[S(I + r + 1, n - 1) * e + c] - u[S(I - r, n - 1) * e + c];
66
+ for (let k = -i; k <= i; k++) m += h[S(k, o - 1) * n + s];
67
+ for (let k = 0; k < o; k++)
68
+ l[k * n + s] = m * F, m += h[S(k + i + 1, o - 1) * n + s] - h[S(k - i, o - 1) * n + s];
69
69
  }
70
70
  }
71
- return a;
71
+ return l;
72
72
  }
73
- function ie(h, e) {
74
- if (!h) return e;
75
- const n = h.trim();
76
- if (n[0] === "#") {
77
- let i = n.slice(1);
78
- if (i.length === 3 && (i = i[0] + i[0] + i[1] + i[1] + i[2] + i[2]), i.length >= 6) {
79
- const a = parseInt(i.slice(0, 2), 16), u = parseInt(i.slice(2, 4), 16), b = parseInt(i.slice(4, 6), 16);
80
- if (!Number.isNaN(a) && !Number.isNaN(u) && !Number.isNaN(b)) return [a, u, b];
73
+ function le(x, n) {
74
+ if (!x) return n;
75
+ const o = x.trim();
76
+ if (o[0] === "#") {
77
+ let a = o.slice(1);
78
+ if (a.length === 3 && (a = a[0] + a[0] + a[1] + a[1] + a[2] + a[2]), a.length >= 6) {
79
+ const l = parseInt(a.slice(0, 2), 16), h = parseInt(a.slice(2, 4), 16), F = parseInt(a.slice(4, 6), 16);
80
+ if (!Number.isNaN(l) && !Number.isNaN(h) && !Number.isNaN(F)) return [l, h, F];
81
81
  }
82
- return e;
82
+ return n;
83
83
  }
84
- const r = n.match(/rgba?\(([^)]+)\)/i);
85
- if (r) {
86
- const i = r[1].split(",").map((a) => parseFloat(a));
87
- if (i.length >= 3 && i.slice(0, 3).every((a) => !Number.isNaN(a)))
88
- return [Math.round(i[0]), Math.round(i[1]), Math.round(i[2])];
84
+ const i = o.match(/rgba?\(([^)]+)\)/i);
85
+ if (i) {
86
+ const a = i[1].split(",").map((l) => parseFloat(l));
87
+ if (a.length >= 3 && a.slice(0, 3).every((l) => !Number.isNaN(l)))
88
+ return [Math.round(a[0]), Math.round(a[1]), Math.round(a[2])];
89
89
  }
90
- return e;
90
+ return n;
91
91
  }
92
- function K(h) {
93
- return h < 0 ? 0 : h > 255 ? 255 : Math.round(h);
92
+ function H(x) {
93
+ return x < 0 ? 0 : x > 255 ? 255 : Math.round(x);
94
94
  }
95
- function bt(h, e, n) {
96
- return h < e ? e : h > n ? n : h;
95
+ function Tt(x, n, o) {
96
+ return x < n ? n : x > o ? o : x;
97
97
  }
98
- function ae(h) {
99
- return (h.split(",")[0] || "serif").trim().replace(/^["']|["']$/g, "");
98
+ function ce(x) {
99
+ return (x.split(",")[0] || "serif").trim().replace(/^["']|["']$/g, "");
100
100
  }
101
- function Le(h, e) {
102
- if (typeof window > "u" || typeof document > "u" || !h)
101
+ function Ie(x, n) {
102
+ if (typeof window > "u" || typeof document > "u" || !x)
103
103
  return { setText() {
104
104
  }, replay() {
105
105
  }, resize() {
@@ -107,420 +107,470 @@ function Le(h, e) {
107
107
  }, focus() {
108
108
  }, destroy() {
109
109
  }, get text() {
110
- return e.text ?? "";
110
+ return n.text ?? "";
111
111
  } };
112
- let n = e.text ?? "", r = e.font ?? "Georgia, serif", i = bt(e.weight ?? 680, 1, 1e3), a = bt(e.fill ?? 0.9, 0.05, 1), u = Math.max(1, e.sewRate ?? 110), b = e.sheen ?? !0, S = e.animate ?? !0, A = e.editable ?? !1, c = e.pitch, m = e.onTextChange, I = ae(r);
113
- const O = e.reducedMotion ?? !!(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
114
- let B = ie(e.threadColor ?? "#fffbf3", [255, 251, 243]), it = [0, 0, 0], D = [0, 0, 0];
115
- function at(t) {
116
- B = ie(t, [255, 251, 243]), it = [B[0] * 0.585, B[1] * 0.585, B[2] * 0.585], D = [B[0] * 0.47, B[1] * 0.47, B[2] * 0.47];
117
- }
118
- at(e.threadColor ?? "#fffbf3");
119
- const U = [];
120
- let k, R;
121
- h instanceof HTMLCanvasElement ? (k = h, R = h.parentElement ?? h) : (R = h, k = document.createElement("canvas"), U.push(k), R.appendChild(k)), k.classList.add(Dt.bg);
122
- const j = document.createElement("canvas");
123
- U.push(j), j.classList.add(Dt.fx), R.appendChild(j), getComputedStyle(R).position === "static" && (R.style.position = "relative"), k.style.display = "block", k.style.width = "100%", Object.assign(j.style, { position: "absolute", inset: "0", width: "100%", pointerEvents: "none", mixBlendMode: "screen" });
124
- let y = null, E = null, Q = !1, s = 0, x = 0, W = 0, At = 0, tt = 4, et = [], lt = 0, st = 0, jt = -1, zt = "", qt = -1, _t = -1, Et = new Uint8Array(0), St = new Float32Array(0), ht = new Float32Array(0), mt = new Float32Array(0), V = null, nt = null, xt = null, yt = [], gt = 3;
125
- const $ = { rows: [], idx: 0, acc: 0, rate: 0, on: !1 }, X = { x: 0, y: 0, set: !1 };
126
- let Z = !0, Ft = 0, ct = !1, ft = 0, z = !1, Y = !1;
127
- function le() {
128
- const t = R.getBoundingClientRect(), o = Math.max(1, Math.round(t.width || Math.min(window.innerWidth * 0.95, 1240))), l = n || "Ag", f = k.getContext("2d");
112
+ let o = n.text ?? "", i = n.font ?? "Georgia, serif", a = Tt(n.weight ?? 680, 1, 1e3), l = Tt(n.fill ?? 0.9, 0.05, 1), h = Math.max(1, n.sewRate ?? 110), F = n.sewStyle === "hand" ? "hand" : "machine", S = n.sheen ?? !0, P = n.animate ?? !0, s = n.editable ?? !1, m = n.pitch, k = n.onTextChange, j = ce(i);
113
+ const yt = n.reducedMotion ?? !!(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
114
+ let B = le(n.threadColor ?? "#fffbf3", [255, 251, 243]), st = [0, 0, 0], D = [0, 0, 0];
115
+ function ft(t) {
116
+ B = le(t, [255, 251, 243]), st = [B[0] * 0.585, B[1] * 0.585, B[2] * 0.585], D = [B[0] * 0.47, B[1] * 0.47, B[2] * 0.47];
117
+ }
118
+ ft(n.threadColor ?? "#fffbf3");
119
+ const G = [];
120
+ let O, R;
121
+ x instanceof HTMLCanvasElement ? (O = x, R = x.parentElement ?? x) : (R = x, O = document.createElement("canvas"), G.push(O), R.appendChild(O)), O.classList.add(Dt.bg);
122
+ const z = document.createElement("canvas");
123
+ G.push(z), z.classList.add(Dt.fx), R.appendChild(z), getComputedStyle(R).position === "static" && (R.style.position = "relative"), O.style.display = "block", O.style.width = "100%", Object.assign(z.style, { position: "absolute", inset: "0", width: "100%", pointerEvents: "none", mixBlendMode: "screen" });
124
+ let v = null, A = null, W = !1, u = 0, p = 0, ot = 0, St = 0, rt = 4, it = [], ut = 0, dt = 0, zt = -1, qt = "", _t = -1, Ut = -1, At = new Uint8Array(0), Ft = new Float32Array(0), gt = new Float32Array(0), pt = new Float32Array(0), J = null, at = null, wt = null, ht = [], tt = 3;
125
+ const $ = { rows: [], idx: 0, acc: 0, rate: 0, on: !1 }, K = { x: 0, y: 0, set: !1 };
126
+ let et = !0, Lt = 0, mt = !1, xt = 0, q = !1, Q = !1;
127
+ function se() {
128
+ const t = R.getBoundingClientRect(), e = Math.max(1, Math.round(t.width || Math.min(window.innerWidth * 0.95, 1240))), r = o || "Ag", f = O.getContext("2d");
129
129
  f && (f.textBaseline = "middle");
130
- let T = 100;
131
- f && (f.font = `${i} 100px ${r}`, T = f.measureText(l).width || 100);
132
- const C = Math.max(8, 100 * (o * a) / T);
133
- let v = C * 0.62, F = C * 0.62, P = o * a;
130
+ let C = 100;
131
+ f && (f.font = `${a} 100px ${i}`, C = f.measureText(r).width || 100);
132
+ const y = Math.max(8, 100 * (e * l) / C);
133
+ let g = y * 0.62, T = y * 0.62, b = e * l;
134
134
  if (f) {
135
- f.font = `${i} ${C}px ${r}`;
136
- const w = f.measureText(l);
137
- P = w.width || P, w.actualBoundingBoxAscent > 0 && (v = w.actualBoundingBoxAscent), w.actualBoundingBoxDescent > 0 && (F = w.actualBoundingBoxDescent);
135
+ f.font = `${a} ${y}px ${i}`;
136
+ const w = f.measureText(r);
137
+ b = w.width || b, w.actualBoundingBoxAscent > 0 && (g = w.actualBoundingBoxAscent), w.actualBoundingBoxDescent > 0 && (T = w.actualBoundingBoxDescent);
138
138
  }
139
- const p = Math.max(1, Math.round(2 * Math.max(v, F) * 1.1));
140
- let d = Math.min(window.devicePixelRatio || 1, 1.7);
141
- for (; o * d * p * d > 9e5 && d > 0.4; ) d -= 0.1;
142
- s = Math.max(1, Math.round(o * d)), x = Math.max(1, Math.round(p * d)), W = Math.max(4, Math.round(C * d)), At = Math.round(s / 2 - P * d / 2);
143
- for (const w of [k, j])
144
- w.width = s, w.height = x, w.style.height = p + "px";
145
- R.style.height = p + "px", tt = c ?? Math.max(3, x * 95e-4);
139
+ const d = Math.max(1, Math.round(2 * Math.max(g, T) * 1.1));
140
+ let c = Math.min(window.devicePixelRatio || 1, 1.7);
141
+ for (; e * c * d * c > 9e5 && c > 0.4; ) c -= 0.1;
142
+ u = Math.max(1, Math.round(e * c)), p = Math.max(1, Math.round(d * c)), ot = Math.max(4, Math.round(y * c)), St = Math.round(u / 2 - b * c / 2);
143
+ for (const w of [O, z])
144
+ w.width = u, w.height = p, w.style.height = d + "px";
145
+ R.style.height = d + "px", rt = m ?? Math.max(3, p * 95e-4);
146
146
  }
147
- function se() {
148
- nt && qt === s && _t === x || (nt = document.createElement("canvas"), nt.width = s, nt.height = x, xt = nt.getContext("2d", { willReadFrequently: !0 }), qt = s, _t = x);
149
- }
150
- function Gt() {
151
- const t = Math.max(7, tt * 2.5), o = Math.max(3.2, tt * 1.3);
152
- lt = Math.ceil(t) + 2, st = Math.ceil(o) + 2, et = [];
153
- for (let l = 0; l < 20; l++) {
154
- const f = 0.34 + l / 19 * 0.82, T = document.createElement("canvas");
155
- T.width = lt, T.height = st;
156
- const C = T.getContext("2d");
157
- if (!C) {
158
- et.push(T);
147
+ function fe() {
148
+ at && _t === u && Ut === p || (at = document.createElement("canvas"), at.width = u, at.height = p, wt = at.getContext("2d", { willReadFrequently: !0 }), _t = u, Ut = p);
149
+ }
150
+ function Xt() {
151
+ const t = Math.max(7, rt * 2.5), e = Math.max(3.2, rt * 1.3);
152
+ ut = Math.ceil(t) + 2, dt = Math.ceil(e) + 2, it = [];
153
+ for (let r = 0; r < 20; r++) {
154
+ const f = 0.34 + r / 19 * 0.82, C = document.createElement("canvas");
155
+ C.width = ut, C.height = dt;
156
+ const y = C.getContext("2d");
157
+ if (!y) {
158
+ it.push(C);
159
159
  continue;
160
160
  }
161
- const v = lt / 2, F = st / 2, P = C.createLinearGradient(0, F - o / 2, 0, F + o / 2), p = (N, q) => `rgba(${K(N[0] * f)},${K(N[1] * f)},${K(N[2] * f)},${q})`;
162
- P.addColorStop(0, p(D, 0)), P.addColorStop(0.16, p(it, 1)), P.addColorStop(0.5, p(B, 1)), P.addColorStop(0.84, p(it, 1)), P.addColorStop(1, p(D, 0)), C.fillStyle = P, C.beginPath();
163
- const d = o / 2;
164
- C.moveTo(v - t / 2 + d, F - d), C.lineTo(v + t / 2 - d, F - d), C.arc(v + t / 2 - d, F, d, -Math.PI / 2, Math.PI / 2), C.lineTo(v - t / 2 + d, F + d), C.arc(v - t / 2 + d, F, d, Math.PI / 2, -Math.PI / 2), C.closePath(), C.fill(), C.globalCompositeOperation = "destination-in";
165
- const w = C.createLinearGradient(v - t / 2, 0, v + t / 2, 0);
166
- w.addColorStop(0, "rgba(0,0,0,0)"), w.addColorStop(0.22, "rgba(0,0,0,1)"), w.addColorStop(0.78, "rgba(0,0,0,1)"), w.addColorStop(1, "rgba(0,0,0,0)"), C.fillStyle = w, C.fillRect(0, 0, lt, st), et.push(T);
161
+ const g = ut / 2, T = dt / 2, b = y.createLinearGradient(0, T - e / 2, 0, T + e / 2), d = (I, N) => `rgba(${H(I[0] * f)},${H(I[1] * f)},${H(I[2] * f)},${N})`;
162
+ b.addColorStop(0, d(D, 0)), b.addColorStop(0.16, d(st, 1)), b.addColorStop(0.5, d(B, 1)), b.addColorStop(0.84, d(st, 1)), b.addColorStop(1, d(D, 0)), y.fillStyle = b, y.beginPath();
163
+ const c = e / 2;
164
+ y.moveTo(g - t / 2 + c, T - c), y.lineTo(g + t / 2 - c, T - c), y.arc(g + t / 2 - c, T, c, -Math.PI / 2, Math.PI / 2), y.lineTo(g - t / 2 + c, T + c), y.arc(g - t / 2 + c, T, c, Math.PI / 2, -Math.PI / 2), y.closePath(), y.fill(), y.globalCompositeOperation = "destination-in";
165
+ const w = y.createLinearGradient(g - t / 2, 0, g + t / 2, 0);
166
+ w.addColorStop(0, "rgba(0,0,0,0)"), w.addColorStop(0.22, "rgba(0,0,0,1)"), w.addColorStop(0.78, "rgba(0,0,0,1)"), w.addColorStop(1, "rgba(0,0,0,0)"), y.fillStyle = w, y.fillRect(0, 0, ut, dt), it.push(C);
167
167
  }
168
- jt = tt, zt = B.join(",");
168
+ zt = rt, qt = B.join(",");
169
169
  }
170
- function ce() {
171
- et.length && jt === tt && zt === B.join(",") || Gt();
172
- }
173
- function fe() {
174
- if (!xt) return;
175
- const t = xt;
176
- t.clearRect(0, 0, s, x), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.font = `${i} ${W}px ${r}`, t.fillText(n, At, x * 0.5);
177
- const o = t.getImageData(0, 0, s, x).data, l = new Uint8Array(s * x);
178
- for (let g = 0; g < x; g++) for (let M = 0; M < s; M++) {
179
- const L = g * s + M, _ = o[L * 4 + 3] / 255, G = ne(M * 0.5, g * 0.5) * 0.22 + ne(M * 1.8, g * 1.8) * 0.1;
180
- l[L] = _ > 0.5 + (G - 0.16) ? 1 : 0;
170
+ function ue() {
171
+ it.length && zt === rt && qt === B.join(",") || Xt();
172
+ }
173
+ function de() {
174
+ if (!wt) return;
175
+ const t = wt;
176
+ t.clearRect(0, 0, u, p), t.fillStyle = "#fff", t.textAlign = "left", t.textBaseline = "middle", t.font = `${a} ${ot}px ${i}`, t.fillText(o, St, p * 0.5);
177
+ const e = t.getImageData(0, 0, u, p).data, r = new Uint8Array(u * p);
178
+ for (let M = 0; M < p; M++) for (let E = 0; E < u; E++) {
179
+ const L = M * u + E, U = e[L * 4 + 3] / 255, X = re(E * 0.5, M * 0.5) * 0.22 + re(E * 1.8, M * 1.8) * 0.1;
180
+ r[L] = U > 0.5 + (X - 0.16) ? 1 : 0;
181
181
  }
182
- Et = l;
183
- const f = Fe(l, s, x), T = new Float32Array(s * x);
184
- for (let g = 1; g < x - 1; g++) for (let M = 1; M < s - 1; M++) {
185
- const L = g * s + M;
186
- T[L] = (f[L] * 4 + f[L - 1] + f[L + 1] + f[L - s] + f[L + s]) / 8;
182
+ At = r;
183
+ const f = $e(r, u, p), C = new Float32Array(u * p);
184
+ for (let M = 1; M < p - 1; M++) for (let E = 1; E < u - 1; E++) {
185
+ const L = M * u + E;
186
+ C[L] = (f[L] * 4 + f[L - 1] + f[L + 1] + f[L - u] + f[L + u]) / 8;
187
187
  }
188
- const C = new Float32Array(s * x), v = new Float32Array(s * x), F = new Float32Array(s * x), P = new Float32Array(s * x);
189
- for (let g = 1; g < x - 1; g++) for (let M = 1; M < s - 1; M++) {
190
- const L = g * s + M;
191
- if (!l[L]) continue;
192
- const _ = (T[L + 1] - T[L - 1]) * 0.5, G = (T[L + s] - T[L - s]) * 0.5;
193
- F[L] = _, P[L] = G, C[L] = _ * _ - G * G, v[L] = 2 * _ * G;
188
+ const y = new Float32Array(u * p), g = new Float32Array(u * p), T = new Float32Array(u * p), b = new Float32Array(u * p);
189
+ for (let M = 1; M < p - 1; M++) for (let E = 1; E < u - 1; E++) {
190
+ const L = M * u + E;
191
+ if (!r[L]) continue;
192
+ const U = (C[L + 1] - C[L - 1]) * 0.5, X = (C[L + u] - C[L - u]) * 0.5;
193
+ T[L] = U, b[L] = X, y[L] = U * U - X * X, g[L] = 2 * U * X;
194
194
  }
195
- const p = Math.max(7, Math.round(x * 0.05)), d = re(C, s, x, p, 2), w = re(v, s, x, p, 2);
196
- ht = new Float32Array(s * x), mt = new Float32Array(s * x);
197
- for (let g = 0; g < s * x; g++) {
198
- if (!l[g]) continue;
199
- const M = 0.5 * Math.atan2(w[g], d[g]);
200
- ht[g] = Math.cos(M), mt[g] = Math.sin(M);
195
+ const d = Math.max(7, Math.round(p * 0.05)), c = ae(y, u, p, d, 2), w = ae(g, u, p, d, 2);
196
+ gt = new Float32Array(u * p), pt = new Float32Array(u * p);
197
+ for (let M = 0; M < u * p; M++) {
198
+ if (!r[M]) continue;
199
+ const E = 0.5 * Math.atan2(w[M], c[M]);
200
+ gt[M] = Math.cos(E), pt[M] = Math.sin(E);
201
201
  }
202
- const N = Math.max(9, x * 0.04), q = new Float32Array(s * x), ut = -0.45, dt = -0.62, Ct = 0.64;
203
- for (let g = 1; g < x - 1; g++) for (let M = 1; M < s - 1; M++) {
204
- const L = g * s + M;
205
- if (!l[L]) continue;
206
- let _ = F[L], G = P[L];
207
- const Zt = Math.hypot(_, G) || 1;
208
- _ /= Zt, G /= Zt;
209
- const Ht = T[L], Wt = (1 - Math.min(Ht / N, 1)) * 1.25;
210
- let Bt = -_ * Wt, kt = -G * Wt;
211
- const te = 1.5, Nt = Math.hypot(Bt, kt, te);
212
- Bt /= Nt, kt /= Nt;
213
- let Ot = Bt * ut + kt * dt + te / Nt * Ct;
214
- Ot < 0 && (Ot = 0);
215
- const be = Math.min(1, 0.45 + 0.55 * Math.min(Ht / (N * 0.7), 1));
216
- q[L] = Math.min(1.12, (0.5 + 0.75 * Ot) * be);
202
+ const I = Math.max(9, p * 0.04), N = new Float32Array(u * p), V = -0.45, Z = -0.62, Y = 0.64;
203
+ for (let M = 1; M < p - 1; M++) for (let E = 1; E < u - 1; E++) {
204
+ const L = M * u + E;
205
+ if (!r[L]) continue;
206
+ let U = T[L], X = b[L];
207
+ const Wt = Math.hypot(U, X) || 1;
208
+ U /= Wt, X /= Wt;
209
+ const te = C[L], ee = (1 - Math.min(te / I, 1)) * 1.25;
210
+ let Bt = -U * ee, Ot = -X * ee;
211
+ const ne = 1.5, Nt = Math.hypot(Bt, Ot, ne);
212
+ Bt /= Nt, Ot /= Nt;
213
+ let jt = Bt * V + Ot * Z + ne / Nt * Y;
214
+ jt < 0 && (jt = 0);
215
+ const Se = Math.min(1, 0.45 + 0.55 * Math.min(te / (I * 0.7), 1));
216
+ N[L] = Math.min(1.12, (0.5 + 0.75 * jt) * Se);
217
217
  }
218
- St = q, V = document.createElement("canvas"), V.width = s, V.height = x;
219
- const J = V.getContext("2d");
220
- if (J) {
221
- const g = J.createImageData(s, x);
222
- for (let M = 0; M < s * x; M++) l[M] && (g.data[M * 4] = 255, g.data[M * 4 + 1] = 255, g.data[M * 4 + 2] = 255, g.data[M * 4 + 3] = 255);
223
- J.putImageData(g, 0, 0);
218
+ Ft = N, J = document.createElement("canvas"), J.width = u, J.height = p;
219
+ const _ = J.getContext("2d");
220
+ if (_) {
221
+ const M = _.createImageData(u, p);
222
+ for (let E = 0; E < u * p; E++) r[E] && (M.data[E * 4] = 255, M.data[E * 4 + 1] = 255, M.data[E * 4 + 2] = 255, M.data[E * 4 + 3] = 255);
223
+ _.putImageData(M, 0, 0);
224
224
  }
225
225
  }
226
- function ue() {
227
- const t = Math.max(1.6, tt * 0.6);
228
- gt = t;
229
- const o = [];
230
- for (let l = 0; l < x; l += t) for (let f = 0; f < s; f += t) {
231
- const T = (H(Math.floor(f), Math.floor(l)) - 0.5) * t * 0.9, C = (H(Math.floor(l), Math.floor(f)) - 0.5) * t * 0.9, v = Math.round(f + T), F = Math.round(l + C);
232
- if (v < 1 || F < 1 || v >= s - 1 || F >= x - 1) continue;
233
- const P = F * s + v;
234
- if (!Et[P]) continue;
235
- const p = Math.atan2(mt[P], ht[P]), d = 0.86 + H(v * 7, F * 13) * 0.18;
236
- let w = St[P] * d;
237
- w = w < 0 ? 0 : w > 1.12 ? 1.12 : w, o.push({ x: v, y: F, ang: p, idx: Math.min(19, Math.max(0, Math.round(w / 1.12 * 19))) });
226
+ function he() {
227
+ const t = Math.max(1.6, rt * 0.6);
228
+ tt = t;
229
+ const e = [];
230
+ for (let r = 0; r < p; r += t) for (let f = 0; f < u; f += t) {
231
+ const C = (nt(Math.floor(f), Math.floor(r)) - 0.5) * t * 0.9, y = (nt(Math.floor(r), Math.floor(f)) - 0.5) * t * 0.9, g = Math.round(f + C), T = Math.round(r + y);
232
+ if (g < 1 || T < 1 || g >= u - 1 || T >= p - 1) continue;
233
+ const b = T * u + g;
234
+ if (!At[b]) continue;
235
+ const d = Math.atan2(pt[b], gt[b]), c = 0.86 + nt(g * 7, T * 13) * 0.18;
236
+ let w = Ft[b] * c;
237
+ w = w < 0 ? 0 : w > 1.12 ? 1.12 : w, e.push({ x: g, y: T, ang: d, idx: Math.min(19, Math.max(0, Math.round(w / 1.12 * 19))) });
238
238
  }
239
- yt = o;
239
+ ht = e;
240
240
  }
241
- function Ut(t, o) {
242
- t.save(), t.translate(o.x, o.y), t.rotate(o.ang), t.drawImage(et[o.idx], -lt / 2, -st / 2), t.restore();
241
+ function Gt(t, e) {
242
+ t.save(), t.translate(e.x, e.y), t.rotate(e.ang), t.drawImage(it[e.idx], -ut / 2, -dt / 2), t.restore();
243
243
  }
244
- function Lt() {
245
- const t = k.getContext("2d");
244
+ function Rt() {
245
+ const t = O.getContext("2d");
246
246
  if (t)
247
- for (const o of yt) Ut(t, o);
247
+ for (const e of ht) Gt(t, e);
248
248
  }
249
- function Rt() {
250
- const t = k.getContext("2d");
251
- t && t.clearRect(0, 0, s, x);
249
+ function $t() {
250
+ const t = O.getContext("2d");
251
+ t && t.clearRect(0, 0, u, p);
252
252
  }
253
- function de(t) {
253
+ function Kt(t) {
254
254
  if (!t.length) return [];
255
- const o = Math.max(4, gt * 1.5), l = /* @__PURE__ */ new Map(), f = (p, d) => p + "," + d;
256
- t.forEach((p, d) => {
257
- const w = f(Math.floor(p.x / o), Math.floor(p.y / o));
258
- let N = l.get(w);
259
- N || l.set(w, N = []), N.push(d);
255
+ const e = Math.max(4, tt * 1.5), r = /* @__PURE__ */ new Map(), f = (d, c) => d + "," + c;
256
+ t.forEach((d, c) => {
257
+ const w = f(Math.floor(d.x / e), Math.floor(d.y / e));
258
+ let I = r.get(w);
259
+ I || r.set(w, I = []), I.push(c);
260
260
  });
261
- const T = gt * 1.8 * (gt * 1.8);
262
- function C(p) {
263
- const d = t[p], w = Math.floor(d.x / o), N = Math.floor(d.y / o), q = [];
264
- for (let ut = -1; ut <= 1; ut++) for (let dt = -1; dt <= 1; dt++) {
265
- const Ct = l.get(f(w + ut, N + dt));
266
- if (Ct)
267
- for (const J of Ct) {
268
- if (J === p) continue;
269
- const g = t[J].x - d.x, M = t[J].y - d.y;
270
- g * g + M * M <= T && q.push(J);
261
+ const C = tt * 1.8 * (tt * 1.8);
262
+ function y(d) {
263
+ const c = t[d], w = Math.floor(c.x / e), I = Math.floor(c.y / e), N = [];
264
+ for (let V = -1; V <= 1; V++) for (let Z = -1; Z <= 1; Z++) {
265
+ const Y = r.get(f(w + V, I + Z));
266
+ if (Y)
267
+ for (const _ of Y) {
268
+ if (_ === d) continue;
269
+ const M = t[_].x - c.x, E = t[_].y - c.y;
270
+ M * M + E * E <= C && N.push(_);
271
271
  }
272
272
  }
273
- return q;
273
+ return N;
274
274
  }
275
- const v = new Uint8Array(t.length), F = [], P = t.map((p, d) => d).sort((p, d) => t[p].x + t[p].y - (t[d].x + t[d].y));
276
- for (const p of P) {
277
- if (v[p]) continue;
278
- let d = [p];
279
- for (v[p] = 1; d.length; ) {
280
- F.push(d.map((N) => t[N]));
275
+ const g = new Uint8Array(t.length), T = [], b = t.map((d, c) => c).sort((d, c) => t[d].x + t[d].y - (t[c].x + t[c].y));
276
+ for (const d of b) {
277
+ if (g[d]) continue;
278
+ let c = [d];
279
+ for (g[d] = 1; c.length; ) {
280
+ T.push(c.map((I) => t[I]));
281
281
  const w = [];
282
- for (const N of d) for (const q of C(N)) v[q] || (v[q] = 1, w.push(q));
283
- d = w;
282
+ for (const I of c) for (const N of y(I)) g[N] || (g[N] = 1, w.push(N));
283
+ c = w;
284
284
  }
285
285
  }
286
- return F;
286
+ return T;
287
287
  }
288
- function he() {
289
- if (Rt(), O || !S) {
290
- Lt(), $.on = !1;
288
+ function me(t) {
289
+ const e = Math.max(4, tt * 1.5), r = /* @__PURE__ */ new Map(), f = (b, d) => b + "," + d;
290
+ t.forEach((b, d) => {
291
+ const c = f(Math.floor(b.x / e), Math.floor(b.y / e));
292
+ let w = r.get(c);
293
+ w || r.set(c, w = []), w.push(d);
294
+ });
295
+ const C = tt * 1.8 * (tt * 1.8), y = (b) => {
296
+ const d = t[b], c = Math.floor(d.x / e), w = Math.floor(d.y / e), I = [];
297
+ for (let N = -1; N <= 1; N++) for (let V = -1; V <= 1; V++) {
298
+ const Z = r.get(f(c + N, w + V));
299
+ if (Z)
300
+ for (const Y of Z) {
301
+ if (Y === b) continue;
302
+ const _ = t[Y].x - d.x, M = t[Y].y - d.y;
303
+ _ * _ + M * M <= C && I.push(Y);
304
+ }
305
+ }
306
+ return I;
307
+ }, g = new Uint8Array(t.length), T = [];
308
+ for (let b = 0; b < t.length; b++) {
309
+ if (g[b]) continue;
310
+ const d = [];
311
+ let c = [b];
312
+ for (g[b] = 1; c.length; ) {
313
+ const w = [];
314
+ for (const I of c) {
315
+ d.push(t[I]);
316
+ for (const N of y(I)) g[N] || (g[N] = 1, w.push(N));
317
+ }
318
+ c = w;
319
+ }
320
+ T.push(d);
321
+ }
322
+ return T;
323
+ }
324
+ function xe(t) {
325
+ if (!t.length) return [];
326
+ const e = (C) => {
327
+ let y = 1 / 0;
328
+ for (const g of C) g.x < y && (y = g.x);
329
+ return y;
330
+ }, r = me(t).sort((C, y) => e(C) - e(y)), f = [];
331
+ for (const C of r) {
332
+ const y = Kt(C);
333
+ y.sort((g, T) => T.length - g.length);
334
+ for (const g of y) f.push(g);
335
+ }
336
+ return f;
337
+ }
338
+ function ye() {
339
+ if ($t(), yt || !P) {
340
+ Rt(), $.on = !1;
291
341
  return;
292
342
  }
293
- $.rows = de(yt), $.idx = 0, $.acc = 0, $.rate = u, $.on = $.rows.length > 0;
343
+ $.rows = F === "hand" ? xe(ht) : Kt(ht), $.idx = 0, $.acc = 0, $.rate = h, $.on = $.rows.length > 0;
294
344
  }
295
- function me(t) {
296
- const o = k.getContext("2d");
297
- if (o)
345
+ function ge(t) {
346
+ const e = O.getContext("2d");
347
+ if (e)
298
348
  for (t > $.rows.length && (t = $.rows.length); $.idx < t; ) {
299
- const l = $.rows[$.idx++];
300
- for (const f of l) Ut(o, f);
349
+ const r = $.rows[$.idx++];
350
+ for (const f of r) Gt(e, f);
301
351
  }
302
352
  }
303
- function xe(t, o) {
304
- const l = j.getContext("2d");
305
- if (!l || (l.clearRect(0, 0, s, x), !b || !V)) return;
306
- const f = s * 0.32, T = l.createRadialGradient(t, o, 0, t, o, f);
307
- T.addColorStop(0, "rgba(255,250,238,0.18)"), T.addColorStop(0.5, "rgba(255,250,238,0.055)"), T.addColorStop(1, "rgba(255,250,238,0)"), l.fillStyle = T, l.fillRect(0, 0, s, x), l.globalCompositeOperation = "destination-in", l.drawImage(V, 0, 0), l.globalCompositeOperation = "source-over";
353
+ function pe(t, e) {
354
+ const r = z.getContext("2d");
355
+ if (!r || (r.clearRect(0, 0, u, p), !S || !J)) return;
356
+ const f = u * 0.32, C = r.createRadialGradient(t, e, 0, t, e, f);
357
+ C.addColorStop(0, "rgba(255,250,238,0.18)"), C.addColorStop(0.5, "rgba(255,250,238,0.055)"), C.addColorStop(1, "rgba(255,250,238,0)"), r.fillStyle = C, r.fillRect(0, 0, u, p), r.globalCompositeOperation = "destination-in", r.drawImage(J, 0, 0), r.globalCompositeOperation = "source-over";
308
358
  }
309
- function ye() {
310
- E || !A || (E = document.createElement("span"), E.className = Dt.caret, E.setAttribute("aria-hidden", "true"), Object.assign(E.style, { position: "absolute", pointerEvents: "none", borderRadius: "1px", opacity: "0", background: `rgb(${K(B[0])},${K(B[1])},${K(B[2])})` }), R.appendChild(E), U.push(E));
359
+ function we() {
360
+ A || !s || (A = document.createElement("span"), A.className = Dt.caret, A.setAttribute("aria-hidden", "true"), Object.assign(A.style, { position: "absolute", pointerEvents: "none", borderRadius: "1px", opacity: "0", background: `rgb(${H(B[0])},${H(B[1])},${H(B[2])})` }), R.appendChild(A), G.push(A));
311
361
  }
312
- function $t() {
313
- if (!A || !E) return;
314
- const t = k.getContext("2d");
362
+ function It() {
363
+ if (!s || !A) return;
364
+ const t = O.getContext("2d");
315
365
  if (!t) return;
316
- t.font = `${i} ${W}px ${r}`;
317
- const o = t.measureText(n).width, l = (k.clientWidth || s) / s, f = W * 0.7;
318
- E.style.left = (At + o + W * 0.05) * l + "px", E.style.top = 0.5 * (k.clientHeight || x) - f * l / 2 + "px", E.style.height = f * l + "px", E.style.width = Math.max(2, Math.round(W * 0.02 * l)) + "px", E.style.background = `rgb(${K(B[0])},${K(B[1])},${K(B[2])})`;
366
+ t.font = `${a} ${ot}px ${i}`;
367
+ const e = t.measureText(o).width, r = (O.clientWidth || u) / u, f = ot * 0.7;
368
+ A.style.left = (St + e + ot * 0.05) * r + "px", A.style.top = 0.5 * (O.clientHeight || p) - f * r / 2 + "px", A.style.height = f * r + "px", A.style.width = Math.max(2, Math.round(ot * 0.02 * r)) + "px", A.style.background = `rgb(${H(B[0])},${H(B[1])},${H(B[2])})`;
319
369
  }
320
- function ot() {
321
- z || ct || (ct = !0, ft = 0, Ft = requestAnimationFrame(Xt));
370
+ function lt() {
371
+ q || mt || (mt = !0, xt = 0, Lt = requestAnimationFrame(Vt));
322
372
  }
323
- function Xt(t) {
324
- if (z) {
325
- ct = !1;
373
+ function Vt(t) {
374
+ if (q) {
375
+ mt = !1;
326
376
  return;
327
377
  }
328
- ft || (ft = t);
329
- const o = Math.min(0.25, (t - ft) / 1e3);
330
- ft = t, $.on && ($.acc += $.rate * o, me($.acc), $.idx >= $.rows.length && ($.on = !1)), Z && V && (xe(X.set ? X.x : s * 0.5, X.set ? X.y : x * 0.45), Z = !1);
331
- const l = A && Q;
332
- if (E && (E.style.opacity = l && Math.floor(t / 530) % 2 === 0 ? "1" : "0"), !$.on && !Z && !l) {
333
- ct = !1;
378
+ xt || (xt = t);
379
+ const e = Math.min(0.25, (t - xt) / 1e3);
380
+ xt = t, $.on && ($.acc += $.rate * e, ge($.acc), $.idx >= $.rows.length && ($.on = !1)), et && J && (pe(K.set ? K.x : u * 0.5, K.set ? K.y : p * 0.45), et = !1);
381
+ const r = s && W;
382
+ if (A && (A.style.opacity = r && Math.floor(t / 530) % 2 === 0 ? "1" : "0"), !$.on && !et && !r) {
383
+ mt = !1;
334
384
  return;
335
385
  }
336
- Ft = requestAnimationFrame(Xt);
386
+ Lt = requestAnimationFrame(Vt);
337
387
  }
338
- function pt(t) {
339
- const o = R.getBoundingClientRect();
340
- X.x = (t.clientX - o.left) / (o.width || 1) * s, X.y = (t.clientY - o.top) / (o.height || 1) * x, X.set = !0, Z = !0, ot();
388
+ function Mt(t) {
389
+ const e = R.getBoundingClientRect();
390
+ K.x = (t.clientX - e.left) / (e.width || 1) * u, K.y = (t.clientY - e.top) / (e.height || 1) * p, K.set = !0, et = !0, lt();
341
391
  }
342
- function wt() {
343
- X.set = !1, Z = !0, ot();
392
+ function Ct() {
393
+ K.set = !1, et = !0, lt();
344
394
  }
345
- function ge() {
346
- y && Vt(y.value, !0);
395
+ function Me() {
396
+ v && Ht(v.value, !0);
347
397
  }
348
- function pe(t) {
349
- t.key === "Enter" && (t.preventDefault(), Pt.replay());
398
+ function Ce(t) {
399
+ t.key === "Enter" && (t.preventDefault(), kt.replay());
350
400
  }
351
- function we() {
352
- Q = !0, ot();
401
+ function ve() {
402
+ W = !0, lt();
353
403
  }
354
- function Me() {
355
- Q = !1, E && (E.style.opacity = "0");
404
+ function be() {
405
+ W = !1, A && (A.style.opacity = "0");
356
406
  }
357
- function Kt(t) {
358
- t === A && y || (A = t, t ? (y || (y = document.createElement("input"), y.type = "text", y.value = n, y.maxLength = 64, y.setAttribute("aria-label", "Embroidered text — type to change it"), y.setAttribute("autocomplete", "off"), y.setAttribute("autocapitalize", "off"), y.spellcheck = !1, Object.assign(y.style, { position: "absolute", inset: "0", width: "100%", height: "100%", margin: "0", padding: "0", border: "0", outline: "none", background: "transparent", color: "transparent", caretColor: "transparent", font: "inherit", textAlign: "center", cursor: "text" }), y.addEventListener("input", ge), y.addEventListener("keydown", pe), y.addEventListener("focus", we), y.addEventListener("blur", Me), R.appendChild(y), U.push(y)), ye(), $t()) : (y && (y.remove(), y = null), Q = !1, E && (E.style.opacity = "0")));
407
+ function Yt(t) {
408
+ t === s && v || (s = t, t ? (v || (v = document.createElement("input"), v.type = "text", v.value = o, v.maxLength = 64, v.setAttribute("aria-label", "Embroidered text — type to change it"), v.setAttribute("autocomplete", "off"), v.setAttribute("autocapitalize", "off"), v.spellcheck = !1, Object.assign(v.style, { position: "absolute", inset: "0", width: "100%", height: "100%", margin: "0", padding: "0", border: "0", outline: "none", background: "transparent", color: "transparent", caretColor: "transparent", font: "inherit", textAlign: "center", cursor: "text" }), v.addEventListener("input", Me), v.addEventListener("keydown", Ce), v.addEventListener("focus", ve), v.addEventListener("blur", be), R.appendChild(v), G.push(v)), we(), It()) : (v && (v.remove(), v = null), W = !1, A && (A.style.opacity = "0")));
359
409
  }
360
- function Ce(t) {
361
- if (t !== b)
362
- if (b = t, t)
363
- R.addEventListener("pointermove", pt, { passive: !0 }), R.addEventListener("pointerleave", wt, { passive: !0 }), X.set = !1, Z = !0, ot();
410
+ function Te(t) {
411
+ if (t !== S)
412
+ if (S = t, t)
413
+ R.addEventListener("pointermove", Mt, { passive: !0 }), R.addEventListener("pointerleave", Ct, { passive: !0 }), K.set = !1, et = !0, lt();
364
414
  else {
365
- R.removeEventListener("pointermove", pt), R.removeEventListener("pointerleave", wt);
366
- const o = j.getContext("2d");
367
- o && o.clearRect(0, 0, s, x);
415
+ R.removeEventListener("pointermove", Mt), R.removeEventListener("pointerleave", Ct);
416
+ const e = z.getContext("2d");
417
+ e && e.clearRect(0, 0, u, p);
368
418
  }
369
419
  }
370
- function rt(t) {
371
- le(), se(), ce(), fe(), ue(), t ? he() : (Rt(), Lt(), $.on = !1), y && y.value !== n && (y.value = n), $t(), Z = !0, ot();
420
+ function ct(t) {
421
+ se(), fe(), ue(), de(), he(), t ? ye() : ($t(), Rt(), $.on = !1), v && v.value !== o && (v.value = o), It(), et = !0, lt();
372
422
  }
373
- function Vt(t, o) {
374
- t = t ?? "", !(t === n && Y) && (n = t, Y && (rt(!1), o && m && m(n)));
423
+ function Ht(t, e) {
424
+ t = t ?? "", !(t === o && Q) && (o = t, Q && (ct(!1), e && k && k(o)));
375
425
  }
376
- const Mt = /* @__PURE__ */ new Set();
377
- function Yt(t, o, l) {
378
- const f = `${o} 200px ${t}`;
379
- let T = !1;
426
+ const vt = /* @__PURE__ */ new Set();
427
+ function Jt(t, e, r) {
428
+ const f = `${e} 200px ${t}`;
429
+ let C = !1;
380
430
  try {
381
- T = !!document.fonts && document.fonts.check(f);
431
+ C = !!document.fonts && document.fonts.check(f);
382
432
  } catch {
383
- T = !0;
433
+ C = !0;
384
434
  }
385
- if (!document.fonts || T) {
386
- l();
435
+ if (!document.fonts || C) {
436
+ r();
387
437
  return;
388
438
  }
389
- let C = !1, v;
390
- const F = () => {
391
- C || (C = !0, clearTimeout(v), Mt.delete(v), z || l());
439
+ let y = !1, g;
440
+ const T = () => {
441
+ y || (y = !0, clearTimeout(g), vt.delete(g), q || r());
392
442
  };
393
- document.fonts.load(f, n).then(() => document.fonts.ready).then(F, F), v = setTimeout(F, 1500), Mt.add(v);
443
+ document.fonts.load(f, o).then(() => document.fonts.ready).then(T, T), g = setTimeout(T, 1500), vt.add(g);
394
444
  }
395
- function ve() {
396
- z || (rt(!0), Y = !0);
445
+ function Ee() {
446
+ q || (ct(!0), Q = !0);
397
447
  }
398
- A && (A = !1, Kt(!0)), b && (R.addEventListener("pointermove", pt, { passive: !0 }), R.addEventListener("pointerleave", wt, { passive: !0 })), Yt(I, i, ve);
399
- let It, Jt = -1;
400
- function Qt() {
401
- clearTimeout(It), It = setTimeout(() => {
402
- if (z || !Y) return;
448
+ s && (s = !1, Yt(!0)), S && (R.addEventListener("pointermove", Mt, { passive: !0 }), R.addEventListener("pointerleave", Ct, { passive: !0 })), Jt(j, a, Ee);
449
+ let Pt, Qt = -1;
450
+ function Zt() {
451
+ clearTimeout(Pt), Pt = setTimeout(() => {
452
+ if (q || !Q) return;
403
453
  const t = Math.round(R.getBoundingClientRect().width);
404
- t !== Jt && (Jt = t, rt(!1));
454
+ t !== Qt && (Qt = t, ct(!1));
405
455
  }, 200);
406
456
  }
407
- window.addEventListener("resize", Qt);
408
- const Pt = {
457
+ window.addEventListener("resize", Zt);
458
+ const kt = {
409
459
  get text() {
410
- return n;
460
+ return o;
411
461
  },
412
462
  setText(t) {
413
- if (!z) {
414
- if (!Y) {
415
- n = t ?? "", y && (y.value = n);
463
+ if (!q) {
464
+ if (!Q) {
465
+ o = t ?? "", v && (v.value = o);
416
466
  return;
417
467
  }
418
- Vt(t, !1);
468
+ Ht(t, !1);
419
469
  }
420
470
  },
421
471
  replay() {
422
- z || !Y || rt(!0);
472
+ q || !Q || ct(!0);
423
473
  },
424
474
  resize() {
425
- z || !Y || rt(!1);
475
+ q || !Q || ct(!1);
426
476
  },
427
477
  update(t) {
428
- if (z) return;
429
- t.text !== void 0 && Pt.setText(t.text);
430
- let o = !1, l = !1;
431
- if (t.font !== void 0 && t.font !== r && (r = t.font, I = ae(r), o = !0), t.weight !== void 0) {
432
- const f = bt(t.weight, 1, 1e3);
433
- f !== i && (i = f, o = !0);
478
+ if (q) return;
479
+ t.text !== void 0 && kt.setText(t.text);
480
+ let e = !1, r = !1;
481
+ if (t.font !== void 0 && t.font !== i && (i = t.font, j = ce(i), e = !0), t.weight !== void 0) {
482
+ const f = Tt(t.weight, 1, 1e3);
483
+ f !== a && (a = f, e = !0);
434
484
  }
435
485
  if (t.fill !== void 0) {
436
- const f = bt(t.fill, 0.05, 1);
437
- f !== a && (a = f, o = !0);
486
+ const f = Tt(t.fill, 0.05, 1);
487
+ f !== l && (l = f, e = !0);
438
488
  }
439
- t.pitch !== void 0 && t.pitch !== c && (c = t.pitch, o = !0), t.threadColor !== void 0 && (at(t.threadColor), l = !0), t.sewRate !== void 0 && (u = Math.max(1, t.sewRate)), t.animate !== void 0 && (S = t.animate), t.onTextChange !== void 0 && (m = t.onTextChange), t.sheen !== void 0 && Ce(t.sheen), t.editable !== void 0 && Kt(t.editable), Y && (o ? Yt(I, i, () => {
440
- z || rt(!1);
441
- }) : l && (Gt(), Rt(), Lt(), $t(), ot()));
489
+ t.pitch !== void 0 && t.pitch !== m && (m = t.pitch, e = !0), t.threadColor !== void 0 && (ft(t.threadColor), r = !0), t.sewRate !== void 0 && (h = Math.max(1, t.sewRate)), t.sewStyle !== void 0 && (F = t.sewStyle === "hand" ? "hand" : "machine"), t.animate !== void 0 && (P = t.animate), t.onTextChange !== void 0 && (k = t.onTextChange), t.sheen !== void 0 && Te(t.sheen), t.editable !== void 0 && Yt(t.editable), Q && (e ? Jt(j, a, () => {
490
+ q || ct(!1);
491
+ }) : r && (Xt(), $t(), Rt(), It(), lt()));
442
492
  },
443
493
  focus() {
444
- !z && A && (y == null || y.focus());
494
+ !q && s && (v == null || v.focus());
445
495
  },
446
496
  destroy() {
447
- if (!z) {
448
- z = !0, ct = !1, cancelAnimationFrame(Ft), clearTimeout(It);
449
- for (const t of Mt) clearTimeout(t);
450
- Mt.clear(), window.removeEventListener("resize", Qt), R.removeEventListener("pointermove", pt), R.removeEventListener("pointerleave", wt);
451
- for (const t of U) t.remove();
452
- et = [], yt = [], $.rows = [], Et = new Uint8Array(0), St = new Float32Array(0), ht = new Float32Array(0), mt = new Float32Array(0), V = nt = null, xt = null, E = null, y = null;
497
+ if (!q) {
498
+ q = !0, mt = !1, cancelAnimationFrame(Lt), clearTimeout(Pt);
499
+ for (const t of vt) clearTimeout(t);
500
+ vt.clear(), window.removeEventListener("resize", Zt), R.removeEventListener("pointermove", Mt), R.removeEventListener("pointerleave", Ct);
501
+ for (const t of G) t.remove();
502
+ it = [], ht = [], $.rows = [], At = new Uint8Array(0), Ft = new Float32Array(0), gt = new Float32Array(0), pt = new Float32Array(0), J = at = null, wt = null, A = null, v = null;
453
503
  }
454
504
  }
455
505
  };
456
- return Pt;
506
+ return kt;
457
507
  }
458
- function Re(h) {
459
- const e = vt(null), n = vt(null), r = vt(h);
460
- r.current = h;
461
- const i = vt(h.onTextChange);
462
- i.current = h.onTextChange;
463
- const { text: a, font: u, weight: b, threadColor: S, pitch: A, fill: c, animate: m, sewRate: I, sheen: O, editable: B, reducedMotion: it } = h;
464
- return Te(() => {
465
- const D = e.current;
508
+ function Pe(x) {
509
+ const n = bt(null), o = bt(null), i = bt(x);
510
+ i.current = x;
511
+ const a = bt(x.onTextChange);
512
+ a.current = x.onTextChange;
513
+ const { text: l, font: h, weight: F, threadColor: S, pitch: P, fill: s, animate: m, sewStyle: k, sewRate: j, sheen: yt, editable: B, reducedMotion: st } = x;
514
+ return Ae(() => {
515
+ const D = n.current;
466
516
  if (!D) return;
467
- const at = Le(D, {
468
- ...r.current,
517
+ const ft = Ie(D, {
518
+ ...i.current,
469
519
  // Stable callback wrapper so typing edits always reach the latest handler.
470
- onTextChange: (y) => {
471
- var E;
472
- return (E = i.current) == null ? void 0 : E.call(i, y);
520
+ onTextChange: (v) => {
521
+ var A;
522
+ return (A = a.current) == null ? void 0 : A.call(a, v);
473
523
  }
474
524
  });
475
- n.current = at;
476
- let U = 0, k = 0, R = !0, j;
477
- return typeof ResizeObserver < "u" && (j = new ResizeObserver((y) => {
478
- const E = Math.round(y[0].contentRect.width);
525
+ o.current = ft;
526
+ let G = 0, O = 0, R = !0, z;
527
+ return typeof ResizeObserver < "u" && (z = new ResizeObserver((v) => {
528
+ const A = Math.round(v[0].contentRect.width);
479
529
  if (R) {
480
- R = !1, k = E;
530
+ R = !1, O = A;
481
531
  return;
482
532
  }
483
- E !== k && (k = E, cancelAnimationFrame(U), U = requestAnimationFrame(() => {
484
- var Q;
485
- return (Q = n.current) == null ? void 0 : Q.resize();
533
+ A !== O && (O = A, cancelAnimationFrame(G), G = requestAnimationFrame(() => {
534
+ var W;
535
+ return (W = o.current) == null ? void 0 : W.resize();
486
536
  }));
487
- }), j.observe(D)), () => {
488
- j == null || j.disconnect(), cancelAnimationFrame(U), at.destroy(), n.current = null;
537
+ }), z.observe(D)), () => {
538
+ z == null || z.disconnect(), cancelAnimationFrame(G), ft.destroy(), o.current = null;
489
539
  };
490
- }, [it]), ee(() => {
540
+ }, [st]), oe(() => {
491
541
  var D;
492
- (D = n.current) == null || D.update({ font: u, weight: b, threadColor: S, pitch: A, fill: c, animate: m, sewRate: I, sheen: O, editable: B });
493
- }, [u, b, S, A, c, m, I, O, B]), ee(() => {
542
+ (D = o.current) == null || D.update({ font: h, weight: F, threadColor: S, pitch: P, fill: s, animate: m, sewStyle: k, sewRate: j, sheen: yt, editable: B });
543
+ }, [h, F, S, P, s, m, k, j, yt, B]), oe(() => {
494
544
  var D;
495
- (D = n.current) == null || D.setText(a);
496
- }, [a]), e;
545
+ (D = o.current) == null || D.setText(l);
546
+ }, [l]), n;
497
547
  }
498
- const $e = Ae(
499
- function({ className: e, style: n, as: r = "div", "aria-label": i, role: a, "aria-describedby": u, ...b }, S) {
500
- const A = Re(b), c = Ee(
548
+ const ke = Fe(
549
+ function({ className: n, style: o, as: i = "div", "aria-label": a, role: l, "aria-describedby": h, ...F }, S) {
550
+ const P = Pe(F), s = Le(
501
551
  (m) => {
502
- A.current = m, typeof S == "function" ? S(m) : S && (S.current = m);
552
+ P.current = m, typeof S == "function" ? S(m) : S && (S.current = m);
503
553
  },
504
554
  // eslint-disable-next-line react-hooks/exhaustive-deps
505
- [A, S]
555
+ [P, S]
506
556
  );
507
- return /* @__PURE__ */ Se(
508
- r,
557
+ return /* @__PURE__ */ Re(
558
+ i,
509
559
  {
510
- ref: c,
511
- className: e,
512
- style: n,
513
- role: b.editable ? a : a ?? "img",
514
- "aria-label": b.editable ? i : i ?? b.text,
515
- "aria-describedby": u
560
+ ref: s,
561
+ className: n,
562
+ style: o,
563
+ role: F.editable ? l : l ?? "img",
564
+ "aria-label": F.editable ? a : a ?? F.text,
565
+ "aria-describedby": h
516
566
  }
517
567
  );
518
568
  }
519
569
  );
520
- $e.displayName = "ThreadText";
570
+ ke.displayName = "ThreadText";
521
571
  export {
522
572
  Dt as THREAD_TEXT_CLASSES,
523
- $e as ThreadText,
524
- Le as createThreadText,
525
- Re as useThreadText
573
+ ke as ThreadText,
574
+ Ie as createThreadText,
575
+ Pe as useThreadText
526
576
  };
@@ -1 +1 @@
1
- var ThreadText=(function(ct){"use strict";const bt={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function K(r,n){let e=Math.imul(r|0,374761393)+Math.imul(n|0,668265263)|0;return e=Math.imul(e^e>>>13,1274126177),((e^e>>>16)>>>0)/4294967295}function _t(r,n){const e=Math.floor(r),o=Math.floor(n),i=r-e,c=n-o,m=i*i*(3-2*i),F=c*c*(3-2*c),$=K(e,o),E=K(e+1,o),u=K(e,o+1),y=K(e+1,o+1);return $+(E-$)*m+(u-$)*F+($-E-u+y)*m*F}const ft=1e20;function qt(r,n,e,o,i){let c=0;o[0]=0,i[0]=-ft,i[1]=ft;for(let m=1;m<n;m++){let F=(r[m]+m*m-(r[o[c]]+o[c]*o[c]))/(2*m-2*o[c]);for(;F<=i[c];)c--,F=(r[m]+m*m-(r[o[c]]+o[c]*o[c]))/(2*m-2*o[c]);c++,o[c]=m,i[c]=F,i[c+1]=ft}c=0;for(let m=0;m<n;m++){for(;i[c+1]<m;)c++;e[m]=(m-o[c])*(m-o[c])+r[o[c]]}}function ce(r,n,e){const o=new Float64Array(n*e);for(let u=0;u<n*e;u++)o[u]=r[u]?ft:0;const i=Math.max(n,e),c=new Float64Array(i),m=new Float64Array(i),F=new Int32Array(i),$=new Float64Array(i+1);for(let u=0;u<n;u++){for(let y=0;y<e;y++)c[y]=o[y*n+u];qt(c,e,m,F,$);for(let y=0;y<e;y++)o[y*n+u]=m[y]}for(let u=0;u<e;u++){for(let y=0;y<n;y++)c[y]=o[u*n+y];qt(c,n,m,F,$);for(let y=0;y<n;y++)o[u*n+y]=m[y]}const E=new Float32Array(n*e);for(let u=0;u<n*e;u++)E[u]=Math.sqrt(o[u]);return E}function zt(r,n,e,o,i){let c=Float32Array.from(r);const m=new Float32Array(n*e),F=1/(2*o+1),$=(E,u)=>E<0?0:E>u?u:E;for(let E=0;E<i;E++){for(let u=0;u<e;u++){const y=u*n;let I=0;for(let D=-o;D<=o;D++)I+=c[y+$(D,n-1)];for(let D=0;D<n;D++)m[y+D]=I*F,I+=c[y+$(D+o+1,n-1)]-c[y+$(D-o,n-1)]}for(let u=0;u<n;u++){let y=0;for(let I=-o;I<=o;I++)y+=m[$(I,e-1)*n+u];for(let I=0;I<e;I++)c[I*n+u]=y*F,y+=m[$(I+o+1,e-1)*n+u]-m[$(I-o,e-1)*n+u]}}return c}function Gt(r,n){if(!r)return n;const e=r.trim();if(e[0]==="#"){let i=e.slice(1);if(i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),i.length>=6){const c=parseInt(i.slice(0,2),16),m=parseInt(i.slice(2,4),16),F=parseInt(i.slice(4,6),16);if(!Number.isNaN(c)&&!Number.isNaN(m)&&!Number.isNaN(F))return[c,m,F]}return n}const o=e.match(/rgba?\(([^)]+)\)/i);if(o){const i=o[1].split(",").map(c=>parseFloat(c));if(i.length>=3&&i.slice(0,3).every(c=>!Number.isNaN(c)))return[Math.round(i[0]),Math.round(i[1]),Math.round(i[2])]}return n}function z(r){return r<0?0:r>255?255:Math.round(r)}function dt(r,n,e){return r<n?n:r>e?e:r}function Ut(r){return(r.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function fe(r,n){if(typeof window>"u"||typeof document>"u"||!r)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let e=n.text??"",o=n.font??"Georgia, serif",i=dt(n.weight??680,1,1e3),c=dt(n.fill??.9,.05,1),m=Math.max(1,n.sewRate??110),F=n.sheen??!0,$=n.animate??!0,E=n.editable??!1,u=n.pitch,y=n.onTextChange,I=Ut(o);const D=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let P=Gt(n.threadColor??"#fffbf3",[255,251,243]),St=[0,0,0],At=[0,0,0];function Ht(t){P=Gt(t,[255,251,243]),St=[P[0]*.585,P[1]*.585,P[2]*.585],At=[P[0]*.47,P[1]*.47,P[2]*.47]}Ht(n.threadColor??"#fffbf3");const nt=[];let O,L;r instanceof HTMLCanvasElement?(O=r,L=r.parentElement??r):(L=r,O=document.createElement("canvas"),nt.push(O),L.appendChild(O)),O.classList.add(bt.bg);const V=document.createElement("canvas");nt.push(V),V.classList.add(bt.fx),L.appendChild(V),getComputedStyle(L).position==="static"&&(L.style.position="relative"),O.style.display="block",O.style.width="100%",Object.assign(V.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let g=null,R=null,ht=!1,s=0,h=0,J=0,Et=0,Q=4,Z=[],ot=0,it=0,Kt=-1,Vt="",Yt=-1,Jt=-1,Ft=new Uint8Array(0),Lt=new Float32Array(0),mt=new Float32Array(0),yt=new Float32Array(0),U=null,W=null,xt=null,gt=[],pt=3;const A={rows:[],idx:0,acc:0,rate:0,on:!1},G={x:0,y:0,set:!1};let Y=!0,Rt=0,rt=!1,at=0,k=!1,X=!1;function ye(){const t=L.getBoundingClientRect(),a=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),l=e||"Ag",f=O.getContext("2d");f&&(f.textBaseline="middle");let b=100;f&&(f.font=`${i} 100px ${o}`,b=f.measureText(l).width||100);const v=Math.max(8,100*(a*c)/b);let C=v*.62,T=v*.62,N=a*c;if(f){f.font=`${i} ${v}px ${o}`;const w=f.measureText(l);N=w.width||N,w.actualBoundingBoxAscent>0&&(C=w.actualBoundingBoxAscent),w.actualBoundingBoxDescent>0&&(T=w.actualBoundingBoxDescent)}const p=Math.max(1,Math.round(2*Math.max(C,T)*1.1));let d=Math.min(window.devicePixelRatio||1,1.7);for(;a*d*p*d>9e5&&d>.4;)d-=.1;s=Math.max(1,Math.round(a*d)),h=Math.max(1,Math.round(p*d)),J=Math.max(4,Math.round(v*d)),Et=Math.round(s/2-N*d/2);for(const w of[O,V])w.width=s,w.height=h,w.style.height=p+"px";L.style.height=p+"px",Q=u??Math.max(3,h*.0095)}function xe(){W&&Yt===s&&Jt===h||(W=document.createElement("canvas"),W.width=s,W.height=h,xt=W.getContext("2d",{willReadFrequently:!0}),Yt=s,Jt=h)}function Qt(){const t=Math.max(7,Q*2.5),a=Math.max(3.2,Q*1.3);ot=Math.ceil(t)+2,it=Math.ceil(a)+2,Z=[];for(let l=0;l<20;l++){const f=.34+l/19*.82,b=document.createElement("canvas");b.width=ot,b.height=it;const v=b.getContext("2d");if(!v){Z.push(b);continue}const C=ot/2,T=it/2,N=v.createLinearGradient(0,T-a/2,0,T+a/2),p=(B,j)=>`rgba(${z(B[0]*f)},${z(B[1]*f)},${z(B[2]*f)},${j})`;N.addColorStop(0,p(At,0)),N.addColorStop(.16,p(St,1)),N.addColorStop(.5,p(P,1)),N.addColorStop(.84,p(St,1)),N.addColorStop(1,p(At,0)),v.fillStyle=N,v.beginPath();const d=a/2;v.moveTo(C-t/2+d,T-d),v.lineTo(C+t/2-d,T-d),v.arc(C+t/2-d,T,d,-Math.PI/2,Math.PI/2),v.lineTo(C-t/2+d,T+d),v.arc(C-t/2+d,T,d,Math.PI/2,-Math.PI/2),v.closePath(),v.fill(),v.globalCompositeOperation="destination-in";const w=v.createLinearGradient(C-t/2,0,C+t/2,0);w.addColorStop(0,"rgba(0,0,0,0)"),w.addColorStop(.22,"rgba(0,0,0,1)"),w.addColorStop(.78,"rgba(0,0,0,1)"),w.addColorStop(1,"rgba(0,0,0,0)"),v.fillStyle=w,v.fillRect(0,0,ot,it),Z.push(b)}Kt=Q,Vt=P.join(",")}function ge(){Z.length&&Kt===Q&&Vt===P.join(",")||Qt()}function pe(){if(!xt)return;const t=xt;t.clearRect(0,0,s,h),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${i} ${J}px ${o}`,t.fillText(e,Et,h*.5);const a=t.getImageData(0,0,s,h).data,l=new Uint8Array(s*h);for(let x=0;x<h;x++)for(let M=0;M<s;M++){const S=x*s+M,_=a[S*4+3]/255,q=_t(M*.5,x*.5)*.22+_t(M*1.8,x*1.8)*.1;l[S]=_>.5+(q-.16)?1:0}Ft=l;const f=ce(l,s,h),b=new Float32Array(s*h);for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const S=x*s+M;b[S]=(f[S]*4+f[S-1]+f[S+1]+f[S-s]+f[S+s])/8}const v=new Float32Array(s*h),C=new Float32Array(s*h),T=new Float32Array(s*h),N=new Float32Array(s*h);for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const S=x*s+M;if(!l[S])continue;const _=(b[S+1]-b[S-1])*.5,q=(b[S+s]-b[S-s])*.5;T[S]=_,N[S]=q,v[S]=_*_-q*q,C[S]=2*_*q}const p=Math.max(7,Math.round(h*.05)),d=zt(v,s,h,p,2),w=zt(C,s,h,p,2);mt=new Float32Array(s*h),yt=new Float32Array(s*h);for(let x=0;x<s*h;x++){if(!l[x])continue;const M=.5*Math.atan2(w[x],d[x]);mt[x]=Math.cos(M),yt[x]=Math.sin(M)}const B=Math.max(9,h*.04),j=new Float32Array(s*h),lt=-.45,st=-.62,Ct=.64;for(let x=1;x<h-1;x++)for(let M=1;M<s-1;M++){const S=x*s+M;if(!l[S])continue;let _=T[S],q=N[S];const re=Math.hypot(_,q)||1;_/=re,q/=re;const ae=b[S],le=(1-Math.min(ae/B,1))*1.25;let Ot=-_*le,kt=-q*le;const se=1.5,Dt=Math.hypot(Ot,kt,se);Ot/=Dt,kt/=Dt;let jt=Ot*lt+kt*st+se/Dt*Ct;jt<0&&(jt=0);const Ne=Math.min(1,.45+.55*Math.min(ae/(B*.7),1));j[S]=Math.min(1.12,(.5+.75*jt)*Ne)}Lt=j,U=document.createElement("canvas"),U.width=s,U.height=h;const H=U.getContext("2d");if(H){const x=H.createImageData(s,h);for(let M=0;M<s*h;M++)l[M]&&(x.data[M*4]=255,x.data[M*4+1]=255,x.data[M*4+2]=255,x.data[M*4+3]=255);H.putImageData(x,0,0)}}function we(){const t=Math.max(1.6,Q*.6);pt=t;const a=[];for(let l=0;l<h;l+=t)for(let f=0;f<s;f+=t){const b=(K(Math.floor(f),Math.floor(l))-.5)*t*.9,v=(K(Math.floor(l),Math.floor(f))-.5)*t*.9,C=Math.round(f+b),T=Math.round(l+v);if(C<1||T<1||C>=s-1||T>=h-1)continue;const N=T*s+C;if(!Ft[N])continue;const p=Math.atan2(yt[N],mt[N]),d=.86+K(C*7,T*13)*.18;let w=Lt[N]*d;w=w<0?0:w>1.12?1.12:w,a.push({x:C,y:T,ang:p,idx:Math.min(19,Math.max(0,Math.round(w/1.12*19)))})}gt=a}function Zt(t,a){t.save(),t.translate(a.x,a.y),t.rotate(a.ang),t.drawImage(Z[a.idx],-ot/2,-it/2),t.restore()}function Nt(){const t=O.getContext("2d");if(t)for(const a of gt)Zt(t,a)}function $t(){const t=O.getContext("2d");t&&t.clearRect(0,0,s,h)}function Me(t){if(!t.length)return[];const a=Math.max(4,pt*1.5),l=new Map,f=(p,d)=>p+","+d;t.forEach((p,d)=>{const w=f(Math.floor(p.x/a),Math.floor(p.y/a));let B=l.get(w);B||l.set(w,B=[]),B.push(d)});const b=pt*1.8*(pt*1.8);function v(p){const d=t[p],w=Math.floor(d.x/a),B=Math.floor(d.y/a),j=[];for(let lt=-1;lt<=1;lt++)for(let st=-1;st<=1;st++){const Ct=l.get(f(w+lt,B+st));if(Ct)for(const H of Ct){if(H===p)continue;const x=t[H].x-d.x,M=t[H].y-d.y;x*x+M*M<=b&&j.push(H)}}return j}const C=new Uint8Array(t.length),T=[],N=t.map((p,d)=>d).sort((p,d)=>t[p].x+t[p].y-(t[d].x+t[d].y));for(const p of N){if(C[p])continue;let d=[p];for(C[p]=1;d.length;){T.push(d.map(B=>t[B]));const w=[];for(const B of d)for(const j of v(B))C[j]||(C[j]=1,w.push(j));d=w}}return T}function ve(){if($t(),D||!$){Nt(),A.on=!1;return}A.rows=Me(gt),A.idx=0,A.acc=0,A.rate=m,A.on=A.rows.length>0}function Ce(t){const a=O.getContext("2d");if(a)for(t>A.rows.length&&(t=A.rows.length);A.idx<t;){const l=A.rows[A.idx++];for(const f of l)Zt(a,f)}}function be(t,a){const l=V.getContext("2d");if(!l||(l.clearRect(0,0,s,h),!F||!U))return;const f=s*.32,b=l.createRadialGradient(t,a,0,t,a,f);b.addColorStop(0,"rgba(255,250,238,0.18)"),b.addColorStop(.5,"rgba(255,250,238,0.055)"),b.addColorStop(1,"rgba(255,250,238,0)"),l.fillStyle=b,l.fillRect(0,0,s,h),l.globalCompositeOperation="destination-in",l.drawImage(U,0,0),l.globalCompositeOperation="source-over"}function Te(){R||!E||(R=document.createElement("span"),R.className=bt.caret,R.setAttribute("aria-hidden","true"),Object.assign(R.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${z(P[0])},${z(P[1])},${z(P[2])})`}),L.appendChild(R),nt.push(R))}function It(){if(!E||!R)return;const t=O.getContext("2d");if(!t)return;t.font=`${i} ${J}px ${o}`;const a=t.measureText(e).width,l=(O.clientWidth||s)/s,f=J*.7;R.style.left=(Et+a+J*.05)*l+"px",R.style.top=.5*(O.clientHeight||h)-f*l/2+"px",R.style.height=f*l+"px",R.style.width=Math.max(2,Math.round(J*.02*l))+"px",R.style.background=`rgb(${z(P[0])},${z(P[1])},${z(P[2])})`}function tt(){k||rt||(rt=!0,at=0,Rt=requestAnimationFrame(Wt))}function Wt(t){if(k){rt=!1;return}at||(at=t);const a=Math.min(.25,(t-at)/1e3);at=t,A.on&&(A.acc+=A.rate*a,Ce(A.acc),A.idx>=A.rows.length&&(A.on=!1)),Y&&U&&(be(G.set?G.x:s*.5,G.set?G.y:h*.45),Y=!1);const l=E&&ht;if(R&&(R.style.opacity=l&&Math.floor(t/530)%2===0?"1":"0"),!A.on&&!Y&&!l){rt=!1;return}Rt=requestAnimationFrame(Wt)}function wt(t){const a=L.getBoundingClientRect();G.x=(t.clientX-a.left)/(a.width||1)*s,G.y=(t.clientY-a.top)/(a.height||1)*h,G.set=!0,Y=!0,tt()}function Mt(){G.set=!1,Y=!0,tt()}function Se(){g&&ee(g.value,!0)}function Ae(t){t.key==="Enter"&&(t.preventDefault(),Bt.replay())}function Ee(){ht=!0,tt()}function Fe(){ht=!1,R&&(R.style.opacity="0")}function te(t){t===E&&g||(E=t,t?(g||(g=document.createElement("input"),g.type="text",g.value=e,g.maxLength=64,g.setAttribute("aria-label","Embroidered text — type to change it"),g.setAttribute("autocomplete","off"),g.setAttribute("autocapitalize","off"),g.spellcheck=!1,Object.assign(g.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),g.addEventListener("input",Se),g.addEventListener("keydown",Ae),g.addEventListener("focus",Ee),g.addEventListener("blur",Fe),L.appendChild(g),nt.push(g)),Te(),It()):(g&&(g.remove(),g=null),ht=!1,R&&(R.style.opacity="0")))}function Le(t){if(t!==F)if(F=t,t)L.addEventListener("pointermove",wt,{passive:!0}),L.addEventListener("pointerleave",Mt,{passive:!0}),G.set=!1,Y=!0,tt();else{L.removeEventListener("pointermove",wt),L.removeEventListener("pointerleave",Mt);const a=V.getContext("2d");a&&a.clearRect(0,0,s,h)}}function et(t){ye(),xe(),ge(),pe(),we(),t?ve():($t(),Nt(),A.on=!1),g&&g.value!==e&&(g.value=e),It(),Y=!0,tt()}function ee(t,a){t=t??"",!(t===e&&X)&&(e=t,X&&(et(!1),a&&y&&y(e)))}const vt=new Set;function ne(t,a,l){const f=`${a} 200px ${t}`;let b=!1;try{b=!!document.fonts&&document.fonts.check(f)}catch{b=!0}if(!document.fonts||b){l();return}let v=!1,C;const T=()=>{v||(v=!0,clearTimeout(C),vt.delete(C),k||l())};document.fonts.load(f,e).then(()=>document.fonts.ready).then(T,T),C=setTimeout(T,1500),vt.add(C)}function Re(){k||(et(!0),X=!0)}E&&(E=!1,te(!0)),F&&(L.addEventListener("pointermove",wt,{passive:!0}),L.addEventListener("pointerleave",Mt,{passive:!0})),ne(I,i,Re);let Pt,oe=-1;function ie(){clearTimeout(Pt),Pt=setTimeout(()=>{if(k||!X)return;const t=Math.round(L.getBoundingClientRect().width);t!==oe&&(oe=t,et(!1))},200)}window.addEventListener("resize",ie);const Bt={get text(){return e},setText(t){if(!k){if(!X){e=t??"",g&&(g.value=e);return}ee(t,!1)}},replay(){k||!X||et(!0)},resize(){k||!X||et(!1)},update(t){if(k)return;t.text!==void 0&&Bt.setText(t.text);let a=!1,l=!1;if(t.font!==void 0&&t.font!==o&&(o=t.font,I=Ut(o),a=!0),t.weight!==void 0){const f=dt(t.weight,1,1e3);f!==i&&(i=f,a=!0)}if(t.fill!==void 0){const f=dt(t.fill,.05,1);f!==c&&(c=f,a=!0)}t.pitch!==void 0&&t.pitch!==u&&(u=t.pitch,a=!0),t.threadColor!==void 0&&(Ht(t.threadColor),l=!0),t.sewRate!==void 0&&(m=Math.max(1,t.sewRate)),t.animate!==void 0&&($=t.animate),t.onTextChange!==void 0&&(y=t.onTextChange),t.sheen!==void 0&&Le(t.sheen),t.editable!==void 0&&te(t.editable),X&&(a?ne(I,i,()=>{k||et(!1)}):l&&(Qt(),$t(),Nt(),It(),tt()))},focus(){!k&&E&&(g==null||g.focus())},destroy(){if(!k){k=!0,rt=!1,cancelAnimationFrame(Rt),clearTimeout(Pt);for(const t of vt)clearTimeout(t);vt.clear(),window.removeEventListener("resize",ie),L.removeEventListener("pointermove",wt),L.removeEventListener("pointerleave",Mt);for(const t of nt)t.remove();Z=[],gt=[],A.rows=[],Ft=new Uint8Array(0),Lt=new Float32Array(0),mt=new Float32Array(0),yt=new Float32Array(0),U=W=null,xt=null,R=null,g=null}}};return Bt}const de="data-threadtext",Tt=new WeakMap;function ue(r,n){const e=r.dataset,o={text:e.ttText??n};if(e.ttFont&&(o.font=e.ttFont),e.ttWeight!==void 0){const i=parseFloat(e.ttWeight);isNaN(i)||(o.weight=i)}if(e.ttThreadColor&&(o.threadColor=e.ttThreadColor),e.ttPitch!==void 0){const i=parseFloat(e.ttPitch);isNaN(i)||(o.pitch=i)}if(e.ttFill!==void 0){const i=parseFloat(e.ttFill);isNaN(i)||(o.fill=i)}if(e.ttSewRate!==void 0){const i=parseFloat(e.ttSewRate);isNaN(i)||(o.sewRate=i)}return e.ttSheen==="false"&&(o.sheen=!1),e.ttAnimate==="false"&&(o.animate=!1),e.ttEditable==="true"&&(o.editable=!0),o}function he(r){Xt(r);const n=r.innerHTML,e=(r.dataset.ttText??r.textContent??"").trim();if(!e)return;const o=ue(r,e);r.innerHTML="",o.editable||(r.setAttribute("role","img"),r.setAttribute("aria-label",e));const i=fe(r,o);Tt.set(r,{instance:i,originalHTML:n})}function Xt(r){const n=Tt.get(r);n&&(n.instance.destroy(),r.removeAttribute("role"),r.removeAttribute("aria-label"),r.innerHTML=n.originalHTML,Tt.delete(r))}function ut(r=document){r.querySelectorAll(`[${de}]`).forEach(he)}function me(){const r=()=>{var n;typeof document<"u"&&((n=document.fonts)!=null&&n.ready)?document.fonts.ready.then(()=>ut()).catch(()=>ut()):ut()};typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",r,{once:!0}):r()}return me(),ct.destroy=Xt,ct.init=ut,Object.defineProperty(ct,Symbol.toStringTag,{value:"Module"}),ct})({});
1
+ var ThreadText=(function(ut){"use strict";const St={bg:"tt-bg",fx:"tt-fx",caret:"tt-caret"};function J(a,n){let e=Math.imul(a|0,374761393)+Math.imul(n|0,668265263)|0;return e=Math.imul(e^e>>>13,1274126177),((e^e>>>16)>>>0)/4294967295}function _t(a,n){const e=Math.floor(a),o=Math.floor(n),i=a-e,d=n-o,p=i*i*(3-2*i),$=d*d*(3-2*d),N=J(e,o),O=J(e+1,o),u=J(e,o+1),v=J(e+1,o+1);return N+(O-N)*p+(u-N)*$+(N-O-u+v)*p*$}const ht=1e20;function qt(a,n,e,o,i){let d=0;o[0]=0,i[0]=-ht,i[1]=ht;for(let p=1;p<n;p++){let $=(a[p]+p*p-(a[o[d]]+o[d]*o[d]))/(2*p-2*o[d]);for(;$<=i[d];)d--,$=(a[p]+p*p-(a[o[d]]+o[d]*o[d]))/(2*p-2*o[d]);d++,o[d]=p,i[d]=$,i[d+1]=ht}d=0;for(let p=0;p<n;p++){for(;i[d+1]<p;)d++;e[p]=(p-o[d])*(p-o[d])+a[o[d]]}}function fe(a,n,e){const o=new Float64Array(n*e);for(let u=0;u<n*e;u++)o[u]=a[u]?ht:0;const i=Math.max(n,e),d=new Float64Array(i),p=new Float64Array(i),$=new Int32Array(i),N=new Float64Array(i+1);for(let u=0;u<n;u++){for(let v=0;v<e;v++)d[v]=o[v*n+u];qt(d,e,p,$,N);for(let v=0;v<e;v++)o[v*n+u]=p[v]}for(let u=0;u<e;u++){for(let v=0;v<n;v++)d[v]=o[u*n+v];qt(d,n,p,$,N);for(let v=0;v<n;v++)o[u*n+v]=p[v]}const O=new Float32Array(n*e);for(let u=0;u<n*e;u++)O[u]=Math.sqrt(o[u]);return O}function zt(a,n,e,o,i){let d=Float32Array.from(a);const p=new Float32Array(n*e),$=1/(2*o+1),N=(O,u)=>O<0?0:O>u?u:O;for(let O=0;O<i;O++){for(let u=0;u<e;u++){const v=u*n;let P=0;for(let D=-o;D<=o;D++)P+=d[v+N(D,n-1)];for(let D=0;D<n;D++)p[v+D]=P*$,P+=d[v+N(D+o+1,n-1)]-d[v+N(D-o,n-1)]}for(let u=0;u<n;u++){let v=0;for(let P=-o;P<=o;P++)v+=p[N(P,e-1)*n+u];for(let P=0;P<e;P++)d[P*n+u]=v*$,v+=p[N(P+o+1,e-1)*n+u]-p[N(P-o,e-1)*n+u]}}return d}function Ut(a,n){if(!a)return n;const e=a.trim();if(e[0]==="#"){let i=e.slice(1);if(i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),i.length>=6){const d=parseInt(i.slice(0,2),16),p=parseInt(i.slice(2,4),16),$=parseInt(i.slice(4,6),16);if(!Number.isNaN(d)&&!Number.isNaN(p)&&!Number.isNaN($))return[d,p,$]}return n}const o=e.match(/rgba?\(([^)]+)\)/i);if(o){const i=o[1].split(",").map(d=>parseFloat(d));if(i.length>=3&&i.slice(0,3).every(d=>!Number.isNaN(d)))return[Math.round(i[0]),Math.round(i[1]),Math.round(i[2])]}return n}function U(a){return a<0?0:a>255?255:Math.round(a)}function mt(a,n,e){return a<n?n:a>e?e:a}function Xt(a){return(a.split(",")[0]||"serif").trim().replace(/^["']|["']$/g,"")}function de(a,n){if(typeof window>"u"||typeof document>"u"||!a)return{setText(){},replay(){},resize(){},update(){},focus(){},destroy(){},get text(){return n.text??""}};let e=n.text??"",o=n.font??"Georgia, serif",i=mt(n.weight??680,1,1e3),d=mt(n.fill??.9,.05,1),p=Math.max(1,n.sewRate??110),$=n.sewStyle==="hand"?"hand":"machine",N=n.sheen??!0,O=n.animate??!0,u=n.editable??!1,v=n.pitch,P=n.onTextChange,D=Xt(o);const xe=n.reducedMotion??!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);let k=Ut(n.threadColor??"#fffbf3",[255,251,243]),At=[0,0,0],bt=[0,0,0];function Ht(t){k=Ut(t,[255,251,243]),At=[k[0]*.585,k[1]*.585,k[2]*.585],bt=[k[0]*.47,k[1]*.47,k[2]*.47]}Ht(n.threadColor??"#fffbf3");const at=[];let B,L;a instanceof HTMLCanvasElement?(B=a,L=a.parentElement??a):(L=a,B=document.createElement("canvas"),at.push(B),L.appendChild(B)),B.classList.add(St.bg);const Q=document.createElement("canvas");at.push(Q),Q.classList.add(St.fx),L.appendChild(Q),getComputedStyle(L).position==="static"&&(L.style.position="relative"),B.style.display="block",B.style.width="100%",Object.assign(Q.style,{position:"absolute",inset:"0",width:"100%",pointerEvents:"none",mixBlendMode:"screen"});let S=null,R=null,xt=!1,f=0,x=0,tt=0,Et=0,et=4,nt=[],st=0,lt=0,Kt=-1,Vt="",Yt=-1,Jt=-1,Ft=new Uint8Array(0),Lt=new Float32Array(0),gt=new Float32Array(0),pt=new Float32Array(0),K=null,ot=null,wt=null,ct=[],Z=3;const E={rows:[],idx:0,acc:0,rate:0,on:!1},X={x:0,y:0,set:!1};let W=!0,Rt=0,ft=!1,dt=0,j=!1,V=!1;function ge(){const t=L.getBoundingClientRect(),r=Math.max(1,Math.round(t.width||Math.min(window.innerWidth*.95,1240))),s=e||"Ag",c=B.getContext("2d");c&&(c.textBaseline="middle");let M=100;c&&(c.font=`${i} 100px ${o}`,M=c.measureText(s).width||100);const m=Math.max(8,100*(r*d)/M);let y=m*.62,T=m*.62,C=r*d;if(c){c.font=`${i} ${m}px ${o}`;const g=c.measureText(s);C=g.width||C,g.actualBoundingBoxAscent>0&&(y=g.actualBoundingBoxAscent),g.actualBoundingBoxDescent>0&&(T=g.actualBoundingBoxDescent)}const h=Math.max(1,Math.round(2*Math.max(y,T)*1.1));let l=Math.min(window.devicePixelRatio||1,1.7);for(;r*l*h*l>9e5&&l>.4;)l-=.1;f=Math.max(1,Math.round(r*l)),x=Math.max(1,Math.round(h*l)),tt=Math.max(4,Math.round(m*l)),Et=Math.round(f/2-C*l/2);for(const g of[B,Q])g.width=f,g.height=x,g.style.height=h+"px";L.style.height=h+"px",et=v??Math.max(3,x*.0095)}function pe(){ot&&Yt===f&&Jt===x||(ot=document.createElement("canvas"),ot.width=f,ot.height=x,wt=ot.getContext("2d",{willReadFrequently:!0}),Yt=f,Jt=x)}function Qt(){const t=Math.max(7,et*2.5),r=Math.max(3.2,et*1.3);st=Math.ceil(t)+2,lt=Math.ceil(r)+2,nt=[];for(let s=0;s<20;s++){const c=.34+s/19*.82,M=document.createElement("canvas");M.width=st,M.height=lt;const m=M.getContext("2d");if(!m){nt.push(M);continue}const y=st/2,T=lt/2,C=m.createLinearGradient(0,T-r/2,0,T+r/2),h=(F,I)=>`rgba(${U(F[0]*c)},${U(F[1]*c)},${U(F[2]*c)},${I})`;C.addColorStop(0,h(bt,0)),C.addColorStop(.16,h(At,1)),C.addColorStop(.5,h(k,1)),C.addColorStop(.84,h(At,1)),C.addColorStop(1,h(bt,0)),m.fillStyle=C,m.beginPath();const l=r/2;m.moveTo(y-t/2+l,T-l),m.lineTo(y+t/2-l,T-l),m.arc(y+t/2-l,T,l,-Math.PI/2,Math.PI/2),m.lineTo(y-t/2+l,T+l),m.arc(y-t/2+l,T,l,Math.PI/2,-Math.PI/2),m.closePath(),m.fill(),m.globalCompositeOperation="destination-in";const g=m.createLinearGradient(y-t/2,0,y+t/2,0);g.addColorStop(0,"rgba(0,0,0,0)"),g.addColorStop(.22,"rgba(0,0,0,1)"),g.addColorStop(.78,"rgba(0,0,0,1)"),g.addColorStop(1,"rgba(0,0,0,0)"),m.fillStyle=g,m.fillRect(0,0,st,lt),nt.push(M)}Kt=et,Vt=k.join(",")}function we(){nt.length&&Kt===et&&Vt===k.join(",")||Qt()}function Me(){if(!wt)return;const t=wt;t.clearRect(0,0,f,x),t.fillStyle="#fff",t.textAlign="left",t.textBaseline="middle",t.font=`${i} ${tt}px ${o}`,t.fillText(e,Et,x*.5);const r=t.getImageData(0,0,f,x).data,s=new Uint8Array(f*x);for(let w=0;w<x;w++)for(let A=0;A<f;A++){const b=w*f+A,q=r[b*4+3]/255,z=_t(A*.5,w*.5)*.22+_t(A*1.8,w*1.8)*.1;s[b]=q>.5+(z-.16)?1:0}Ft=s;const c=fe(s,f,x),M=new Float32Array(f*x);for(let w=1;w<x-1;w++)for(let A=1;A<f-1;A++){const b=w*f+A;M[b]=(c[b]*4+c[b-1]+c[b+1]+c[b-f]+c[b+f])/8}const m=new Float32Array(f*x),y=new Float32Array(f*x),T=new Float32Array(f*x),C=new Float32Array(f*x);for(let w=1;w<x-1;w++)for(let A=1;A<f-1;A++){const b=w*f+A;if(!s[b])continue;const q=(M[b+1]-M[b-1])*.5,z=(M[b+f]-M[b-f])*.5;T[b]=q,C[b]=z,m[b]=q*q-z*z,y[b]=2*q*z}const h=Math.max(7,Math.round(x*.05)),l=zt(m,f,x,h,2),g=zt(y,f,x,h,2);gt=new Float32Array(f*x),pt=new Float32Array(f*x);for(let w=0;w<f*x;w++){if(!s[w])continue;const A=.5*Math.atan2(g[w],l[w]);gt[w]=Math.cos(A),pt[w]=Math.sin(A)}const F=Math.max(9,x*.04),I=new Float32Array(f*x),G=-.45,Y=-.62,H=.64;for(let w=1;w<x-1;w++)for(let A=1;A<f-1;A++){const b=w*f+A;if(!s[b])continue;let q=T[b],z=C[b];const ae=Math.hypot(q,z)||1;q/=ae,z/=ae;const se=M[b],le=(1-Math.min(se/F,1))*1.25;let Ot=-q*le,Bt=-z*le;const ce=1.5,Dt=Math.hypot(Ot,Bt,ce);Ot/=Dt,Bt/=Dt;let jt=Ot*G+Bt*Y+ce/Dt*H;jt<0&&(jt=0);const Pe=Math.min(1,.45+.55*Math.min(se/(F*.7),1));I[b]=Math.min(1.12,(.5+.75*jt)*Pe)}Lt=I,K=document.createElement("canvas"),K.width=f,K.height=x;const _=K.getContext("2d");if(_){const w=_.createImageData(f,x);for(let A=0;A<f*x;A++)s[A]&&(w.data[A*4]=255,w.data[A*4+1]=255,w.data[A*4+2]=255,w.data[A*4+3]=255);_.putImageData(w,0,0)}}function ve(){const t=Math.max(1.6,et*.6);Z=t;const r=[];for(let s=0;s<x;s+=t)for(let c=0;c<f;c+=t){const M=(J(Math.floor(c),Math.floor(s))-.5)*t*.9,m=(J(Math.floor(s),Math.floor(c))-.5)*t*.9,y=Math.round(c+M),T=Math.round(s+m);if(y<1||T<1||y>=f-1||T>=x-1)continue;const C=T*f+y;if(!Ft[C])continue;const h=Math.atan2(pt[C],gt[C]),l=.86+J(y*7,T*13)*.18;let g=Lt[C]*l;g=g<0?0:g>1.12?1.12:g,r.push({x:y,y:T,ang:h,idx:Math.min(19,Math.max(0,Math.round(g/1.12*19)))})}ct=r}function Zt(t,r){t.save(),t.translate(r.x,r.y),t.rotate(r.ang),t.drawImage(nt[r.idx],-st/2,-lt/2),t.restore()}function Nt(){const t=B.getContext("2d");if(t)for(const r of ct)Zt(t,r)}function It(){const t=B.getContext("2d");t&&t.clearRect(0,0,f,x)}function Wt(t){if(!t.length)return[];const r=Math.max(4,Z*1.5),s=new Map,c=(h,l)=>h+","+l;t.forEach((h,l)=>{const g=c(Math.floor(h.x/r),Math.floor(h.y/r));let F=s.get(g);F||s.set(g,F=[]),F.push(l)});const M=Z*1.8*(Z*1.8);function m(h){const l=t[h],g=Math.floor(l.x/r),F=Math.floor(l.y/r),I=[];for(let G=-1;G<=1;G++)for(let Y=-1;Y<=1;Y++){const H=s.get(c(g+G,F+Y));if(H)for(const _ of H){if(_===h)continue;const w=t[_].x-l.x,A=t[_].y-l.y;w*w+A*A<=M&&I.push(_)}}return I}const y=new Uint8Array(t.length),T=[],C=t.map((h,l)=>l).sort((h,l)=>t[h].x+t[h].y-(t[l].x+t[l].y));for(const h of C){if(y[h])continue;let l=[h];for(y[h]=1;l.length;){T.push(l.map(F=>t[F]));const g=[];for(const F of l)for(const I of m(F))y[I]||(y[I]=1,g.push(I));l=g}}return T}function Ce(t){const r=Math.max(4,Z*1.5),s=new Map,c=(C,h)=>C+","+h;t.forEach((C,h)=>{const l=c(Math.floor(C.x/r),Math.floor(C.y/r));let g=s.get(l);g||s.set(l,g=[]),g.push(h)});const M=Z*1.8*(Z*1.8),m=C=>{const h=t[C],l=Math.floor(h.x/r),g=Math.floor(h.y/r),F=[];for(let I=-1;I<=1;I++)for(let G=-1;G<=1;G++){const Y=s.get(c(l+I,g+G));if(Y)for(const H of Y){if(H===C)continue;const _=t[H].x-h.x,w=t[H].y-h.y;_*_+w*w<=M&&F.push(H)}}return F},y=new Uint8Array(t.length),T=[];for(let C=0;C<t.length;C++){if(y[C])continue;const h=[];let l=[C];for(y[C]=1;l.length;){const g=[];for(const F of l){h.push(t[F]);for(const I of m(F))y[I]||(y[I]=1,g.push(I))}l=g}T.push(h)}return T}function Se(t){if(!t.length)return[];const r=M=>{let m=1/0;for(const y of M)y.x<m&&(m=y.x);return m},s=Ce(t).sort((M,m)=>r(M)-r(m)),c=[];for(const M of s){const m=Wt(M);m.sort((y,T)=>T.length-y.length);for(const y of m)c.push(y)}return c}function Te(){if(It(),xe||!O){Nt(),E.on=!1;return}E.rows=$==="hand"?Se(ct):Wt(ct),E.idx=0,E.acc=0,E.rate=p,E.on=E.rows.length>0}function Ae(t){const r=B.getContext("2d");if(r)for(t>E.rows.length&&(t=E.rows.length);E.idx<t;){const s=E.rows[E.idx++];for(const c of s)Zt(r,c)}}function be(t,r){const s=Q.getContext("2d");if(!s||(s.clearRect(0,0,f,x),!N||!K))return;const c=f*.32,M=s.createRadialGradient(t,r,0,t,r,c);M.addColorStop(0,"rgba(255,250,238,0.18)"),M.addColorStop(.5,"rgba(255,250,238,0.055)"),M.addColorStop(1,"rgba(255,250,238,0)"),s.fillStyle=M,s.fillRect(0,0,f,x),s.globalCompositeOperation="destination-in",s.drawImage(K,0,0),s.globalCompositeOperation="source-over"}function Ee(){R||!u||(R=document.createElement("span"),R.className=St.caret,R.setAttribute("aria-hidden","true"),Object.assign(R.style,{position:"absolute",pointerEvents:"none",borderRadius:"1px",opacity:"0",background:`rgb(${U(k[0])},${U(k[1])},${U(k[2])})`}),L.appendChild(R),at.push(R))}function $t(){if(!u||!R)return;const t=B.getContext("2d");if(!t)return;t.font=`${i} ${tt}px ${o}`;const r=t.measureText(e).width,s=(B.clientWidth||f)/f,c=tt*.7;R.style.left=(Et+r+tt*.05)*s+"px",R.style.top=.5*(B.clientHeight||x)-c*s/2+"px",R.style.height=c*s+"px",R.style.width=Math.max(2,Math.round(tt*.02*s))+"px",R.style.background=`rgb(${U(k[0])},${U(k[1])},${U(k[2])})`}function rt(){j||ft||(ft=!0,dt=0,Rt=requestAnimationFrame(te))}function te(t){if(j){ft=!1;return}dt||(dt=t);const r=Math.min(.25,(t-dt)/1e3);dt=t,E.on&&(E.acc+=E.rate*r,Ae(E.acc),E.idx>=E.rows.length&&(E.on=!1)),W&&K&&(be(X.set?X.x:f*.5,X.set?X.y:x*.45),W=!1);const s=u&&xt;if(R&&(R.style.opacity=s&&Math.floor(t/530)%2===0?"1":"0"),!E.on&&!W&&!s){ft=!1;return}Rt=requestAnimationFrame(te)}function Mt(t){const r=L.getBoundingClientRect();X.x=(t.clientX-r.left)/(r.width||1)*f,X.y=(t.clientY-r.top)/(r.height||1)*x,X.set=!0,W=!0,rt()}function vt(){X.set=!1,W=!0,rt()}function Fe(){S&&ne(S.value,!0)}function Le(t){t.key==="Enter"&&(t.preventDefault(),kt.replay())}function Re(){xt=!0,rt()}function Ne(){xt=!1,R&&(R.style.opacity="0")}function ee(t){t===u&&S||(u=t,t?(S||(S=document.createElement("input"),S.type="text",S.value=e,S.maxLength=64,S.setAttribute("aria-label","Embroidered text — type to change it"),S.setAttribute("autocomplete","off"),S.setAttribute("autocapitalize","off"),S.spellcheck=!1,Object.assign(S.style,{position:"absolute",inset:"0",width:"100%",height:"100%",margin:"0",padding:"0",border:"0",outline:"none",background:"transparent",color:"transparent",caretColor:"transparent",font:"inherit",textAlign:"center",cursor:"text"}),S.addEventListener("input",Fe),S.addEventListener("keydown",Le),S.addEventListener("focus",Re),S.addEventListener("blur",Ne),L.appendChild(S),at.push(S)),Ee(),$t()):(S&&(S.remove(),S=null),xt=!1,R&&(R.style.opacity="0")))}function Ie(t){if(t!==N)if(N=t,t)L.addEventListener("pointermove",Mt,{passive:!0}),L.addEventListener("pointerleave",vt,{passive:!0}),X.set=!1,W=!0,rt();else{L.removeEventListener("pointermove",Mt),L.removeEventListener("pointerleave",vt);const r=Q.getContext("2d");r&&r.clearRect(0,0,f,x)}}function it(t){ge(),pe(),we(),Me(),ve(),t?Te():(It(),Nt(),E.on=!1),S&&S.value!==e&&(S.value=e),$t(),W=!0,rt()}function ne(t,r){t=t??"",!(t===e&&V)&&(e=t,V&&(it(!1),r&&P&&P(e)))}const Ct=new Set;function oe(t,r,s){const c=`${r} 200px ${t}`;let M=!1;try{M=!!document.fonts&&document.fonts.check(c)}catch{M=!0}if(!document.fonts||M){s();return}let m=!1,y;const T=()=>{m||(m=!0,clearTimeout(y),Ct.delete(y),j||s())};document.fonts.load(c,e).then(()=>document.fonts.ready).then(T,T),y=setTimeout(T,1500),Ct.add(y)}function $e(){j||(it(!0),V=!0)}u&&(u=!1,ee(!0)),N&&(L.addEventListener("pointermove",Mt,{passive:!0}),L.addEventListener("pointerleave",vt,{passive:!0})),oe(D,i,$e);let Pt,re=-1;function ie(){clearTimeout(Pt),Pt=setTimeout(()=>{if(j||!V)return;const t=Math.round(L.getBoundingClientRect().width);t!==re&&(re=t,it(!1))},200)}window.addEventListener("resize",ie);const kt={get text(){return e},setText(t){if(!j){if(!V){e=t??"",S&&(S.value=e);return}ne(t,!1)}},replay(){j||!V||it(!0)},resize(){j||!V||it(!1)},update(t){if(j)return;t.text!==void 0&&kt.setText(t.text);let r=!1,s=!1;if(t.font!==void 0&&t.font!==o&&(o=t.font,D=Xt(o),r=!0),t.weight!==void 0){const c=mt(t.weight,1,1e3);c!==i&&(i=c,r=!0)}if(t.fill!==void 0){const c=mt(t.fill,.05,1);c!==d&&(d=c,r=!0)}t.pitch!==void 0&&t.pitch!==v&&(v=t.pitch,r=!0),t.threadColor!==void 0&&(Ht(t.threadColor),s=!0),t.sewRate!==void 0&&(p=Math.max(1,t.sewRate)),t.sewStyle!==void 0&&($=t.sewStyle==="hand"?"hand":"machine"),t.animate!==void 0&&(O=t.animate),t.onTextChange!==void 0&&(P=t.onTextChange),t.sheen!==void 0&&Ie(t.sheen),t.editable!==void 0&&ee(t.editable),V&&(r?oe(D,i,()=>{j||it(!1)}):s&&(Qt(),It(),Nt(),$t(),rt()))},focus(){!j&&u&&(S==null||S.focus())},destroy(){if(!j){j=!0,ft=!1,cancelAnimationFrame(Rt),clearTimeout(Pt);for(const t of Ct)clearTimeout(t);Ct.clear(),window.removeEventListener("resize",ie),L.removeEventListener("pointermove",Mt),L.removeEventListener("pointerleave",vt);for(const t of at)t.remove();nt=[],ct=[],E.rows=[],Ft=new Uint8Array(0),Lt=new Float32Array(0),gt=new Float32Array(0),pt=new Float32Array(0),K=ot=null,wt=null,R=null,S=null}}};return kt}const ue="data-threadtext",Tt=new WeakMap;function he(a,n){const e=a.dataset,o={text:e.ttText??n};if(e.ttFont&&(o.font=e.ttFont),e.ttWeight!==void 0){const i=parseFloat(e.ttWeight);isNaN(i)||(o.weight=i)}if(e.ttThreadColor&&(o.threadColor=e.ttThreadColor),e.ttPitch!==void 0){const i=parseFloat(e.ttPitch);isNaN(i)||(o.pitch=i)}if(e.ttFill!==void 0){const i=parseFloat(e.ttFill);isNaN(i)||(o.fill=i)}if(e.ttSewStyle==="hand"&&(o.sewStyle="hand"),e.ttSewRate!==void 0){const i=parseFloat(e.ttSewRate);isNaN(i)||(o.sewRate=i)}return e.ttSheen==="false"&&(o.sheen=!1),e.ttAnimate==="false"&&(o.animate=!1),e.ttEditable==="true"&&(o.editable=!0),o}function me(a){Gt(a);const n=a.innerHTML,e=(a.dataset.ttText??a.textContent??"").trim();if(!e)return;const o=he(a,e);a.innerHTML="",o.editable||(a.setAttribute("role","img"),a.setAttribute("aria-label",e));const i=de(a,o);Tt.set(a,{instance:i,originalHTML:n})}function Gt(a){const n=Tt.get(a);n&&(n.instance.destroy(),a.removeAttribute("role"),a.removeAttribute("aria-label"),a.innerHTML=n.originalHTML,Tt.delete(a))}function yt(a=document){a.querySelectorAll(`[${ue}]`).forEach(me)}function ye(){const a=()=>{var n;typeof document<"u"&&((n=document.fonts)!=null&&n.ready)?document.fonts.ready.then(()=>yt()).catch(()=>yt()):yt()};typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",a,{once:!0}):a()}return ye(),ut.destroy=Gt,ut.init=yt,Object.defineProperty(ut,Symbol.toStringTag,{value:"Module"}),ut})({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liiift-studio/threadtext",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Render any text as photorealistic procedural satin-stitch embroidery, in real time in the browser, from the font's glyph geometry",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",