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/LICENSE +21 -0
- package/dist/elements-Bb37NHHO.d.cts +269 -0
- package/dist/elements-Bb37NHHO.d.ts +269 -0
- package/dist/elements.cjs +41 -0
- package/dist/elements.d.cts +2 -0
- package/dist/elements.d.ts +2 -0
- package/dist/elements.js +41 -0
- package/dist/index.cjs +41 -0
- package/dist/index.d.cts +177 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.js +41 -0
- package/package.json +51 -0
package/dist/elements.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
function ie(n,t,e){let r=Math.cos(t),s=Math.sin(t),c=r*n[1]-s*n[0],i=s*n[1]+r*n[0],o=n[2],a=Math.cos(e),l=Math.sin(e),f=a*i-l*o,m=l*i+a*o;return[c,f,m]}function I(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,r]=n.center??[.5,.5];return{kind:"perspective",get rotX(){return t.rotX},set rotX(s){t.rotX=s},get rotY(){return t.rotY},set rotY(s){t.rotY=s},get distance(){return t.distance},set distance(s){t.distance=s},get scale(){return t.scale},set scale(s){t.scale=s},get stretch(){return t.stretch},set stretch(s){t.stretch=s},get target(){return t.target},set target(s){t.target=s},project(s,c,i,o){let a=[s[0]-t.target[0],s[1]-t.target[1],s[2]-t.target[2]],l=ie(a,t.rotY,t.rotX),f=30,m=1.5,E=l[2]*f,g=.001,h=1-E/t.distance;if(h<g)return[NaN,NaN,l[2]];let G=1/h,M=Math.min(c,i)*t.scale*m*G,_=c*e+l[0]*M*o*t.stretch,d=i*r+l[1]*M;return[_,d,l[2]]}}}function oe(n={}){let t={rotX:n.rotX??0,rotY:n.rotY??0,distance:0,scale:n.zoom??.4,stretch:1,target:[0,0,0]},[e,r]=n.center??[.5,.5];return{kind:"orthographic",get rotX(){return t.rotX},set rotX(s){t.rotX=s},get rotY(){return t.rotY},set rotY(s){t.rotY=s},get distance(){return t.distance},set distance(s){t.distance=s},get scale(){return t.scale},set scale(s){t.scale=s},get stretch(){return t.stretch},set stretch(s){t.stretch=s},get target(){return t.target},set target(s){t.target=s},project(s,c,i,o){let a=[s[0]-t.target[0],s[1]-t.target[1],s[2]-t.target[2]],l=ie(a,t.rotY,t.rotX),m=Math.min(c,i)*t.scale*1.5,E=c*e+l[0]*m*o*t.stretch,g=i*r+l[1]*m;return[E,g,l[2]]}}}import{trianglesToFeatureEdges as Se}from"@glyphcss/core";var He={direction:[.5,.7,.5],intensity:1},we={intensity:.4};function le(n){let t=n.triangles??[],e=n.mode??(t.length?"solid":"wireframe"),r=n.wireframe??(e==="wireframe"?Se(t):[]);return{camera:n.camera,grid:n.grid,triangles:t,wireframe:r,mode:e,directionalLight:n.directionalLight??He,ambientLight:n.ambientLight??we,glyphPalette:n.glyphPalette??"default",useColors:n.useColors??!0}}var dt=" .:-=+*#%@".split(""),ht=" .:-=+*#%@".split(""),B={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("")}},mt=B.default;function j(n){return B[n]??B.default}function ce(n){let{camera:t,grid:e,wireframe:r,triangles:s,mode:c,directionalLight:i,ambientLight:o}=n,{cols:a,rows:l,cellAspect:f}=e;if(c==="solid")return Pe(n,a,l,f);let m=j(n.glyphPalette),E=new Uint8Array(a*l),g=n.useColors?new Array(a*l).fill(null):null;for(let h of r){let G=t.project(h.from,a,l,f),M=t.project(h.to,a,l,f);G[0]!==G[0]||M[0]!==M[0]||Ie(E,g,G[0]|0,G[1]|0,M[0]|0,M[1]|0,h.weight??2,h.color??null,a,l)}return ke(E,g,a,l,m)}function Pe(n,t,e,r){let{camera:s,triangles:c,directionalLight:i,ambientLight:o}=n,a=j(n.glyphPalette).solid,l=new Array(t*e).fill(" "),f=n.useColors,m=f?new Array(t*e).fill(null):null,E=new Float64Array(t*e).fill(-1/0),g=i.direction,h=Math.hypot(g[0],g[1],g[2])||1,G=g[0]/h,M=g[1]/h,_=g[2]/h,d=i.intensity??1,b=o.intensity??.4,v=W(i.color??"#ffffff"),L=W(o.color??"#ffffff");for(let y of c){let[u,C,A]=y.vertices,T=s.project(u,t,e,r),p=s.project(C,t,e,r),x=s.project(A,t,e,r);if(T[0]!==T[0]||p[0]!==p[0]||x[0]!==x[0])continue;let S=C[0]-u[0],w=C[1]-u[1],H=C[2]-u[2],J=A[0]-u[0],Q=A[1]-u[1],ee=A[2]-u[2],te=w*ee-H*Q,ne=H*J-S*ee,se=S*Q-w*J,ge=Math.hypot(te,ne,se)||1,be=(te*G+ne*M+se*_)/ge,R=Math.max(0,be)*d,ve=Math.min(1,Math.max(0,b+R)),Ee=Math.min(a.length-1,ve*(a.length-1)|0),Ge=a[Ee],re=null;if(f){let D=y.color?W(y.color):[255,255,255],xe=b*L[0]/255+R*v[0]/255,Le=b*L[1]/255+R*v[1]/255,Ce=b*L[2]/255+R*v[2]/255,Ae=Math.min(255,D[0]*xe),Te=Math.min(255,D[1]*Le),_e=Math.min(255,D[2]*Ce);re=`#${U(Ae)}${U(Te)}${U(_e)}`}let Me=(T[2]+p[2]+x[2])/3;Oe(T[0],T[1],p[0],p[1],x[0],x[1],Me,Ge,re,l,m,E,t,e)}return Re(l,m,t,e)}function Oe(n,t,e,r,s,c,i,o,a,l,f,m,E,g){let h=n,G=t,M=e,_=r,d=s,b=c;if(_<G){let y=h;h=M,M=y,y=G,G=_,_=y}if(b<G){let y=h;h=d,d=y,y=G,G=b,b=y}if(b<_){let y=M;M=d,d=y,y=_,_=b,b=y}let v=Math.max(0,Math.ceil(G)),L=Math.min(g-1,Math.floor(b));if(!(v>L))for(let y=v;y<=L;y++){let u=(y-G)/(b-G||1),C=h+(d-h)*u,A;if(y<_){let x=(y-G)/(_-G||1);A=h+(M-h)*x}else{let x=(y-_)/(b-_||1);A=M+(d-M)*x}let T=Math.max(0,Math.ceil(Math.min(C,A))),p=Math.min(E-1,Math.floor(Math.max(C,A)));for(let x=T;x<=p;x++){let S=y*E+x;i>m[S]&&(m[S]=i,l[S]=o,f&&(f[S]=a))}}}function Re(n,t,e,r){let s=[],c=null,i="",o=()=>{i&&(c!==null?s.push(`<span style="color:${c}">${i}</span>`):s.push(i),i="")};for(let a=0;a<r;a++){for(let l=0;l<e;l++){let f=a*e+l,m=n[f],E=t&&m!==" "?t[f]??null:null;E!==c&&(o(),c=E),i+=m}o(),c=null,a<r-1&&s.push(`
|
|
2
|
+
`)}return s.join("")}function Ie(n,t,e,r,s,c,i,o,a,l){let f=Math.abs(s-e),m=-Math.abs(c-r),E=e<s?1:-1,g=r<c?1:-1,h=f+m;for(;;){if(e>=0&&e<a&&r>=0&&r<l){let M=r*a+e;n[M]<i&&(n[M]=i,t&&(t[M]=o))}if(e===s&&r===c)break;let G=2*h;G>=m&&(h+=m,e+=E),G<=f&&(h+=f,r+=g)}}function ke(n,t,e,r,s){let c=[],i=null,o="",a=()=>{o&&(i!==null?c.push(`<span style="color:${i}">${o}</span>`):c.push(o),o="")};for(let l=0;l<r;l++){for(let f=0;f<e;f++){let m=l*e+f,E=n[m],g,h;E===0?(g=" ",h=null):(g=E===1?s.thin[Math.random()*s.thin.length|0]:E===2?s.normal[Math.random()*s.normal.length|0]:s.core[Math.random()*s.core.length|0],h=t?t[m]??null:null),h!==i&&(a(),i=h),o+=g}a(),i=null,l<r-1&&c.push(`
|
|
3
|
+
`)}return c.join("")}function W(n){let t=n.startsWith("#")?n.slice(1):n;if(t.length===3){let e=parseInt(t[0]+t[0],16),r=parseInt(t[1]+t[1],16),s=parseInt(t[2]+t[2],16);return[e||0,r||0,s||0]}if(t.length===6){let e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),s=parseInt(t.slice(4,6),16);return[e||0,r||0,s||0]}return[255,255,255]}function U(n){let t=Math.max(0,Math.min(255,n|0)).toString(16);return t.length===1?"0"+t:t}var ae="glyphcss-styles";function ue(n){let t=n??(typeof document<"u"?document:void 0);if(!t||t.getElementById(ae))return;let e=t.createElement("style");e.id=ae,e.textContent=Ye,t.head.appendChild(e)}var Ye=`
|
|
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 pe(n,t,e,r,s){return n.map(c=>{let[i,o,a]=t.project(c.at,e,r,s),l=a>-3&&i>=0&&i<e&&o>=0&&o<r;return{id:c.id,col:i,row:o,depth:a,visible:l}})}var Fe=1;function Xe(n,t){let{position:e,scale:r,rotation:s}=t;if(!e&&!r&&!s)return n;let[c,i,o]=e??[0,0,0],a=1,l=1,f=1;r!==void 0&&(typeof r=="number"?a=l=f=r:[a,l,f]=r);let[m,E,g]=s??[0,0,0],h=Math.cos(m),G=Math.sin(m),M=Math.cos(E),_=Math.sin(E),d=Math.cos(g),b=Math.sin(g);function v(L){let y=L[0]*a,u=L[1]*l,C=L[2]*f,A=d*y-b*u,T=b*y+d*u,p=C;return y=M*A+_*p,u=T,C=-_*A+M*p,A=y,T=h*u-G*C,p=G*u+h*C,[A+c,T+i,p+o]}return n.map(L=>({...L,vertices:[v(L.vertices[0]),v(L.vertices[1]),v(L.vertices[2])]}))}function de(n,t={}){ue(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??I()},r=n.ownerDocument.createElement("div");r.className="glyphcss-scene";let s=n.ownerDocument.createElement("pre");s.className="glyphcss-output";let c=n.ownerDocument.createElement("div");c.className="glyphcss-hotspot-layer",r.appendChild(s),r.appendChild(c),n.appendChild(r);let i=new Map,o=[],a=!1;function l(){a||(a=!0,Promise.resolve().then(()=>{a=!1,f()}))}function f(){let d=[];for(let L of i.values()){let y=Xe(L.triangles,L.transform);for(let u of y)d.push(u)}let b=le({camera:e.camera,grid:{cols:e.cols,rows:e.rows,cellAspect:e.cellAspect},triangles:d,mode:e.mode,directionalLight:e.directionalLight,ambientLight:e.ambientLight,glyphPalette:e.glyphPalette,useColors:e.useColors}),v=ce(b);e.useColors?s.innerHTML=v:s.textContent=v,m()}function m(){let{cols:d,rows:b,cellAspect:v,camera:L}=e,y=pe(o.map(T=>T.hotspot),L,d,b,v),u=s.getBoundingClientRect(),C=d>0?u.width/d:8,A=b>0?u.height/b:16;for(let T=0;T<o.length;T++){let{el:p}=o[T],x=y[T];x.visible?(p.style.display="",p.style.left=`${x.col*C}px`,p.style.top=`${x.row*A}px`,p.style.zIndex=String(Math.round(x.depth*1e3))):p.style.display="none"}}function E(d,b={}){let v=Fe++;return i.set(v,{id:v,triangles:d,transform:b}),l(),{get id(){return v},get triangles(){return d},setTransform(L){let y=i.get(v);y&&(y.transform=L,l())},dispose(){i.delete(v),l()}}}function g(d,b){let v=n.ownerDocument.createElement("div");v.className="glyphcss-hotspot",v.setAttribute("data-hotspot-id",d.id);let[L,y]=d.size??[1,1];v.style.position="absolute",v.style.width=`${L}ch`,v.style.height=`${y*e.cellAspect}ch`,b&&v.addEventListener("click",b),c.appendChild(v);let u={hotspot:{id:d.id,at:d.at,size:d.size},el:v,onClick:b};return o.push(u),l(),{remove(){let C=o.indexOf(u);C>=0&&o.splice(C,1),b&&v.removeEventListener("click",b),c.removeChild(v),l()}}}function h(){f()}function G(d){d.mode!==void 0&&(e.mode=d.mode),d.glyphPalette!==void 0&&(e.glyphPalette=d.glyphPalette),d.useColors!==void 0&&(e.useColors=d.useColors),d.cols!==void 0&&(e.cols=d.cols),d.rows!==void 0&&(e.rows=d.rows),d.cellAspect!==void 0&&(e.cellAspect=d.cellAspect),d.directionalLight!==void 0&&(e.directionalLight=d.directionalLight),d.ambientLight!==void 0&&(e.ambientLight=d.ambientLight),d.camera!==void 0&&(e.camera=d.camera),l()}function M(){return{...e}}function _(){i.clear(),n.contains(r)&&n.removeChild(r)}return l(),{get host(){return n},get output(){return s},get camera(){return e.camera},add:E,addHotspot:g,rerender:h,setOptions:G,getOptions:M,destroy:_}}var ze=typeof HTMLElement<"u"?HTMLElement:class{},Ne=["mode","glyph-palette","use-colors","cols","rows","cell-aspect","directional-direction","directional-intensity","ambient-intensity"];function P(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function Ve(n){if(n==="wireframe"||n==="solid"||n==="voxel")return n}function De(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}var k=class extends ze{constructor(){super(...arguments);this._scene=null}static get observedAttributes(){return[...Ne]}getScene(){return this._scene}_readOptions(){let e={},r=Ve(this.getAttribute("mode"));r!==void 0&&(e.mode=r);let s=this.getAttribute("glyph-palette");s&&(e.glyphPalette=s);let c=De(this.getAttribute("use-colors"));c!==void 0&&(e.useColors=c);let i=P(this.getAttribute("cols"));i!==void 0&&(e.cols=i);let o=P(this.getAttribute("rows"));o!==void 0&&(e.rows=o);let a=P(this.getAttribute("cell-aspect"));a!==void 0&&(e.cellAspect=a);let l=P(this.getAttribute("directional-intensity"));l!==void 0&&(e.directionalLight={direction:[.5,.7,.5],intensity:l});let f=P(this.getAttribute("ambient-intensity"));return f!==void 0&&(e.ambientLight={intensity:f}),e}connectedCallback(){this._scene||(this._scene=de(this,this._readOptions()),this.dispatchEvent(new CustomEvent("glyphcss:scene-ready",{bubbles:!1})))}disconnectedCallback(){this._scene&&(this._scene.destroy(),this._scene=null)}attributeChangedCallback(e,r,s){r!==s&&this._scene&&this._scene.setOptions(this._readOptions())}};import{loadMesh as Be}from"@glyphcss/core";var je=typeof HTMLElement<"u"?HTMLElement:class{},We=["src","position","scale","rotation"];function $(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 Ue(n){if(n){if(!n.includes(",")){let t=parseFloat(n);return Number.isFinite(t)?t:void 0}return $(n)}}function $e(n){return n.closest("glyphcss-scene")??null}function qe(n){let t=[[0,0],[0,0],[0,0]],e=[];for(let r of n){let s=r.vertices;if(!(s.length<3))for(let c=1;c<s.length-1;c++)e.push({vertices:[s[0],s[c],s[c+1]],uvs:t,...r.color?{color:r.color}:{}})}return e}var Y=class extends je{constructor(){super(...arguments);this._handle=null;this._loadToken=0}static get observedAttributes(){return[...We]}getMeshHandle(){return this._handle}connectedCallback(){this._maybeLoad()}disconnectedCallback(){this._tearDown()}attributeChangedCallback(e,r,s){if(r!==s){if(e==="src"){this._tearDown(),this._maybeLoad();return}this._handle&&this._handle.setTransform(this._readTransform())}}_readTransform(){return{position:$(this.getAttribute("position")),scale:Ue(this.getAttribute("scale")),rotation:$(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 r=$e(this);if(!r)return;let s=++this._loadToken,c;try{c=await Be(e)}catch(a){this.dispatchEvent(new CustomEvent("glyphcss:error",{detail:a,bubbles:!0}));return}if(s!==this._loadToken){try{c.dispose()}catch{}return}let i=r.getScene();if(!i){try{c.dispose()}catch{}return}let o=qe(c.polygons);this._handle=i.add(o,this._readTransform()),this.dispatchEvent(new CustomEvent("glyphcss:loaded",{detail:{triangles:o},bubbles:!0}))}};var Ze=typeof HTMLElement<"u"?HTMLElement:class{};function Ke(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 Je(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 Qe(n){return n.closest("glyphcss-scene")??null}var F=class extends Ze{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,r,s){r!==s&&(this._handle&&(this._handle.remove(),this._handle=null),this._register())}_register(){let e=Ke(this.getAttribute("at"));if(!e)return;let s=Qe(this)?.getScene();if(!s)return;let c=this.getAttribute("hotspot-id")??this.getAttribute("id")??String(Math.random()),i=Je(this.getAttribute("size"));this._handle=s.addHotspot({id:c,at:e,size:i},()=>this.dispatchEvent(new CustomEvent("glyphcss:hotspot-click",{detail:{id:c},bubbles:!0})))}};var et=typeof HTMLElement<"u"?HTMLElement:class{};function O(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function tt(n){return n.closest("glyphcss-scene")??null}var X=class extends et{static get observedAttributes(){return["rot-x","rot-y","distance","scale","stretch"]}connectedCallback(){this._apply()}attributeChangedCallback(t,e,r){e!==r&&this._apply()}_apply(){let e=tt(this)?.getScene();if(!e)return;let r=I({rotX:O(this.getAttribute("rot-x")),rotY:O(this.getAttribute("rot-y")),distance:O(this.getAttribute("distance")),scale:O(this.getAttribute("scale")),stretch:O(this.getAttribute("stretch"))});e.setOptions({camera:r})}};var nt=typeof HTMLElement<"u"?HTMLElement:class{};function q(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function st(n){return n.closest("glyphcss-scene")??null}var z=class extends nt{static get observedAttributes(){return["rot-x","rot-y","zoom"]}connectedCallback(){this._apply()}attributeChangedCallback(t,e,r){e!==r&&this._apply()}_apply(){let e=st(this)?.getScene();if(!e)return;let r=oe({rotX:q(this.getAttribute("rot-x")),rotY:q(this.getAttribute("rot-y")),zoom:q(this.getAttribute("zoom"))});e.setOptions({camera:r})}};function me(n,t={}){let e=n.host,r=t.drag??!0,s=t.wheel??!0,c=he(t.invert),i=t.animate??!1,o=!1,a=!1,l=null,f=null,m=null,E={x:0,y:0},g=n.camera;function h(u){if(!(!r||o)&&m===null&&u.isPrimary!==!1){u.preventDefault(),m=u.pointerId,E={x:u.clientX,y:u.clientY},e.style.cursor="grabbing";try{u.target.setPointerCapture(u.pointerId)}catch{}i&&i.pauseOnInteraction!==!1&&(a=!0)}}function G(u){if(m===null||u.pointerId!==m||!r||o)return;u.preventDefault();let C=u.clientX-E.x,A=u.clientY-E.y;E={x:u.clientX,y:u.clientY};let T=c,x=1/4*Math.PI/180;g.rotY=g.rotY-C*x*T,g.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,g.rotX+A*x*T)),n.rerender()}function M(u){if(m===u.pointerId){m=null,e.style.cursor=r&&!o?"grab":"";try{u.target.releasePointerCapture(u.pointerId)}catch{}i&&(a=!1)}}function _(u){if(!s||o)return;u.preventDefault();let C=u.deltaY*.001;g.scale=Math.max(.05,Math.min(10,g.scale*(1-C))),n.rerender()}function d(u){if(!(o||!i)){if(!a){let C=f!==null?Math.min(u-f,50):16.67,A=typeof i=="object"&&i.speed?i.speed:.3,T=typeof i=="object"&&i.axis?i.axis:"y",p=A*(Math.PI/180)*(C/16.67);T==="y"?g.rotY=g.rotY+p:g.rotX=g.rotX+p,n.rerender()}f=u,l=requestAnimationFrame(d)}}function b(){l===null&&typeof requestAnimationFrame<"u"&&i&&(l=requestAnimationFrame(d))}function v(){l!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(l),l=null),f=null}function L(){e.addEventListener("pointerdown",h),e.addEventListener("pointermove",G),e.addEventListener("pointerup",M),e.addEventListener("pointercancel",M),e.addEventListener("wheel",_,{passive:!1}),e.style.cursor=r?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function y(){e.removeEventListener("pointerdown",h),e.removeEventListener("pointermove",G),e.removeEventListener("pointerup",M),e.removeEventListener("pointercancel",M),e.removeEventListener("wheel",_),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return L(),b(),{update(u){let C=!!i;r=u.drag??r,s=u.wheel??s,c=he(u.invert),i=u.animate??i,!o&&m===null&&(e.style.cursor=r?"grab":"");let A=!!i;C&&!A?v():!C&&A&&b()},pause(){o||(o=!0,y(),v(),m=null,a=!1)},resume(){o&&(o=!1,L(),b())},destroy(){o||y(),v(),o=!0}}}function he(n){return n===void 0||n===!1?1:n===!0?-1:n}var rt=typeof HTMLElement<"u"?HTMLElement:class{};function it(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function Z(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function ot(n){return n.closest("glyphcss-scene")??null}var N=class extends rt{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,r,s){r!==s&&this._controls?.update(this._readOptions())}_readOptions(){let e=Z(this.getAttribute("drag")),r=Z(this.getAttribute("wheel")),s=Z(this.getAttribute("invert")),c=it(this.getAttribute("animate-speed")),i=this.getAttribute("animate-axis")==="x"?"x":"y";return{...e!==void 0?{drag:e}:{},...r!==void 0?{wheel:r}:{},...s!==void 0?{invert:s}:{},...c!==void 0?{animate:{speed:c,axis:i}}:{}}}_attach(){if(this._controls)return;let e=ot(this);if(!e)return;let r=e.getScene();if(!r){let s=()=>{e.removeEventListener("glyphcss:scene-ready",s),this._attach()};e.addEventListener("glyphcss:scene-ready",s);return}this._controls=me(r,this._readOptions())}};function ye(n,t={}){let e=n.host,r=t.drag??!0,s=t.wheel??!0,c=fe(t.invert),i=t.animate??!1,o=!1,a=!1,l=null,f=null,m=null,E={x:0,y:0},g=!1,h=n.camera,G=1/4*Math.PI/180,M=.02;function _(p){if(!(!r||o)&&m===null&&p.isPrimary!==!1){p.preventDefault(),m=p.pointerId,E={x:p.clientX,y:p.clientY},g=p.button===2,e.style.cursor="grabbing";try{p.target.setPointerCapture(p.pointerId)}catch{}i&&i.pauseOnInteraction!==!1&&(a=!0)}}function d(p){if(m===null||p.pointerId!==m||!r||o)return;p.preventDefault();let x=p.clientX-E.x,S=p.clientY-E.y;E={x:p.clientX,y:p.clientY};let w=c;if(g||p.shiftKey)h.rotY=h.rotY-x*G*w,h.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,h.rotX+S*G*w));else{let H=h.target;h.target=[H[0]-x*M/h.scale,H[1]-S*M/h.scale,H[2]]}n.rerender()}function b(p){if(m===p.pointerId){m=null,g=!1,e.style.cursor=r&&!o?"grab":"";try{p.target.releasePointerCapture(p.pointerId)}catch{}i&&(a=!1)}}function v(p){p.preventDefault()}function L(p){if(!s||o)return;p.preventDefault();let x=p.deltaY*.001;h.scale=Math.max(.05,Math.min(10,h.scale*(1-x))),n.rerender()}function y(p){if(!(o||!i)){if(!a){let x=f!==null?Math.min(p-f,50):16.67,S=typeof i=="object"&&i.speed?i.speed:.3,w=typeof i=="object"&&i.axis?i.axis:"y",H=S*(Math.PI/180)*(x/16.67);w==="y"?h.rotY=h.rotY+H:h.rotX=h.rotX+H,n.rerender()}f=p,l=requestAnimationFrame(y)}}function u(){l===null&&typeof requestAnimationFrame<"u"&&i&&(l=requestAnimationFrame(y))}function C(){l!==null&&(typeof cancelAnimationFrame<"u"&&cancelAnimationFrame(l),l=null),f=null}function A(){e.addEventListener("pointerdown",_),e.addEventListener("pointermove",d),e.addEventListener("pointerup",b),e.addEventListener("pointercancel",b),e.addEventListener("contextmenu",v),e.addEventListener("wheel",L,{passive:!1}),e.style.cursor=r?"grab":"",e.style.touchAction="none",e.style.userSelect="none"}function T(){e.removeEventListener("pointerdown",_),e.removeEventListener("pointermove",d),e.removeEventListener("pointerup",b),e.removeEventListener("pointercancel",b),e.removeEventListener("contextmenu",v),e.removeEventListener("wheel",L),e.style.cursor="",e.style.touchAction="",e.style.userSelect=""}return A(),u(),{update(p){let x=!!i;r=p.drag??r,s=p.wheel??s,c=fe(p.invert),i=p.animate??i,!o&&m===null&&(e.style.cursor=r?"grab":"");let S=!!i;x&&!S?C():!x&&S&&u()},pause(){o||(o=!0,T(),C(),m=null,a=!1)},resume(){o&&(o=!1,A(),u())},destroy(){o||T(),C(),o=!0}}}function fe(n){return n===void 0||n===!1?1:n===!0?-1:n}var lt=typeof HTMLElement<"u"?HTMLElement:class{};function K(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function ct(n){return n.closest("glyphcss-scene")??null}var V=class extends lt{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,r,s){r!==s&&this._controls?.update(this._readOptions())}_readOptions(){let e=K(this.getAttribute("drag")),r=K(this.getAttribute("wheel")),s=K(this.getAttribute("invert"));return{...e!==void 0?{drag:e}:{},...r!==void 0?{wheel:r}:{},...s!==void 0?{invert:s}:{}}}_attach(){if(this._controls)return;let e=ct(this);if(!e)return;let r=e.getScene();if(!r){let s=()=>{e.removeEventListener("glyphcss:scene-ready",s),this._attach()};e.addEventListener("glyphcss:scene-ready",s);return}this._controls=ye(r,this._readOptions())}};typeof customElements<"u"&&(customElements.get("glyphcss-scene")||customElements.define("glyphcss-scene",k),customElements.get("glyphcss-mesh")||customElements.define("glyphcss-mesh",Y),customElements.get("glyphcss-hotspot")||customElements.define("glyphcss-hotspot",F),customElements.get("glyphcss-perspective-camera")||customElements.define("glyphcss-perspective-camera",X),customElements.get("glyphcss-orthographic-camera")||customElements.define("glyphcss-orthographic-camera",z),customElements.get("glyphcss-orbit-controls")||customElements.define("glyphcss-orbit-controls",N),customElements.get("glyphcss-map-controls")||customElements.define("glyphcss-map-controls",V));export{F as GlyphcssHotspotElement,V as GlyphcssMapControlsElement,Y as GlyphcssMeshElement,N as GlyphcssOrbitControlsElement,z as GlyphcssOrthographicCameraElement,X as GlyphcssPerspectiveCameraElement,k as GlyphcssSceneElement};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";var re=Object.defineProperty;var Ve=Object.getOwnPropertyDescriptor;var Ne=Object.getOwnPropertyNames;var Be=Object.prototype.hasOwnProperty;var je=(n,t)=>{for(var e in t)re(n,e,{get:t[e],enumerable:!0})},ne=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ne(t))!Be.call(n,r)&&r!==e&&re(n,r,{get:()=>t[r],enumerable:!(s=Ve(t,r))||s.enumerable});return n},H=(n,t,e)=>(ne(n,t,"default"),e&&ne(e,t,"default"));var We=n=>ne(re({},"__esModule",{value:!0}),n);var _={};je(_,{DEFAULT_RAMP:()=>Ge,GlyphcssHotspotElement:()=>Z,GlyphcssMapControlsElement:()=>ee,GlyphcssMeshElement:()=>$,GlyphcssOrbitControlsElement:()=>Q,GlyphcssOrthographicCameraElement:()=>J,GlyphcssPerspectiveCameraElement:()=>K,GlyphcssSceneElement:()=>q,SOLID_RAMP:()=>Ee,WIREFRAME_GLYPHS:()=>Me,WIREFRAME_PALETTES:()=>R,bakeFrames:()=>xe,buildRasterizeContext:()=>V,createGlyphcssFirstPersonCamera:()=>be,createGlyphcssFirstPersonControls:()=>Te,createGlyphcssMapControls:()=>U,createGlyphcssOrbitControls:()=>W,createGlyphcssOrthographicCamera:()=>z,createGlyphcssPerspectiveCamera:()=>k,createGlyphcssScene:()=>j,getWireframeGlyphs:()=>F,injectGlyphcssBaseStyles:()=>N,projectHotspots:()=>B,rasterize:()=>I});module.exports=We(_);function se(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 k(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=se(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=se(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 be(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=se(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]]}}}var ve=require("@glyphcss/core"),Ue={direction:[.5,.7,.5],intensity:1},qe={intensity:.4};function V(n){let t=n.triangles??[],e=n.mode??(t.length?"solid":"wireframe"),s=n.wireframe??(e==="wireframe"?(0,ve.trianglesToFeatureEdges)(t):[]);return{camera:n.camera,grid:n.grid,triangles:t,wireframe:s,mode:e,directionalLight:n.directionalLight??Ue,ambientLight:n.ambientLight??qe,glyphPalette:n.glyphPalette??"default",useColors:n.useColors??!0}}var Ge=" .:-=+*#%@".split(""),Ee=" .:-=+*#%@".split(""),R={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("")}},Me=R.default;function F(n){return R[n]??R.default}function I(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 $e(n,p,l,y);let u=F(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]||Je(b,f,M[0]|0,M[1]|0,E[0]|0,E[1]|0,d.weight??2,d.color??null,p,l)}return Qe(b,f,p,l,u)}function $e(n,t,e,s){let{camera:r,triangles:c,directionalLight:o,ambientLight:a}=n,p=F(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=oe(o.color??"#ffffff"),C=oe(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 P=x[0]-i[0],O=x[1]-i[1],w=x[2]-i[2],ue=L[0]-i[0],de=L[1]-i[1],he=L[2]-i[2],me=O*he-w*de,fe=w*ue-P*he,ye=P*de-O*ue,He=Math.hypot(me,fe,ye)||1,Pe=(me*M+fe*E+ye*T)/He,D=Math.max(0,Pe)*h,we=Math.min(1,Math.max(0,v+D)),Oe=Math.min(p.length-1,we*(p.length-1)|0),ke=p[Oe],ge=null;if(y){let te=g.color?oe(g.color):[255,255,255],Fe=v*C[0]/255+D*G[0]/255,Ie=v*C[1]/255+D*G[1]/255,Ye=v*C[2]/255+D*G[2]/255,Xe=Math.min(255,te[0]*Fe),De=Math.min(255,te[1]*Ie),ze=Math.min(255,te[2]*Ye);ge=`#${ie(Xe)}${ie(De)}${ie(ze)}`}let Re=(A[2]+m[2]+S[2])/3;Ze(A[0],A[1],m[0],m[1],S[0],S[1],Re,ke,ge,l,u,b,t,e)}return Ke(l,u,t,e)}function Ze(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 P=g*b+S;o>u[P]&&(u[P]=o,l[P]=a,y&&(y[P]=p))}}}function Ke(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 xe(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]=I(n)}return e==="y"?s.rotY=r:s.rotX=r,c}function Je(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 Qe(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 oe(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 ie(n){let t=Math.max(0,Math.min(255,n|0)).toString(16);return t.length===1?"0"+t:t}var Ce="glyphcss-styles";function N(n){let t=n??(typeof document<"u"?document:void 0);if(!t||t.getElementById(Ce))return;let e=t.createElement("style");e.id=Ce,e.textContent=et,t.head.appendChild(e)}var et=`
|
|
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 B(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 tt=1;function nt(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 j(n,t={}){N(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??k()},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=nt(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=I(v);e.useColors?r.innerHTML=G:r.textContent=G,u()}function u(){let{cols:h,rows:v,cellAspect:G,camera:C}=e,g=B(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=tt++;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 W(n,t={}){let e=n.host,s=t.drag??!0,r=t.wheel??!0,c=Le(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=Le(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 Le(n){return n===void 0||n===!1?1:n===!0?-1:n}function U(n,t={}){let e=n.host,s=t.drag??!0,r=t.wheel??!0,c=Ae(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,P=m.clientY-b.y;b={x:m.clientX,y:m.clientY};let O=c;if(f||m.shiftKey)d.rotY=d.rotY-S*M*O,d.rotX=Math.max(-Math.PI/2,Math.min(Math.PI/2,d.rotX+P*M*O));else{let w=d.target;d.target=[w[0]-S*E/d.scale,w[1]-P*E/d.scale,w[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,P=typeof o=="object"&&o.speed?o.speed:.3,O=typeof o=="object"&&o.axis?o.axis:"y",w=P*(Math.PI/180)*(S/16.67);O==="y"?d.rotY=d.rotY+w:d.rotX=d.rotX+w,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=Ae(m.invert),o=m.animate??o,!a&&u===null&&(e.style.cursor=s?"grab":"");let P=!!o;S&&!P?x():!S&&P&&i()},pause(){a||(a=!0,A(),x(),u=null,p=!1)},resume(){a&&(a=!1,L(),i())},destroy(){a||A(),x(),a=!0}}}function Ae(n){return n===void 0||n===!1?1:n===!0?-1:n}function Te(n,t={}){let e=n.host,s=t.drag??!0,r=t.keyboard??!0,c=t.moveSpeed??.05,o=t.lookSpeed??.004,a=Se(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=Se(i.invert)},pause(){p||(p=!0,g(),l=null)},resume(){p&&(p=!1,C())},destroy(){p||g(),p=!0}}}function Se(n){return n===void 0||n===!1?1:n===!0?-1:n}var rt=typeof HTMLElement<"u"?HTMLElement:class{},st=["mode","glyph-palette","use-colors","cols","rows","cell-aspect","directional-direction","directional-intensity","ambient-intensity"];function Y(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function ot(n){if(n==="wireframe"||n==="solid"||n==="voxel")return n}function it(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}var q=class extends rt{constructor(){super(...arguments);this._scene=null}static get observedAttributes(){return[...st]}getScene(){return this._scene}_readOptions(){let e={},s=ot(this.getAttribute("mode"));s!==void 0&&(e.mode=s);let r=this.getAttribute("glyph-palette");r&&(e.glyphPalette=r);let c=it(this.getAttribute("use-colors"));c!==void 0&&(e.useColors=c);let o=Y(this.getAttribute("cols"));o!==void 0&&(e.cols=o);let a=Y(this.getAttribute("rows"));a!==void 0&&(e.rows=a);let p=Y(this.getAttribute("cell-aspect"));p!==void 0&&(e.cellAspect=p);let l=Y(this.getAttribute("directional-intensity"));l!==void 0&&(e.directionalLight={direction:[.5,.7,.5],intensity:l});let y=Y(this.getAttribute("ambient-intensity"));return y!==void 0&&(e.ambientLight={intensity:y}),e}connectedCallback(){this._scene||(this._scene=j(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())}};var _e=require("@glyphcss/core"),lt=typeof HTMLElement<"u"?HTMLElement:class{},ct=["src","position","scale","rotation"];function le(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 at(n){if(n){if(!n.includes(",")){let t=parseFloat(n);return Number.isFinite(t)?t:void 0}return le(n)}}function pt(n){return n.closest("glyphcss-scene")??null}function ut(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 $=class extends lt{constructor(){super(...arguments);this._handle=null;this._loadToken=0}static get observedAttributes(){return[...ct]}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:le(this.getAttribute("position")),scale:at(this.getAttribute("scale")),rotation:le(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=pt(this);if(!s)return;let r=++this._loadToken,c;try{c=await(0,_e.loadMesh)(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=ut(c.polygons);this._handle=o.add(a,this._readTransform()),this.dispatchEvent(new CustomEvent("glyphcss:loaded",{detail:{triangles:a},bubbles:!0}))}};var dt=typeof HTMLElement<"u"?HTMLElement:class{};function ht(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 mt(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 ft(n){return n.closest("glyphcss-scene")??null}var Z=class extends dt{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=ht(this.getAttribute("at"));if(!e)return;let r=ft(this)?.getScene();if(!r)return;let c=this.getAttribute("hotspot-id")??this.getAttribute("id")??String(Math.random()),o=mt(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 yt=typeof HTMLElement<"u"?HTMLElement:class{};function X(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function gt(n){return n.closest("glyphcss-scene")??null}var K=class extends yt{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=gt(this)?.getScene();if(!e)return;let s=k({rotX:X(this.getAttribute("rot-x")),rotY:X(this.getAttribute("rot-y")),distance:X(this.getAttribute("distance")),scale:X(this.getAttribute("scale")),stretch:X(this.getAttribute("stretch"))});e.setOptions({camera:s})}};var bt=typeof HTMLElement<"u"?HTMLElement:class{};function ce(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function vt(n){return n.closest("glyphcss-scene")??null}var J=class extends bt{static get observedAttributes(){return["rot-x","rot-y","zoom"]}connectedCallback(){this._apply()}attributeChangedCallback(t,e,s){e!==s&&this._apply()}_apply(){let e=vt(this)?.getScene();if(!e)return;let s=z({rotX:ce(this.getAttribute("rot-x")),rotY:ce(this.getAttribute("rot-y")),zoom:ce(this.getAttribute("zoom"))});e.setOptions({camera:s})}};var Gt=typeof HTMLElement<"u"?HTMLElement:class{};function Et(n){if(n==null)return;let t=parseFloat(n);return Number.isFinite(t)?t:void 0}function ae(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function Mt(n){return n.closest("glyphcss-scene")??null}var Q=class extends Gt{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=ae(this.getAttribute("drag")),s=ae(this.getAttribute("wheel")),r=ae(this.getAttribute("invert")),c=Et(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=Mt(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=W(s,this._readOptions())}};var xt=typeof HTMLElement<"u"?HTMLElement:class{};function pe(n){if(n!==null){if(n==="false")return!1;if(n==="true"||n==="")return!0}}function Ct(n){return n.closest("glyphcss-scene")??null}var ee=class extends xt{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=pe(this.getAttribute("drag")),s=pe(this.getAttribute("wheel")),r=pe(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=Ct(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=U(s,this._readOptions())}};H(_,require("@glyphcss/core"),module.exports);0&&(module.exports={DEFAULT_RAMP,GlyphcssHotspotElement,GlyphcssMapControlsElement,GlyphcssMeshElement,GlyphcssOrbitControlsElement,GlyphcssOrthographicCameraElement,GlyphcssPerspectiveCameraElement,GlyphcssSceneElement,SOLID_RAMP,WIREFRAME_GLYPHS,WIREFRAME_PALETTES,bakeFrames,buildRasterizeContext,createGlyphcssFirstPersonCamera,createGlyphcssFirstPersonControls,createGlyphcssMapControls,createGlyphcssOrbitControls,createGlyphcssOrthographicCamera,createGlyphcssPerspectiveCamera,createGlyphcssScene,getWireframeGlyphs,injectGlyphcssBaseStyles,projectHotspots,rasterize,...require("@glyphcss/core")});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { G as GlyphcssSceneHandle, a as GlyphcssCamera, b as GlyphcssTriangle, c as GlyphcssDirectionalLight, d as GlyphcssAmbientLight } from './elements-Bb37NHHO.cjs';
|
|
2
|
+
export { e as GlyphcssFirstPersonCameraHandle, f as GlyphcssFirstPersonCameraOptions, g as GlyphcssHotspotElement, h as GlyphcssHotspotHandle, i as GlyphcssHotspotOptions, j as GlyphcssMapControlsElement, k as GlyphcssMeshElement, l as GlyphcssMeshHandle, m as GlyphcssMeshTransform, n as GlyphcssOrbitControlsElement, o as GlyphcssOrthographicCameraElement, p as GlyphcssOrthographicCameraHandle, q as GlyphcssOrthographicCameraOptions, r as GlyphcssPerspectiveCameraElement, s as GlyphcssPerspectiveCameraHandle, t as GlyphcssPerspectiveCameraOptions, u as GlyphcssSceneElement, v as GlyphcssSceneOptions, w as createGlyphcssFirstPersonCamera, x as createGlyphcssOrthographicCamera, y as createGlyphcssPerspectiveCamera, z as createGlyphcssScene } from './elements-Bb37NHHO.cjs';
|
|
3
|
+
import { Hotspot, HotspotCell, GridSize, WireframeEdge, RenderMode, CharRamp } from '@glyphcss/core';
|
|
4
|
+
export * from '@glyphcss/core';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* createGlyphcssOrbitControls — orbit-mode camera input for a GlyphcssScene.
|
|
8
|
+
*
|
|
9
|
+
* Left-drag rotates rotX / rotY around the target (orbit). Wheel zooms or
|
|
10
|
+
* dollies. Mirrors polycss's createPolyOrbitControls semantics, adapted for
|
|
11
|
+
* the ASCII rasterizer's GlyphcssCamera instead of the CSS matrix3d camera.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
interface GlyphcssOrbitControlsOptions {
|
|
15
|
+
/** Pointer-drag. Default: true. */
|
|
16
|
+
drag?: boolean;
|
|
17
|
+
/** Wheel / pinch zoom. Default: true. */
|
|
18
|
+
wheel?: boolean;
|
|
19
|
+
/** Drag-direction inversion. Default: false. */
|
|
20
|
+
invert?: boolean | number;
|
|
21
|
+
/** Auto-rotate. Pass false or omit to disable. */
|
|
22
|
+
animate?: false | {
|
|
23
|
+
speed?: number;
|
|
24
|
+
axis?: "x" | "y";
|
|
25
|
+
pauseOnInteraction?: boolean;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
interface GlyphcssOrbitControlsHandle {
|
|
29
|
+
update(opts: GlyphcssOrbitControlsOptions): void;
|
|
30
|
+
pause(): void;
|
|
31
|
+
resume(): void;
|
|
32
|
+
destroy(): void;
|
|
33
|
+
}
|
|
34
|
+
declare function createGlyphcssOrbitControls(scene: GlyphcssSceneHandle, options?: GlyphcssOrbitControlsOptions): GlyphcssOrbitControlsHandle;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* createGlyphcssMapControls — map/pan-mode camera input for a GlyphcssScene.
|
|
38
|
+
*
|
|
39
|
+
* Left-drag pans the target (slippy-map semantics). Right-drag or
|
|
40
|
+
* Shift+left-drag orbits. Wheel zooms. Mirrors polycss's createPolyMapControls
|
|
41
|
+
* semantics, adapted for the ASCII rasterizer's GlyphcssCamera.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
interface GlyphcssMapControlsOptions {
|
|
45
|
+
drag?: boolean;
|
|
46
|
+
wheel?: boolean;
|
|
47
|
+
invert?: boolean | number;
|
|
48
|
+
animate?: false | {
|
|
49
|
+
speed?: number;
|
|
50
|
+
axis?: "x" | "y";
|
|
51
|
+
pauseOnInteraction?: boolean;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
interface GlyphcssMapControlsHandle {
|
|
55
|
+
update(opts: GlyphcssMapControlsOptions): void;
|
|
56
|
+
pause(): void;
|
|
57
|
+
resume(): void;
|
|
58
|
+
destroy(): void;
|
|
59
|
+
}
|
|
60
|
+
declare function createGlyphcssMapControls(scene: GlyphcssSceneHandle, options?: GlyphcssMapControlsOptions): GlyphcssMapControlsHandle;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* createGlyphcssFirstPersonControls — first-person camera input for a GlyphcssScene.
|
|
64
|
+
*
|
|
65
|
+
* Mouse-drag looks around (rotX/rotY). WASD or arrow keys move forward/backward/strafe.
|
|
66
|
+
* Mirrors polycss's createPolyFirstPersonControls semantics for the ASCII rasterizer.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
interface GlyphcssFirstPersonControlsOptions {
|
|
70
|
+
drag?: boolean;
|
|
71
|
+
keyboard?: boolean;
|
|
72
|
+
moveSpeed?: number;
|
|
73
|
+
lookSpeed?: number;
|
|
74
|
+
invert?: boolean | number;
|
|
75
|
+
}
|
|
76
|
+
interface GlyphcssFirstPersonControlsHandle {
|
|
77
|
+
update(opts: GlyphcssFirstPersonControlsOptions): void;
|
|
78
|
+
pause(): void;
|
|
79
|
+
resume(): void;
|
|
80
|
+
destroy(): void;
|
|
81
|
+
}
|
|
82
|
+
declare function createGlyphcssFirstPersonControls(scene: GlyphcssSceneHandle, options?: GlyphcssFirstPersonControlsOptions): GlyphcssFirstPersonControlsHandle;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Project a list of 3D hotspot anchors through the camera. Returns the
|
|
86
|
+
* 2D cell position for each, plus camera-space depth and a visibility flag.
|
|
87
|
+
*
|
|
88
|
+
* Uses the same projection as the renderer (same `camera.project` call) —
|
|
89
|
+
* the renderer and hit layer cannot drift out of sync as long as they
|
|
90
|
+
* share a camera.
|
|
91
|
+
*/
|
|
92
|
+
declare function projectHotspots(hotspots: readonly Hotspot[], camera: GlyphcssCamera, cols: number, rows: number, cellAspect: number): HotspotCell[];
|
|
93
|
+
|
|
94
|
+
interface RasterizeContextOptions {
|
|
95
|
+
camera: GlyphcssCamera;
|
|
96
|
+
grid: GridSize;
|
|
97
|
+
/** Triangle list. Required for `solid` / `voxel` modes, optional otherwise. */
|
|
98
|
+
triangles?: GlyphcssTriangle[];
|
|
99
|
+
/** Explicit wireframe edges. If omitted in wireframe mode, edges are derived from `triangles`. */
|
|
100
|
+
wireframe?: WireframeEdge[];
|
|
101
|
+
mode?: RenderMode;
|
|
102
|
+
directionalLight?: GlyphcssDirectionalLight;
|
|
103
|
+
ambientLight?: GlyphcssAmbientLight;
|
|
104
|
+
/** Named wireframe glyph palette. Defaults to `"default"`. */
|
|
105
|
+
glyphPalette?: string;
|
|
106
|
+
/**
|
|
107
|
+
* When `false`, the rasterizer emits plain text (no <span> wrappers). The
|
|
108
|
+
* output is just one text node — fastest possible DOM update. Default `true`.
|
|
109
|
+
*/
|
|
110
|
+
useColors?: boolean;
|
|
111
|
+
}
|
|
112
|
+
interface RasterizeContext {
|
|
113
|
+
camera: GlyphcssCamera;
|
|
114
|
+
grid: GridSize;
|
|
115
|
+
triangles: GlyphcssTriangle[];
|
|
116
|
+
wireframe: WireframeEdge[];
|
|
117
|
+
mode: RenderMode;
|
|
118
|
+
directionalLight: GlyphcssDirectionalLight;
|
|
119
|
+
ambientLight: GlyphcssAmbientLight;
|
|
120
|
+
/** Named wireframe glyph palette passed to the rasterizer. */
|
|
121
|
+
glyphPalette: string;
|
|
122
|
+
useColors: boolean;
|
|
123
|
+
}
|
|
124
|
+
declare function buildRasterizeContext(opts: RasterizeContextOptions): RasterizeContext;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Render the scene to a string.
|
|
128
|
+
*
|
|
129
|
+
* `wireframe` — Bresenham-draws each edge into a Uint8Array stamp with three
|
|
130
|
+
* weight tiers (1=thin, 2=normal, 3=core) and maps to glyphs via the active
|
|
131
|
+
* palette. The palette is picked from `scene.glyphPalette`.
|
|
132
|
+
*
|
|
133
|
+
* `solid` — scan-fills each triangle with Lambert shading, depth-buffered so
|
|
134
|
+
* closer faces overwrite farther ones. Intensity is mapped to SOLID_RAMP.
|
|
135
|
+
*
|
|
136
|
+
* When cells carry `.color`, output contains `<span style="color:#xyz">…</span>`
|
|
137
|
+
* HTML fragments. The consumer must set `innerHTML` (not `textContent`).
|
|
138
|
+
*
|
|
139
|
+
* This is a direct generalization of RadiantHero's `frameForRotation`:
|
|
140
|
+
* same stamp, same weight scheme, same projection.
|
|
141
|
+
*/
|
|
142
|
+
declare function rasterize(scene: RasterizeContext): string;
|
|
143
|
+
/**
|
|
144
|
+
* Bake N rotation frames into an array of HTML strings, ready to be stacked
|
|
145
|
+
* into a single `<pre>` and animated via CSS `steps(N)`. Mutates `camera.rotY`
|
|
146
|
+
* temporarily and restores it before returning.
|
|
147
|
+
*
|
|
148
|
+
* Each returned frame may contain `<span style="color:…">` elements; consumers
|
|
149
|
+
* must set `innerHTML` (not `textContent`) to preserve colors.
|
|
150
|
+
*/
|
|
151
|
+
declare function bakeFrames(scene: RasterizeContext, frameCount: number, axis?: "x" | "y"): string[];
|
|
152
|
+
|
|
153
|
+
/** Default shading ramp — darkest → brightest. */
|
|
154
|
+
declare const DEFAULT_RAMP: CharRamp;
|
|
155
|
+
/** Solid-mode shading ramp: 10 chars, index = floor(intensity * 9). */
|
|
156
|
+
declare const SOLID_RAMP: CharRamp;
|
|
157
|
+
interface WireframeGlyphTiers {
|
|
158
|
+
thin: string[];
|
|
159
|
+
normal: string[];
|
|
160
|
+
core: string[];
|
|
161
|
+
/** Solid-mode intensity ramp (darkest → brightest) for this palette. */
|
|
162
|
+
solid: string[];
|
|
163
|
+
}
|
|
164
|
+
/** Named glyph palettes — each defines wireframe tiers AND a solid ramp. */
|
|
165
|
+
declare const WIREFRAME_PALETTES: Record<string, WireframeGlyphTiers>;
|
|
166
|
+
/** Wireframe glyph weights, matching RadiantHero's three-tier render.
|
|
167
|
+
* `thin` — spokes / inner shapes
|
|
168
|
+
* `normal` — main cage edges
|
|
169
|
+
* `core` — central sun / focal point
|
|
170
|
+
*/
|
|
171
|
+
declare const WIREFRAME_GLYPHS: WireframeGlyphTiers;
|
|
172
|
+
/** Look up a named wireframe palette, falling back to `default`. */
|
|
173
|
+
declare function getWireframeGlyphs(name: string): WireframeGlyphTiers;
|
|
174
|
+
|
|
175
|
+
declare function injectGlyphcssBaseStyles(doc?: Document): void;
|
|
176
|
+
|
|
177
|
+
export { DEFAULT_RAMP, GlyphcssAmbientLight, GlyphcssCamera, GlyphcssDirectionalLight, type GlyphcssFirstPersonControlsHandle, type GlyphcssFirstPersonControlsOptions, type GlyphcssMapControlsHandle, type GlyphcssMapControlsOptions, type GlyphcssOrbitControlsHandle, type GlyphcssOrbitControlsOptions, GlyphcssSceneHandle, GlyphcssTriangle, type RasterizeContext, type RasterizeContextOptions, SOLID_RAMP, WIREFRAME_GLYPHS, WIREFRAME_PALETTES, type WireframeGlyphTiers, bakeFrames, buildRasterizeContext, createGlyphcssFirstPersonControls, createGlyphcssMapControls, createGlyphcssOrbitControls, getWireframeGlyphs, injectGlyphcssBaseStyles, projectHotspots, rasterize };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { G as GlyphcssSceneHandle, a as GlyphcssCamera, b as GlyphcssTriangle, c as GlyphcssDirectionalLight, d as GlyphcssAmbientLight } from './elements-Bb37NHHO.js';
|
|
2
|
+
export { e as GlyphcssFirstPersonCameraHandle, f as GlyphcssFirstPersonCameraOptions, g as GlyphcssHotspotElement, h as GlyphcssHotspotHandle, i as GlyphcssHotspotOptions, j as GlyphcssMapControlsElement, k as GlyphcssMeshElement, l as GlyphcssMeshHandle, m as GlyphcssMeshTransform, n as GlyphcssOrbitControlsElement, o as GlyphcssOrthographicCameraElement, p as GlyphcssOrthographicCameraHandle, q as GlyphcssOrthographicCameraOptions, r as GlyphcssPerspectiveCameraElement, s as GlyphcssPerspectiveCameraHandle, t as GlyphcssPerspectiveCameraOptions, u as GlyphcssSceneElement, v as GlyphcssSceneOptions, w as createGlyphcssFirstPersonCamera, x as createGlyphcssOrthographicCamera, y as createGlyphcssPerspectiveCamera, z as createGlyphcssScene } from './elements-Bb37NHHO.js';
|
|
3
|
+
import { Hotspot, HotspotCell, GridSize, WireframeEdge, RenderMode, CharRamp } from '@glyphcss/core';
|
|
4
|
+
export * from '@glyphcss/core';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* createGlyphcssOrbitControls — orbit-mode camera input for a GlyphcssScene.
|
|
8
|
+
*
|
|
9
|
+
* Left-drag rotates rotX / rotY around the target (orbit). Wheel zooms or
|
|
10
|
+
* dollies. Mirrors polycss's createPolyOrbitControls semantics, adapted for
|
|
11
|
+
* the ASCII rasterizer's GlyphcssCamera instead of the CSS matrix3d camera.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
interface GlyphcssOrbitControlsOptions {
|
|
15
|
+
/** Pointer-drag. Default: true. */
|
|
16
|
+
drag?: boolean;
|
|
17
|
+
/** Wheel / pinch zoom. Default: true. */
|
|
18
|
+
wheel?: boolean;
|
|
19
|
+
/** Drag-direction inversion. Default: false. */
|
|
20
|
+
invert?: boolean | number;
|
|
21
|
+
/** Auto-rotate. Pass false or omit to disable. */
|
|
22
|
+
animate?: false | {
|
|
23
|
+
speed?: number;
|
|
24
|
+
axis?: "x" | "y";
|
|
25
|
+
pauseOnInteraction?: boolean;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
interface GlyphcssOrbitControlsHandle {
|
|
29
|
+
update(opts: GlyphcssOrbitControlsOptions): void;
|
|
30
|
+
pause(): void;
|
|
31
|
+
resume(): void;
|
|
32
|
+
destroy(): void;
|
|
33
|
+
}
|
|
34
|
+
declare function createGlyphcssOrbitControls(scene: GlyphcssSceneHandle, options?: GlyphcssOrbitControlsOptions): GlyphcssOrbitControlsHandle;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* createGlyphcssMapControls — map/pan-mode camera input for a GlyphcssScene.
|
|
38
|
+
*
|
|
39
|
+
* Left-drag pans the target (slippy-map semantics). Right-drag or
|
|
40
|
+
* Shift+left-drag orbits. Wheel zooms. Mirrors polycss's createPolyMapControls
|
|
41
|
+
* semantics, adapted for the ASCII rasterizer's GlyphcssCamera.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
interface GlyphcssMapControlsOptions {
|
|
45
|
+
drag?: boolean;
|
|
46
|
+
wheel?: boolean;
|
|
47
|
+
invert?: boolean | number;
|
|
48
|
+
animate?: false | {
|
|
49
|
+
speed?: number;
|
|
50
|
+
axis?: "x" | "y";
|
|
51
|
+
pauseOnInteraction?: boolean;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
interface GlyphcssMapControlsHandle {
|
|
55
|
+
update(opts: GlyphcssMapControlsOptions): void;
|
|
56
|
+
pause(): void;
|
|
57
|
+
resume(): void;
|
|
58
|
+
destroy(): void;
|
|
59
|
+
}
|
|
60
|
+
declare function createGlyphcssMapControls(scene: GlyphcssSceneHandle, options?: GlyphcssMapControlsOptions): GlyphcssMapControlsHandle;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* createGlyphcssFirstPersonControls — first-person camera input for a GlyphcssScene.
|
|
64
|
+
*
|
|
65
|
+
* Mouse-drag looks around (rotX/rotY). WASD or arrow keys move forward/backward/strafe.
|
|
66
|
+
* Mirrors polycss's createPolyFirstPersonControls semantics for the ASCII rasterizer.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
interface GlyphcssFirstPersonControlsOptions {
|
|
70
|
+
drag?: boolean;
|
|
71
|
+
keyboard?: boolean;
|
|
72
|
+
moveSpeed?: number;
|
|
73
|
+
lookSpeed?: number;
|
|
74
|
+
invert?: boolean | number;
|
|
75
|
+
}
|
|
76
|
+
interface GlyphcssFirstPersonControlsHandle {
|
|
77
|
+
update(opts: GlyphcssFirstPersonControlsOptions): void;
|
|
78
|
+
pause(): void;
|
|
79
|
+
resume(): void;
|
|
80
|
+
destroy(): void;
|
|
81
|
+
}
|
|
82
|
+
declare function createGlyphcssFirstPersonControls(scene: GlyphcssSceneHandle, options?: GlyphcssFirstPersonControlsOptions): GlyphcssFirstPersonControlsHandle;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Project a list of 3D hotspot anchors through the camera. Returns the
|
|
86
|
+
* 2D cell position for each, plus camera-space depth and a visibility flag.
|
|
87
|
+
*
|
|
88
|
+
* Uses the same projection as the renderer (same `camera.project` call) —
|
|
89
|
+
* the renderer and hit layer cannot drift out of sync as long as they
|
|
90
|
+
* share a camera.
|
|
91
|
+
*/
|
|
92
|
+
declare function projectHotspots(hotspots: readonly Hotspot[], camera: GlyphcssCamera, cols: number, rows: number, cellAspect: number): HotspotCell[];
|
|
93
|
+
|
|
94
|
+
interface RasterizeContextOptions {
|
|
95
|
+
camera: GlyphcssCamera;
|
|
96
|
+
grid: GridSize;
|
|
97
|
+
/** Triangle list. Required for `solid` / `voxel` modes, optional otherwise. */
|
|
98
|
+
triangles?: GlyphcssTriangle[];
|
|
99
|
+
/** Explicit wireframe edges. If omitted in wireframe mode, edges are derived from `triangles`. */
|
|
100
|
+
wireframe?: WireframeEdge[];
|
|
101
|
+
mode?: RenderMode;
|
|
102
|
+
directionalLight?: GlyphcssDirectionalLight;
|
|
103
|
+
ambientLight?: GlyphcssAmbientLight;
|
|
104
|
+
/** Named wireframe glyph palette. Defaults to `"default"`. */
|
|
105
|
+
glyphPalette?: string;
|
|
106
|
+
/**
|
|
107
|
+
* When `false`, the rasterizer emits plain text (no <span> wrappers). The
|
|
108
|
+
* output is just one text node — fastest possible DOM update. Default `true`.
|
|
109
|
+
*/
|
|
110
|
+
useColors?: boolean;
|
|
111
|
+
}
|
|
112
|
+
interface RasterizeContext {
|
|
113
|
+
camera: GlyphcssCamera;
|
|
114
|
+
grid: GridSize;
|
|
115
|
+
triangles: GlyphcssTriangle[];
|
|
116
|
+
wireframe: WireframeEdge[];
|
|
117
|
+
mode: RenderMode;
|
|
118
|
+
directionalLight: GlyphcssDirectionalLight;
|
|
119
|
+
ambientLight: GlyphcssAmbientLight;
|
|
120
|
+
/** Named wireframe glyph palette passed to the rasterizer. */
|
|
121
|
+
glyphPalette: string;
|
|
122
|
+
useColors: boolean;
|
|
123
|
+
}
|
|
124
|
+
declare function buildRasterizeContext(opts: RasterizeContextOptions): RasterizeContext;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Render the scene to a string.
|
|
128
|
+
*
|
|
129
|
+
* `wireframe` — Bresenham-draws each edge into a Uint8Array stamp with three
|
|
130
|
+
* weight tiers (1=thin, 2=normal, 3=core) and maps to glyphs via the active
|
|
131
|
+
* palette. The palette is picked from `scene.glyphPalette`.
|
|
132
|
+
*
|
|
133
|
+
* `solid` — scan-fills each triangle with Lambert shading, depth-buffered so
|
|
134
|
+
* closer faces overwrite farther ones. Intensity is mapped to SOLID_RAMP.
|
|
135
|
+
*
|
|
136
|
+
* When cells carry `.color`, output contains `<span style="color:#xyz">…</span>`
|
|
137
|
+
* HTML fragments. The consumer must set `innerHTML` (not `textContent`).
|
|
138
|
+
*
|
|
139
|
+
* This is a direct generalization of RadiantHero's `frameForRotation`:
|
|
140
|
+
* same stamp, same weight scheme, same projection.
|
|
141
|
+
*/
|
|
142
|
+
declare function rasterize(scene: RasterizeContext): string;
|
|
143
|
+
/**
|
|
144
|
+
* Bake N rotation frames into an array of HTML strings, ready to be stacked
|
|
145
|
+
* into a single `<pre>` and animated via CSS `steps(N)`. Mutates `camera.rotY`
|
|
146
|
+
* temporarily and restores it before returning.
|
|
147
|
+
*
|
|
148
|
+
* Each returned frame may contain `<span style="color:…">` elements; consumers
|
|
149
|
+
* must set `innerHTML` (not `textContent`) to preserve colors.
|
|
150
|
+
*/
|
|
151
|
+
declare function bakeFrames(scene: RasterizeContext, frameCount: number, axis?: "x" | "y"): string[];
|
|
152
|
+
|
|
153
|
+
/** Default shading ramp — darkest → brightest. */
|
|
154
|
+
declare const DEFAULT_RAMP: CharRamp;
|
|
155
|
+
/** Solid-mode shading ramp: 10 chars, index = floor(intensity * 9). */
|
|
156
|
+
declare const SOLID_RAMP: CharRamp;
|
|
157
|
+
interface WireframeGlyphTiers {
|
|
158
|
+
thin: string[];
|
|
159
|
+
normal: string[];
|
|
160
|
+
core: string[];
|
|
161
|
+
/** Solid-mode intensity ramp (darkest → brightest) for this palette. */
|
|
162
|
+
solid: string[];
|
|
163
|
+
}
|
|
164
|
+
/** Named glyph palettes — each defines wireframe tiers AND a solid ramp. */
|
|
165
|
+
declare const WIREFRAME_PALETTES: Record<string, WireframeGlyphTiers>;
|
|
166
|
+
/** Wireframe glyph weights, matching RadiantHero's three-tier render.
|
|
167
|
+
* `thin` — spokes / inner shapes
|
|
168
|
+
* `normal` — main cage edges
|
|
169
|
+
* `core` — central sun / focal point
|
|
170
|
+
*/
|
|
171
|
+
declare const WIREFRAME_GLYPHS: WireframeGlyphTiers;
|
|
172
|
+
/** Look up a named wireframe palette, falling back to `default`. */
|
|
173
|
+
declare function getWireframeGlyphs(name: string): WireframeGlyphTiers;
|
|
174
|
+
|
|
175
|
+
declare function injectGlyphcssBaseStyles(doc?: Document): void;
|
|
176
|
+
|
|
177
|
+
export { DEFAULT_RAMP, GlyphcssAmbientLight, GlyphcssCamera, GlyphcssDirectionalLight, type GlyphcssFirstPersonControlsHandle, type GlyphcssFirstPersonControlsOptions, type GlyphcssMapControlsHandle, type GlyphcssMapControlsOptions, type GlyphcssOrbitControlsHandle, type GlyphcssOrbitControlsOptions, GlyphcssSceneHandle, GlyphcssTriangle, type RasterizeContext, type RasterizeContextOptions, SOLID_RAMP, WIREFRAME_GLYPHS, WIREFRAME_PALETTES, type WireframeGlyphTiers, bakeFrames, buildRasterizeContext, createGlyphcssFirstPersonControls, createGlyphcssMapControls, createGlyphcssOrbitControls, getWireframeGlyphs, injectGlyphcssBaseStyles, projectHotspots, rasterize };
|