glyphcss 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ function D(n,t,e){let s=Math.cos(t),r=Math.sin(t),c=s*n[1]-r*n[0],o=r*n[1]+s*n[0],a=n[2],p=Math.cos(e),l=Math.sin(e),y=p*o-l*a,u=l*o+p*a;return[c,y,u]}function w(n={}){let t={rotX:n.rotX??0,rotY:n.rotY??0,distance:n.distance??3,scale:n.scale??.4,stretch:n.stretch??1,target:[0,0,0]},[e,s]=n.center??[.5,.5];return{kind:"perspective",get rotX(){return t.rotX},set rotX(r){t.rotX=r},get rotY(){return t.rotY},set rotY(r){t.rotY=r},get distance(){return t.distance},set distance(r){t.distance=r},get scale(){return t.scale},set scale(r){t.scale=r},get stretch(){return t.stretch},set stretch(r){t.stretch=r},get target(){return t.target},set target(r){t.target=r},project(r,c,o,a){let p=[r[0]-t.target[0],r[1]-t.target[1],r[2]-t.target[2]],l=D(p,t.rotY,t.rotX),y=30,u=1.5,b=l[2]*y,f=.001,d=1-b/t.distance;if(d<f)return[NaN,NaN,l[2]];let M=1/d,E=Math.min(c,o)*t.scale*u*M,T=c*e+l[0]*E*a*t.stretch,h=o*s+l[1]*E;return[T,h,l[2]]}}}function z(n={}){let t={rotX:n.rotX??0,rotY:n.rotY??0,distance:0,scale:n.zoom??.4,stretch:1,target:[0,0,0]},[e,s]=n.center??[.5,.5];return{kind:"orthographic",get rotX(){return t.rotX},set rotX(r){t.rotX=r},get rotY(){return t.rotY},set rotY(r){t.rotY=r},get distance(){return t.distance},set distance(r){t.distance=r},get scale(){return t.scale},set scale(r){t.scale=r},get stretch(){return t.stretch},set stretch(r){t.stretch=r},get target(){return t.target},set target(r){t.target=r},project(r,c,o,a){let p=[r[0]-t.target[0],r[1]-t.target[1],r[2]-t.target[2]],l=D(p,t.rotY,t.rotX),u=Math.min(c,o)*t.scale*1.5,b=c*e+l[0]*u*a*t.stretch,f=o*s+l[1]*u;return[b,f,l[2]]}}}function He(n={}){let t={rotX:n.rotX??Math.PI/2,rotY:n.rotY??0,distance:0,scale:1,stretch:1,target:n.origin??[0,0,0],focal:n.focal??1},[e,s]=n.center??[.5,.5];return{kind:"firstPerson",get rotX(){return t.rotX},set rotX(r){t.rotX=r},get rotY(){return t.rotY},set rotY(r){t.rotY=r},get distance(){return t.distance},set distance(r){t.distance=r,t.focal=Math.max(.05,r/100)},get scale(){return t.scale},set scale(r){t.scale=r},get stretch(){return t.stretch},set stretch(r){t.stretch=r},get target(){return t.target},set target(r){t.target=r},project(r,c,o,a){let p=[r[0]-t.target[0],r[1]-t.target[1],r[2]-t.target[2]],l=D(p,t.rotY,t.rotX);if(l[2]>=-.001)return[NaN,NaN,l[2]];let u=t.focal/-l[2],b=Math.min(c,o)*t.scale*u,f=c*e+l[0]*b*a*t.stretch,d=o*s+l[1]*b;return[f,d,l[2]]}}}import{trianglesToFeatureEdges as Pe}from"@glyphcss/core";var we={direction:[.5,.7,.5],intensity:1},Oe={intensity:.4};function V(n){let t=n.triangles??[],e=n.mode??(t.length?"solid":"wireframe"),s=n.wireframe??(e==="wireframe"?Pe(t):[]);return{camera:n.camera,grid:n.grid,triangles:t,wireframe:s,mode:e,directionalLight:n.directionalLight??we,ambientLight:n.ambientLight??Oe,glyphPalette:n.glyphPalette??"default",useColors:n.useColors??!0}}var ke=" .:-=+*#%@".split(""),Re=" .:-=+*#%@".split(""),F={default:{thin:"\xB7\u22C5\u2219\u02D9\xB7\u22C5\u2219".split(""),normal:"\u254B\u256C\u253C\u2573\u25C6\u25C7\u25CA\u25B2\u25B3\u25BC\u25BD\u25C8\u2B21\u2B22\u2234\u2235\u22A5\u2295\u2297\u2299\u229A\u229B".split(""),core:"\u2726\u2727\u2729\u25C9\u2299\u25CE".split(""),solid:" .:-=+*#%@".split("")},ascii:{thin:".'".split(""),normal:"+*x".split(""),core:"#@".split(""),solid:" .,:;!+=*xX#@".split("")},dots:{thin:"\xB7\u22C5".split(""),normal:"\u2022\u25CF".split(""),core:"\u25C9\u25CE".split(""),solid:" \xB7\u22C5\u2218\u2022\u25CF\u25C9\u25CE\u2B24".split("")},lines:{thin:"\u2500\u2502".split(""),normal:"\u2550\u2551".split(""),core:"\u2588".split(""),solid:" \u2500\u2550\u256C\u2551\u2588\u2593\u2592\u2591".split("")},blocks:{thin:"\u2591\u2581".split(""),normal:"\u2592\u2593\u258C\u2590\u2580\u2584".split(""),core:"\u2588".split(""),solid:" \u2591\u2592\u2593\u258C\u2590\u2588\u2580\u2584\u25A0".split("")},stars:{thin:"\xB7\u22C6".split(""),normal:"\u2726\u2727\u2729\u272A".split(""),core:"\u272B\u272C\u272D\u2605".split(""),solid:" \xB7\u22C6\u2217\u2726\u2727\u2729\u272A\u272B\u2605".split("")},arrows:{thin:"\xB7\u2219".split(""),normal:"\u2190\u2191\u2192\u2193".split(""),core:"\u2196\u2197\u2198\u2199\u2921\u2922".split(""),solid:" \xB7\u2219\u2191\u2197\u2192\u2198\u2193\u2199\u2190\u2196".split("")},braille:{thin:"\u2801\u2802\u2804\u2808".split(""),normal:"\u2803\u2805\u2806\u2809\u280A\u280B\u280C\u280D\u280E\u280F".split(""),core:"\u283F\u28FF".split(""),solid:" \u2801\u2803\u2807\u2827\u2837\u283F\u287F\u28FF".split("")},runes:{thin:".\xB7".split(""),normal:"\u16A0\u16A1\u16A2\u16A3\u16A4\u16A6\u16A8\u16B1\u16B2\u16B3\u16B7\u16B9\u16C3\u16C7\u16C9".split(""),core:"\u16DE\u16DF\u16E1\u16E2\u16E3".split(""),solid:" \xB7\u16A0\u16A3\u16A4\u16A8\u16B1\u16B7\u16DE\u16E2".split("")},math:{thin:"\u2219\u2218".split(""),normal:"\u2211\u220F\u222B\u221A\u221E\u2248\u2260\u2264\u2265\u2282\u2283\u2286\u2287".split(""),core:"\u222E\u222F\u2230\u2202".split(""),solid:" \u2219\u2218\u2211\u222B\u221A\u221E\u2248\u2295\u2297".split("")},binary:{thin:"\xB7.".split(""),normal:"01".split(""),core:"\u2588".split(""),solid:" .:01\u2588\u2588".split("")},hex:{thin:"\xB7\u2219".split(""),normal:"0123456789ABCDEF".split(""),core:"FFAA".split(""),solid:" 0123456789AF".split("")}},Fe=F.default;function I(n){return F[n]??F.default}function Y(n){let{camera:t,grid:e,wireframe:s,triangles:r,mode:c,directionalLight:o,ambientLight:a}=n,{cols:p,rows:l,cellAspect:y}=e;if(c==="solid")return Ie(n,p,l,y);let u=I(n.glyphPalette),b=new Uint8Array(p*l),f=n.useColors?new Array(p*l).fill(null):null;for(let d of s){let M=t.project(d.from,p,l,y),E=t.project(d.to,p,l,y);M[0]!==M[0]||E[0]!==E[0]||ze(b,f,M[0]|0,M[1]|0,E[0]|0,E[1]|0,d.weight??2,d.color??null,p,l)}return Ve(b,f,p,l,u)}function Ie(n,t,e,s){let{camera:r,triangles:c,directionalLight:o,ambientLight:a}=n,p=I(n.glyphPalette).solid,l=new Array(t*e).fill(" "),y=n.useColors,u=y?new Array(t*e).fill(null):null,b=new Float64Array(t*e).fill(-1/0),f=o.direction,d=Math.hypot(f[0],f[1],f[2])||1,M=f[0]/d,E=f[1]/d,T=f[2]/d,h=o.intensity??1,v=a.intensity??.4,G=N(o.color??"#ffffff"),C=N(a.color??"#ffffff");for(let g of c){let[i,x,L]=g.vertices,A=r.project(i,t,e,s),m=r.project(x,t,e,s),S=r.project(L,t,e,s);if(A[0]!==A[0]||m[0]!==m[0]||S[0]!==S[0])continue;let _=x[0]-i[0],P=x[1]-i[1],H=x[2]-i[2],le=L[0]-i[0],ce=L[1]-i[1],ae=L[2]-i[2],pe=P*ae-H*ce,ue=H*le-_*ae,de=_*ce-P*le,be=Math.hypot(pe,ue,de)||1,ve=(pe*M+ue*E+de*T)/be,R=Math.max(0,ve)*h,Ge=Math.min(1,Math.max(0,v+R)),Ee=Math.min(p.length-1,Ge*(p.length-1)|0),Me=p[Ee],he=null;if(y){let X=g.color?N(g.color):[255,255,255],Ce=v*C[0]/255+R*G[0]/255,Le=v*C[1]/255+R*G[1]/255,Ae=v*C[2]/255+R*G[2]/255,Se=Math.min(255,X[0]*Ce),Te=Math.min(255,X[1]*Le),_e=Math.min(255,X[2]*Ae);he=`#${B(Se)}${B(Te)}${B(_e)}`}let xe=(A[2]+m[2]+S[2])/3;Ye(A[0],A[1],m[0],m[1],S[0],S[1],xe,Me,he,l,u,b,t,e)}return Xe(l,u,t,e)}function Ye(n,t,e,s,r,c,o,a,p,l,y,u,b,f){let d=n,M=t,E=e,T=s,h=r,v=c;if(T<M){let g=d;d=E,E=g,g=M,M=T,T=g}if(v<M){let g=d;d=h,h=g,g=M,M=v,v=g}if(v<T){let g=E;E=h,h=g,g=T,T=v,v=g}let G=Math.max(0,Math.ceil(M)),C=Math.min(f-1,Math.floor(v));if(!(G>C))for(let g=G;g<=C;g++){let i=(g-M)/(v-M||1),x=d+(h-d)*i,L;if(g<T){let S=(g-M)/(T-M||1);L=d+(E-d)*S}else{let S=(g-T)/(v-T||1);L=E+(h-E)*S}let A=Math.max(0,Math.ceil(Math.min(x,L))),m=Math.min(b-1,Math.floor(Math.max(x,L)));for(let S=A;S<=m;S++){let _=g*b+S;o>u[_]&&(u[_]=o,l[_]=a,y&&(y[_]=p))}}}function Xe(n,t,e,s){let r=[],c=null,o="",a=()=>{o&&(c!==null?r.push(`<span style="color:${c}">${o}</span>`):r.push(o),o="")};for(let p=0;p<s;p++){for(let l=0;l<e;l++){let y=p*e+l,u=n[y],b=t&&u!==" "?t[y]??null:null;b!==c&&(a(),c=b),o+=u}a(),c=null,p<s-1&&r.push(`
2
+ `)}return r.join("")}function De(n,t,e="y"){let{camera:s}=n,r=e==="y"?s.rotY:s.rotX,c=new Array(t);for(let o=0;o<t;o++){let a=r+o/t*Math.PI*2;e==="y"?s.rotY=a:s.rotX=a,c[o]=Y(n)}return e==="y"?s.rotY=r:s.rotX=r,c}function ze(n,t,e,s,r,c,o,a,p,l){let y=Math.abs(r-e),u=-Math.abs(c-s),b=e<r?1:-1,f=s<c?1:-1,d=y+u;for(;;){if(e>=0&&e<p&&s>=0&&s<l){let E=s*p+e;n[E]<o&&(n[E]=o,t&&(t[E]=a))}if(e===r&&s===c)break;let M=2*d;M>=u&&(d+=u,e+=b),M<=y&&(d+=y,s+=f)}}function Ve(n,t,e,s,r){let c=[],o=null,a="",p=()=>{a&&(o!==null?c.push(`<span style="color:${o}">${a}</span>`):c.push(a),a="")};for(let l=0;l<s;l++){for(let y=0;y<e;y++){let u=l*e+y,b=n[u],f,d;b===0?(f=" ",d=null):(f=b===1?r.thin[Math.random()*r.thin.length|0]:b===2?r.normal[Math.random()*r.normal.length|0]:r.core[Math.random()*r.core.length|0],d=t?t[u]??null:null),d!==o&&(p(),o=d),a+=f}p(),o=null,l<s-1&&c.push(`
3
+ `)}return c.join("")}function N(n){let t=n.startsWith("#")?n.slice(1):n;if(t.length===3){let e=parseInt(t[0]+t[0],16),s=parseInt(t[1]+t[1],16),r=parseInt(t[2]+t[2],16);return[e||0,s||0,r||0]}if(t.length===6){let e=parseInt(t.slice(0,2),16),s=parseInt(t.slice(2,4),16),r=parseInt(t.slice(4,6),16);return[e||0,s||0,r||0]}return[255,255,255]}function B(n){let t=Math.max(0,Math.min(255,n|0)).toString(16);return t.length===1?"0"+t:t}var me="glyphcss-styles";function j(n){let t=n??(typeof document<"u"?document:void 0);if(!t||t.getElementById(me))return;let e=t.createElement("style");e.id=me,e.textContent=Ne,t.head.appendChild(e)}var Ne=`
4
+ /* \u2500\u2500 Glyphcss scene container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
5
+
6
+ .glyphcss-scene {
7
+ position: relative;
8
+ display: block;
9
+ overflow: hidden;
10
+ line-height: 1;
11
+ }
12
+
13
+ /* \u2500\u2500 ASCII output <pre> \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
14
+
15
+ .glyphcss-scene .glyphcss-output {
16
+ display: block;
17
+ margin: 0;
18
+ padding: 0;
19
+ font-family: monospace;
20
+ font-size: inherit;
21
+ line-height: 1;
22
+ white-space: pre;
23
+ overflow: hidden;
24
+ user-select: none;
25
+ -webkit-user-select: none;
26
+ }
27
+
28
+ /* \u2500\u2500 Hotspot overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
29
+
30
+ .glyphcss-scene .glyphcss-hotspot-layer {
31
+ position: absolute;
32
+ inset: 0;
33
+ pointer-events: none;
34
+ }
35
+
36
+ .glyphcss-scene .glyphcss-hotspot {
37
+ position: absolute;
38
+ pointer-events: all;
39
+ cursor: pointer;
40
+ }
41
+ `;function W(n,t,e,s,r){return n.map(c=>{let[o,a,p]=t.project(c.at,e,s,r),l=p>-3&&o>=0&&o<e&&a>=0&&a<s;return{id:c.id,col:o,row:a,depth:p,visible:l}})}var Be=1;function je(n,t){let{position:e,scale:s,rotation:r}=t;if(!e&&!s&&!r)return n;let[c,o,a]=e??[0,0,0],p=1,l=1,y=1;s!==void 0&&(typeof s=="number"?p=l=y=s:[p,l,y]=s);let[u,b,f]=r??[0,0,0],d=Math.cos(u),M=Math.sin(u),E=Math.cos(b),T=Math.sin(b),h=Math.cos(f),v=Math.sin(f);function G(C){let g=C[0]*p,i=C[1]*l,x=C[2]*y,L=h*g-v*i,A=v*g+h*i,m=x;return g=E*L+T*m,i=A,x=-T*L+E*m,L=g,A=d*i-M*x,m=M*i+d*x,[L+c,A+o,m+a]}return n.map(C=>({...C,vertices:[G(C.vertices[0]),G(C.vertices[1]),G(C.vertices[2])]}))}function U(n,t={}){j(n.ownerDocument??void 0);let e={mode:t.mode??"solid",glyphPalette:t.glyphPalette??"default",useColors:t.useColors??!0,cols:t.cols??80,rows:t.rows??24,cellAspect:t.cellAspect??2,directionalLight:t.directionalLight??{direction:[.5,.7,.5],intensity:1},ambientLight:t.ambientLight??{intensity:.4},camera:t.camera??w()},s=n.ownerDocument.createElement("div");s.className="glyphcss-scene";let r=n.ownerDocument.createElement("pre");r.className="glyphcss-output";let c=n.ownerDocument.createElement("div");c.className="glyphcss-hotspot-layer",s.appendChild(r),s.appendChild(c),n.appendChild(s);let o=new Map,a=[],p=!1;function l(){p||(p=!0,Promise.resolve().then(()=>{p=!1,y()}))}function y(){let h=[];for(let C of o.values()){let g=je(C.triangles,C.transform);for(let i of g)h.push(i)}let v=V({camera:e.camera,grid:{cols:e.cols,rows:e.rows,cellAspect:e.cellAspect},triangles:h,mode:e.mode,directionalLight:e.directionalLight,ambientLight:e.ambientLight,glyphPalette:e.glyphPalette,useColors:e.useColors}),G=Y(v);e.useColors?r.innerHTML=G:r.textContent=G,u()}function u(){let{cols:h,rows:v,cellAspect:G,camera:C}=e,g=W(a.map(A=>A.hotspot),C,h,v,G),i=r.getBoundingClientRect(),x=h>0?i.width/h:8,L=v>0?i.height/v:16;for(let A=0;A<a.length;A++){let{el:m}=a[A],S=g[A];S.visible?(m.style.display="",m.style.left=`${S.col*x}px`,m.style.top=`${S.row*L}px`,m.style.zIndex=String(Math.round(S.depth*1e3))):m.style.display="none"}}function b(h,v={}){let G=Be++;return o.set(G,{id:G,triangles:h,transform:v}),l(),{get id(){return G},get triangles(){return h},setTransform(C){let g=o.get(G);g&&(g.transform=C,l())},dispose(){o.delete(G),l()}}}function f(h,v){let G=n.ownerDocument.createElement("div");G.className="glyphcss-hotspot",G.setAttribute("data-hotspot-id",h.id);let[C,g]=h.size??[1,1];G.style.position="absolute",G.style.width=`${C}ch`,G.style.height=`${g*e.cellAspect}ch`,v&&G.addEventListener("click",v),c.appendChild(G);let i={hotspot:{id:h.id,at:h.at,size:h.size},el:G,onClick:v};return a.push(i),l(),{remove(){let x=a.indexOf(i);x>=0&&a.splice(x,1),v&&G.removeEventListener("click",v),c.removeChild(G),l()}}}function d(){y()}function M(h){h.mode!==void 0&&(e.mode=h.mode),h.glyphPalette!==void 0&&(e.glyphPalette=h.glyphPalette),h.useColors!==void 0&&(e.useColors=h.useColors),h.cols!==void 0&&(e.cols=h.cols),h.rows!==void 0&&(e.rows=h.rows),h.cellAspect!==void 0&&(e.cellAspect=h.cellAspect),h.directionalLight!==void 0&&(e.directionalLight=h.directionalLight),h.ambientLight!==void 0&&(e.ambientLight=h.ambientLight),h.camera!==void 0&&(e.camera=h.camera),l()}function E(){return{...e}}function T(){o.clear(),n.contains(s)&&n.removeChild(s)}return l(),{get host(){return n},get output(){return r},get camera(){return e.camera},add:b,addHotspot:f,rerender:d,setOptions:M,getOptions:E,destroy:T}}function q(n,t={}){let e=n.host,s=t.drag??!0,r=t.wheel??!0,c=fe(t.invert),o=t.animate??!1,a=!1,p=!1,l=null,y=null,u=null,b={x:0,y:0},f=n.camera;function d(i){if(!(!s||a)&&u===null&&i.isPrimary!==!1){i.preventDefault(),u=i.pointerId,b={x:i.clientX,y:i.clientY},e.style.cursor="grabbing";try{i.target.setPointerCapture(i.pointerId)}catch{}o&&o.pauseOnInteraction!==!1&&(p=!0)}}function M(i){if(u===null||i.pointerId!==u||!s||a)return;i.preventDefault();let x=i.clientX-b.x,L=i.clientY-b.y;b={x:i.clientX,y:i.clientY};let A=c,S=1/4*Math.PI/180;f.rotY=f.rotY-x*S*A,f.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,f.rotX+L*S*A)),n.rerender()}function E(i){if(u===i.pointerId){u=null,e.style.cursor=s&&!a?"grab":"";try{i.target.releasePointerCapture(i.pointerId)}catch{}o&&(p=!1)}}function T(i){if(!r||a)return;i.preventDefault();let x=i.deltaY*.001;f.scale=Math.max(.05,Math.min(10,f.scale*(1-x))),n.rerender()}function h(i){if(!(a||!o)){if(!p){let x=y!==null?Math.min(i-y,50):16.67,L=typeof o=="object"&&o.speed?o.speed:.3,A=typeof o=="object"&&o.axis?o.axis:"y",m=L*(Math.PI/180)*(x/16.67);A==="y"?f.rotY=f.rotY+m:f.rotX=f.rotX+m,n.rerender()}y=i,l=requestAnimationFrame(h)}}function v(){l===null&&typeof requestAnimationFrame<"u"&&o&&(l=requestAnimationFrame(h))}function G(){l!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(l),l=null),y=null}function C(){e.addEventListener("pointerdown",d),e.addEventListener("pointermove",M),e.addEventListener("pointerup",E),e.addEventListener("pointercancel",E),e.addEventListener("wheel",T,{passive:!1}),e.style.cursor=s?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function g(){e.removeEventListener("pointerdown",d),e.removeEventListener("pointermove",M),e.removeEventListener("pointerup",E),e.removeEventListener("pointercancel",E),e.removeEventListener("wheel",T),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return C(),v(),{update(i){let x=!!o;s=i.drag??s,r=i.wheel??r,c=fe(i.invert),o=i.animate??o,!a&&u===null&&(e.style.cursor=s?"grab":"");let L=!!o;x&&!L?G():!x&&L&&v()},pause(){a||(a=!0,g(),G(),u=null,p=!1)},resume(){a&&(a=!1,C(),v())},destroy(){a||g(),G(),a=!0}}}function fe(n){return n===void 0||n===!1?1:n===!0?-1:n}function $(n,t={}){let e=n.host,s=t.drag??!0,r=t.wheel??!0,c=ye(t.invert),o=t.animate??!1,a=!1,p=!1,l=null,y=null,u=null,b={x:0,y:0},f=!1,d=n.camera,M=1/4*Math.PI/180,E=.02;function T(m){if(!(!s||a)&&u===null&&m.isPrimary!==!1){m.preventDefault(),u=m.pointerId,b={x:m.clientX,y:m.clientY},f=m.button===2,e.style.cursor="grabbing";try{m.target.setPointerCapture(m.pointerId)}catch{}o&&o.pauseOnInteraction!==!1&&(p=!0)}}function h(m){if(u===null||m.pointerId!==u||!s||a)return;m.preventDefault();let S=m.clientX-b.x,_=m.clientY-b.y;b={x:m.clientX,y:m.clientY};let P=c;if(f||m.shiftKey)d.rotY=d.rotY-S*M*P,d.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,d.rotX+_*M*P));else{let H=d.target;d.target=[H[0]-S*E/d.scale,H[1]-_*E/d.scale,H[2]]}n.rerender()}function v(m){if(u===m.pointerId){u=null,f=!1,e.style.cursor=s&&!a?"grab":"";try{m.target.releasePointerCapture(m.pointerId)}catch{}o&&(p=!1)}}function G(m){m.preventDefault()}function C(m){if(!r||a)return;m.preventDefault();let S=m.deltaY*.001;d.scale=Math.max(.05,Math.min(10,d.scale*(1-S))),n.rerender()}function g(m){if(!(a||!o)){if(!p){let S=y!==null?Math.min(m-y,50):16.67,_=typeof o=="object"&&o.speed?o.speed:.3,P=typeof o=="object"&&o.axis?o.axis:"y",H=_*(Math.PI/180)*(S/16.67);P==="y"?d.rotY=d.rotY+H:d.rotX=d.rotX+H,n.rerender()}y=m,l=requestAnimationFrame(g)}}function i(){l===null&&typeof requestAnimationFrame<"u"&&o&&(l=requestAnimationFrame(g))}function x(){l!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(l),l=null),y=null}function L(){e.addEventListener("pointerdown",T),e.addEventListener("pointermove",h),e.addEventListener("pointerup",v),e.addEventListener("pointercancel",v),e.addEventListener("contextmenu",G),e.addEventListener("wheel",C,{passive:!1}),e.style.cursor=s?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function A(){e.removeEventListener("pointerdown",T),e.removeEventListener("pointermove",h),e.removeEventListener("pointerup",v),e.removeEventListener("pointercancel",v),e.removeEventListener("contextmenu",G),e.removeEventListener("wheel",C),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return L(),i(),{update(m){let S=!!o;s=m.drag??s,r=m.wheel??r,c=ye(m.invert),o=m.animate??o,!a&&u===null&&(e.style.cursor=s?"grab":"");let _=!!o;S&&!_?x():!S&&_&&i()},pause(){a||(a=!0,A(),x(),u=null,p=!1)},resume(){a&&(a=!1,L(),i())},destroy(){a||A(),x(),a=!0}}}function ye(n){return n===void 0||n===!1?1:n===!0?-1:n}function We(n,t={}){let e=n.host,s=t.drag??!0,r=t.keyboard??!0,c=t.moveSpeed??.05,o=t.lookSpeed??.004,a=ge(t.invert),p=!1,l=null,y={x:0,y:0},u=new Set,b=null,f=n.camera;function d(i){if(!(!s||p)&&l===null){i.preventDefault(),l=i.pointerId,y={x:i.clientX,y:i.clientY};try{i.target.setPointerCapture(i.pointerId)}catch{}}}function M(i){if(l===null||i.pointerId!==l||!s||p)return;i.preventDefault();let x=i.clientX-y.x,L=i.clientY-y.y;y={x:i.clientX,y:i.clientY},f.rotY=f.rotY-x*o*a,f.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,f.rotX+L*o*a)),n.rerender()}function E(i){if(l===i.pointerId){l=null;try{i.target.releasePointerCapture(i.pointerId)}catch{}}}function T(i){r&&!p&&u.add(i.key.toLowerCase())}function h(i){u.delete(i.key.toLowerCase())}function v(){if(p||!r||u.size===0)return;let i=f.target,x=Math.cos(f.rotY),L=Math.sin(f.rotY),A=!1;(u.has("w")||u.has("arrowup"))&&(f.target=[i[0]-L*c,i[1]-x*c,i[2]],A=!0),(u.has("s")||u.has("arrowdown"))&&(f.target=[i[0]+L*c,i[1]+x*c,i[2]],A=!0),(u.has("a")||u.has("arrowleft"))&&(f.target=[i[0]-x*c,i[1]+L*c,i[2]],A=!0),(u.has("d")||u.has("arrowright"))&&(f.target=[i[0]+x*c,i[1]-L*c,i[2]],A=!0),A&&n.rerender()}function G(){p||(v(),b=requestAnimationFrame(G))}function C(){e.addEventListener("pointerdown",d),e.addEventListener("pointermove",M),e.addEventListener("pointerup",E),e.addEventListener("pointercancel",E),r&&(e.ownerDocument?.addEventListener("keydown",T),e.ownerDocument?.addEventListener("keyup",h)),e.style.touchAction="none",e.style.userSelect="none",typeof requestAnimationFrame<"u"&&(b=requestAnimationFrame(G))}function g(){e.removeEventListener("pointerdown",d),e.removeEventListener("pointermove",M),e.removeEventListener("pointerup",E),e.removeEventListener("pointercancel",E),e.ownerDocument?.removeEventListener("keydown",T),e.ownerDocument?.removeEventListener("keyup",h),e.style.touchAction="",e.style.userSelect="",b!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(b),b=null),u.clear()}return C(),{update(i){s=i.drag??s,r=i.keyboard??r,c=i.moveSpeed??c,o=i.lookSpeed??o,a=ge(i.invert)},pause(){p||(p=!0,g(),l=null)},resume(){p&&(p=!1,C())},destroy(){p||g(),p=!0}}}function ge(n){return n===void 0||n===!1?1:n===!0?-1:n}var Ue=typeof HTMLElement<"u"?HTMLElement:class{},qe=["mode","glyph-palette","use-colors","cols","rows","cell-aspect","directional-direction","directional-intensity","ambient-intensity"];function O(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function $e(n){if(n==="wireframe"||n==="solid"||n==="voxel")return n}function Ze(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}var Z=class extends Ue{constructor(){super(...arguments);this._scene=null}static get observedAttributes(){return[...qe]}getScene(){return this._scene}_readOptions(){let e={},s=$e(this.getAttribute("mode"));s!==void 0&&(e.mode=s);let r=this.getAttribute("glyph-palette");r&&(e.glyphPalette=r);let c=Ze(this.getAttribute("use-colors"));c!==void 0&&(e.useColors=c);let o=O(this.getAttribute("cols"));o!==void 0&&(e.cols=o);let a=O(this.getAttribute("rows"));a!==void 0&&(e.rows=a);let p=O(this.getAttribute("cell-aspect"));p!==void 0&&(e.cellAspect=p);let l=O(this.getAttribute("directional-intensity"));l!==void 0&&(e.directionalLight={direction:[.5,.7,.5],intensity:l});let y=O(this.getAttribute("ambient-intensity"));return y!==void 0&&(e.ambientLight={intensity:y}),e}connectedCallback(){this._scene||(this._scene=U(this,this._readOptions()),this.dispatchEvent(new CustomEvent("glyphcss:scene-ready",{bubbles:!1})))}disconnectedCallback(){this._scene&&(this._scene.destroy(),this._scene=null)}attributeChangedCallback(e,s,r){s!==r&&this._scene&&this._scene.setOptions(this._readOptions())}};import{loadMesh as Ke}from"@glyphcss/core";var Je=typeof HTMLElement<"u"?HTMLElement:class{},Qe=["src","position","scale","rotation"];function K(n){if(!n)return;let t=n.split(",").map(e=>parseFloat(e.trim()));if(!(t.length!==3||t.some(e=>!Number.isFinite(e))))return[t[0],t[1],t[2]]}function et(n){if(n){if(!n.includes(",")){let t=parseFloat(n);return Number.isFinite(t)?t:void 0}return K(n)}}function tt(n){return n.closest("glyphcss-scene")??null}function nt(n){let t=[[0,0],[0,0],[0,0]],e=[];for(let s of n){let r=s.vertices;if(!(r.length<3))for(let c=1;c<r.length-1;c++)e.push({vertices:[r[0],r[c],r[c+1]],uvs:t,...s.color?{color:s.color}:{}})}return e}var J=class extends Je{constructor(){super(...arguments);this._handle=null;this._loadToken=0}static get observedAttributes(){return[...Qe]}getMeshHandle(){return this._handle}connectedCallback(){this._maybeLoad()}disconnectedCallback(){this._tearDown()}attributeChangedCallback(e,s,r){if(s!==r){if(e==="src"){this._tearDown(),this._maybeLoad();return}this._handle&&this._handle.setTransform(this._readTransform())}}_readTransform(){return{position:K(this.getAttribute("position")),scale:et(this.getAttribute("scale")),rotation:K(this.getAttribute("rotation"))}}_tearDown(){if(this._loadToken+=1,this._handle){try{this._handle.dispose()}catch{}this._handle=null}}async _maybeLoad(){let e=this.getAttribute("src");if(!e)return;let s=tt(this);if(!s)return;let r=++this._loadToken,c;try{c=await Ke(e)}catch(p){this.dispatchEvent(new CustomEvent("glyphcss:error",{detail:p,bubbles:!0}));return}if(r!==this._loadToken){try{c.dispose()}catch{}return}let o=s.getScene();if(!o){try{c.dispose()}catch{}return}let a=nt(c.polygons);this._handle=o.add(a,this._readTransform()),this.dispatchEvent(new CustomEvent("glyphcss:loaded",{detail:{triangles:a},bubbles:!0}))}};var rt=typeof HTMLElement<"u"?HTMLElement:class{};function st(n){if(!n)return;let t=n.split(",").map(e=>parseFloat(e.trim()));if(!(t.length!==3||t.some(e=>!Number.isFinite(e))))return[t[0],t[1],t[2]]}function ot(n){if(!n)return;let t=n.split(",").map(e=>parseFloat(e.trim()));if(!(t.length!==2||t.some(e=>!Number.isFinite(e))))return[t[0],t[1]]}function it(n){return n.closest("glyphcss-scene")??null}var Q=class extends rt{constructor(){super(...arguments);this._handle=null}static get observedAttributes(){return["at","size","hotspot-id"]}connectedCallback(){this._register()}disconnectedCallback(){this._handle&&(this._handle.remove(),this._handle=null)}attributeChangedCallback(e,s,r){s!==r&&(this._handle&&(this._handle.remove(),this._handle=null),this._register())}_register(){let e=st(this.getAttribute("at"));if(!e)return;let r=it(this)?.getScene();if(!r)return;let c=this.getAttribute("hotspot-id")??this.getAttribute("id")??String(Math.random()),o=ot(this.getAttribute("size"));this._handle=r.addHotspot({id:c,at:e,size:o},()=>this.dispatchEvent(new CustomEvent("glyphcss:hotspot-click",{detail:{id:c},bubbles:!0})))}};var lt=typeof HTMLElement<"u"?HTMLElement:class{};function k(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function ct(n){return n.closest("glyphcss-scene")??null}var ee=class extends lt{static get observedAttributes(){return["rot-x","rot-y","distance","scale","stretch"]}connectedCallback(){this._apply()}attributeChangedCallback(t,e,s){e!==s&&this._apply()}_apply(){let e=ct(this)?.getScene();if(!e)return;let s=w({rotX:k(this.getAttribute("rot-x")),rotY:k(this.getAttribute("rot-y")),distance:k(this.getAttribute("distance")),scale:k(this.getAttribute("scale")),stretch:k(this.getAttribute("stretch"))});e.setOptions({camera:s})}};var at=typeof HTMLElement<"u"?HTMLElement:class{};function te(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function pt(n){return n.closest("glyphcss-scene")??null}var ne=class extends at{static get observedAttributes(){return["rot-x","rot-y","zoom"]}connectedCallback(){this._apply()}attributeChangedCallback(t,e,s){e!==s&&this._apply()}_apply(){let e=pt(this)?.getScene();if(!e)return;let s=z({rotX:te(this.getAttribute("rot-x")),rotY:te(this.getAttribute("rot-y")),zoom:te(this.getAttribute("zoom"))});e.setOptions({camera:s})}};var ut=typeof HTMLElement<"u"?HTMLElement:class{};function dt(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function re(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function ht(n){return n.closest("glyphcss-scene")??null}var se=class extends ut{constructor(){super(...arguments);this._controls=null}static get observedAttributes(){return["drag","wheel","invert","animate-speed","animate-axis"]}connectedCallback(){this._attach()}disconnectedCallback(){this._controls&&(this._controls.destroy(),this._controls=null)}attributeChangedCallback(e,s,r){s!==r&&this._controls?.update(this._readOptions())}_readOptions(){let e=re(this.getAttribute("drag")),s=re(this.getAttribute("wheel")),r=re(this.getAttribute("invert")),c=dt(this.getAttribute("animate-speed")),o=this.getAttribute("animate-axis")==="x"?"x":"y";return{...e!==void 0?{drag:e}:{},...s!==void 0?{wheel:s}:{},...r!==void 0?{invert:r}:{},...c!==void 0?{animate:{speed:c,axis:o}}:{}}}_attach(){if(this._controls)return;let e=ht(this);if(!e)return;let s=e.getScene();if(!s){let r=()=>{e.removeEventListener("glyphcss:scene-ready",r),this._attach()};e.addEventListener("glyphcss:scene-ready",r);return}this._controls=q(s,this._readOptions())}};var mt=typeof HTMLElement<"u"?HTMLElement:class{};function oe(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function ft(n){return n.closest("glyphcss-scene")??null}var ie=class extends mt{constructor(){super(...arguments);this._controls=null}static get observedAttributes(){return["drag","wheel","invert"]}connectedCallback(){this._attach()}disconnectedCallback(){this._controls&&(this._controls.destroy(),this._controls=null)}attributeChangedCallback(e,s,r){s!==r&&this._controls?.update(this._readOptions())}_readOptions(){let e=oe(this.getAttribute("drag")),s=oe(this.getAttribute("wheel")),r=oe(this.getAttribute("invert"));return{...e!==void 0?{drag:e}:{},...s!==void 0?{wheel:s}:{},...r!==void 0?{invert:r}:{}}}_attach(){if(this._controls)return;let e=ft(this);if(!e)return;let s=e.getScene();if(!s){let r=()=>{e.removeEventListener("glyphcss:scene-ready",r),this._attach()};e.addEventListener("glyphcss:scene-ready",r);return}this._controls=$(s,this._readOptions())}};export*from"@glyphcss/core";export{ke as DEFAULT_RAMP,Q as GlyphcssHotspotElement,ie as GlyphcssMapControlsElement,J as GlyphcssMeshElement,se as GlyphcssOrbitControlsElement,ne as GlyphcssOrthographicCameraElement,ee as GlyphcssPerspectiveCameraElement,Z as GlyphcssSceneElement,Re as SOLID_RAMP,Fe as WIREFRAME_GLYPHS,F as WIREFRAME_PALETTES,De as bakeFrames,V as buildRasterizeContext,He as createGlyphcssFirstPersonCamera,We as createGlyphcssFirstPersonControls,$ as createGlyphcssMapControls,q as createGlyphcssOrbitControls,z as createGlyphcssOrthographicCamera,w as createGlyphcssPerspectiveCamera,U as createGlyphcssScene,I as getWireframeGlyphs,j as injectGlyphcssBaseStyles,W as projectHotspots,Y as rasterize};
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "glyphcss",
3
+ "version": "0.0.1",
4
+ "description": "Glyphcss — ASCII paint backend with polycss's scene-composition API. Renders 3D meshes as ASCII art in a <pre> element.",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "keywords": [
10
+ "glyphcss",
11
+ "ascii",
12
+ "3d",
13
+ "mesh",
14
+ "terminal",
15
+ "dom",
16
+ "custom-elements",
17
+ "vanilla"
18
+ ],
19
+ "license": "MIT",
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "require": "./dist/index.cjs"
28
+ },
29
+ "./elements": {
30
+ "types": "./dist/elements.d.ts",
31
+ "import": "./dist/elements.js",
32
+ "require": "./dist/elements.cjs"
33
+ }
34
+ },
35
+ "dependencies": {
36
+ "@glyphcss/core": "^0.0.1"
37
+ },
38
+ "devDependencies": {
39
+ "tsup": "^8.0.1",
40
+ "typescript": "^5.3.3",
41
+ "vitest": "^3.1.1",
42
+ "vite": "^6.0.0",
43
+ "@vitest/coverage-v8": "^3.1.1",
44
+ "happy-dom": "^20.7.0"
45
+ },
46
+ "scripts": {
47
+ "build": "tsup",
48
+ "test": "vitest run --passWithNoTests",
49
+ "test:coverage": "vitest run --coverage --passWithNoTests"
50
+ }
51
+ }