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