modern-canvas 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,3 +17,32 @@
17
17
  <img src="https://img.shields.io/npm/l/modern-canvas.svg" alt="License">
18
18
  </a>
19
19
  </p>
20
+
21
+
22
+ ## 📦 Install
23
+
24
+ ```shell
25
+ npm i modern-canvas
26
+ ```
27
+
28
+ ## 🦄 Usage
29
+
30
+ ```ts
31
+ import { createCanvas, plugins } from 'modern-canvas'
32
+
33
+ const canvas = createCanvas({
34
+ view: document.querySelector('canvas'),
35
+ children: [
36
+ { x: 0, y: 0, width: 30, height: 30, rotation: 30, image: '/example.jpg' },
37
+ { x: 30, y: 30, width: 200, height: 200, image: '/example.png' },
38
+ { x: 60, y: 60, width: 120, height: 120, rotation: 50, image: '/example.jpg' },
39
+ { x: 200, y: 200, width: 100, height: 100, image: '/example.png' },
40
+ { x: 30, y: 30, width: 100, height: 100, rotation: 40, text: 'example' },
41
+ ],
42
+ plugins,
43
+ })
44
+
45
+ await canvas.load()
46
+
47
+ canvas.startRenderLoop()
48
+ ```
package/dist/index.cjs CHANGED
@@ -1 +1,48 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=1;exports.one=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function v(o){return typeof o=="function"?o():o}const U=v(()=>({name:"canvas:base",register(o){o.registerShape({name:"rectangle",type:"2d",mode:"triangles",data:new Float32Array([-1,1,-1,-1,1,-1,1,-1,1,1,-1,1])}),o.registerMaterial({name:"baseMaterial",vertexShader:`attribute vec2 aPosition;
2
+ varying vec2 vTextureCoord;
3
+ void main() {
4
+ vTextureCoord = step(0.0, aPosition);
5
+ gl_Position = vec4(aPosition, 0, 1);
6
+ }`,fragmentShader:`uniform sampler2D uSampler;
7
+ varying vec2 vTextureCoord;
8
+ void main() {
9
+ gl_FragColor = texture2D(uSampler, vTextureCoord);
10
+ }`})}})),D=v(()=>({name:"canvas:node-image",register(o){o.registerNodeRenderer({name:"image",include:r=>Boolean(r.image),shape:"rectangle",material:"baseMaterial",update(r){if(!o.resources.has(r.image)){const e=new Image;e.src=r.image,o.registerResource({name:r.image,data:e})}return{uSampler:r.image}}})}})),N=v(()=>{const o=document.createElement("canvas").getContext("2d");return{name:"canvas:node-text",register(r){r.registerNodeRenderer({name:"text",include:e=>Boolean(e.text),shape:"rectangle",material:"baseMaterial",update(e){const{width:a=100,height:t=100,text:c}=e;return r.resources.has(c)||(o.canvas.width=a,o.canvas.height=t,o.font="20px monospace",o.textAlign="center",o.textBaseline="middle",o.fillStyle="black",o.clearRect(0,0,o.canvas.width,o.canvas.height),o.fillText(c,a/2,t/2),r.registerResource({name:c,data:o.canvas})),{uSampler:e.text}}})}}}),F=v(()=>({name:"canvas:fade",register(o){o.registerNodeRenderer({name:"fade",include:r=>Boolean(r.fade),shape:"rectangle",material:{vertexShader:`attribute vec2 aPosition;
11
+ varying vec2 vTextureCoord;
12
+ void main() {
13
+ vTextureCoord = step(0.0, aPosition);
14
+ gl_Position = vec4(aPosition, 0, 1);
15
+ }`,fragmentShader:`uniform sampler2D uSampler;
16
+ varying vec2 vTextureCoord;
17
+ uniform float uTime;
18
+ float linear(float time, float offset, float change, float duration) {
19
+ return change * (time / duration) + offset;
20
+ }
21
+ void main(void) {
22
+ vec4 color = texture2D(uSampler, vTextureCoord);
23
+ gl_FragColor = vec4(color.rgb, linear(uTime, 0.0, 1.0, 3.0));
24
+ }`},update:(r,e)=>({uTime:e})})}}));class _ extends Float32Array{static identity(){return new _([1,0,0,0,1,0,0,0,1])}static translation(r,e){return new _([1,0,0,0,1,0,r,e,1])}static rotation(r){const e=Math.cos(r),a=Math.sin(r);return new _([e,-a,0,a,e,0,0,0,1])}static scaling(r,e){return new _([r,0,0,0,e,0,0,0,1])}multiply(r){const e=this[0],a=this[1],t=this[2],c=this[3],u=this[4],i=this[5],l=this[6],s=this[7],n=this[8],f=r[0],R=r[1],m=r[2],T=r[3],d=r[4],E=r[5],g=r[6],A=r[7],x=r[8];return this[0]=f*e+R*c+m*l,this[1]=f*a+R*u+m*s,this[2]=f*t+R*i+m*n,this[3]=T*e+d*c+E*l,this[4]=T*a+d*u+E*s,this[5]=T*t+d*i+E*n,this[6]=g*e+A*c+x*l,this[7]=g*a+A*u+x*s,this[8]=g*t+A*i+x*n,this}}const L=v(()=>{const o={x:0,y:0};return{name:"canvas:selector2d",register(r){const{view:e}=r;e.addEventListener("mousemove",a=>{const t=e.getBoundingClientRect();o.x=a.clientX-t.left,o.y=a.clientY-t.top}),e.addEventListener("click",()=>{var t;const a=r.get("hovered");a&&((t=r.get("onSelect"))==null||t(a))}),r.registerNodeRenderer({name:"selector2d",include:()=>!1,shape:"rectangle",material:{vertexShader:`attribute vec2 aPosition;
25
+ varying vec2 vTextureCoord;
26
+ uniform mat3 uModelMatrix;
27
+ void main() {
28
+ vTextureCoord = step(0.0, aPosition);
29
+ vec2 position = aPosition;
30
+ gl_Position = vec4((uModelMatrix * vec3(position, 1)).xy, 0, 1);
31
+ }`,fragmentShader:`uniform vec4 uColor;
32
+ void main() {
33
+ gl_FragColor = uColor;
34
+ }`},update:(a,t)=>{const{width:c,height:u}=r;let{x:i=0,y:l=0,width:s=c,height:n=u}=a;const{rotation:f=0}=a;i=i/c,l=l/u,s=s/c,n=n/u;const R=f/180*Math.PI;return{uModelMatrix:_.identity().multiply(_.translation(2*i-(1-s),1-n-2*l)).multiply(_.scaling(s,n)).multiply(_.rotation(R)),uColor:[(t>>>16&255)/255,(t>>>8&255)/255,(t&255)/255,1]}}})},beforeRender(r){var R,m;const{width:e,height:a,gl:t,children:c,nodeRenderers:u}=r;let i=0;const l={};t.bindFramebuffer(t.FRAMEBUFFER,r.glFramebuffers[0].buffer),t.viewport(0,0,e,a),t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT),t.enable(t.DEPTH_TEST),r.forEachNode((T,d)=>{var g;const E=i++;l[E]=d,(g=u.get("selector2d"))==null||g.render(T,E)});const s=new Uint8Array(4);t.readPixels(o.x,a-o.y,1,1,t.RGBA,t.UNSIGNED_BYTE,s);const n=l[(s[0]<<16)+(s[1]<<8)+s[2]];if(((R=r.get("hoveredPath"))==null?void 0:R.join(""))===(n==null?void 0:n.join("")))return;let f;n&&(f={children:c},n.forEach(T=>{var d;return f=(d=f.children)==null?void 0:d[T]})),r.set("hovered",f),r.set("hoveredPath",n),f&&((m=r.get("onHover"))==null||m(f,n))}}}),S=v(()=>({name:"canvas:transform2d",register(o){o.registerNodeRenderer({name:"transform2d",shape:"rectangle",material:{vertexShader:`attribute vec2 aPosition;
35
+ varying vec2 vTextureCoord;
36
+ uniform mat3 uModelMatrix;
37
+ void main() {
38
+ vTextureCoord = step(0.0, aPosition);
39
+ vec2 position = aPosition;
40
+ gl_Position = vec4((uModelMatrix * vec3(position, 1)).xy, 0, 1);
41
+ }`,fragmentShader:`uniform sampler2D uSampler;
42
+ varying vec2 vTextureCoord;
43
+ void main() {
44
+ gl_FragColor = texture2D(uSampler, vTextureCoord);
45
+ }`},update:r=>{const{width:e,height:a}=o;let{x:t=0,y:c=0,width:u=e,height:i=a}=r;const{rotation:l=0}=r;t=t/e,c=c/a,u=u/e,i=i/a;const s=l/180*Math.PI;return{uModelMatrix:_.identity().multiply(_.translation(2*t-(1-u),1-i-2*c)).multiply(_.scaling(u,i)).multiply(_.rotation(s))}}})}})),C=[U,D,N,F,S,L];function p(o,r=0){const{gl:e,width:a,height:t,beforeRenderPlugins:c,afterRenderPlugins:u,nodeRenderers:i,forEachNode:l}=o,s=Array.from(i.values());c.forEach(n=>{var f;return(f=n.beforeRender)==null?void 0:f.call(n,o)}),e.viewport(0,0,a,t),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),l((n,f)=>{e.bindFramebuffer(e.FRAMEBUFFER,null),e.bindTexture(e.TEXTURE_2D,null);const R=s.filter(m=>!m.include&&!m.exclude||m.include&&m.include(n,f)||m.exclude&&!m.exclude(n,f));for(let m=R.length,T=0;T<m;T++){let d=null;T<m-1&&(d=o.glFramebuffers[T%2]),e.bindFramebuffer(e.FRAMEBUFFER,(d==null?void 0:d.buffer)??null),d&&e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),R[T].render(n,r),d&&e.bindTexture(e.TEXTURE_2D,d.texture)}}),u.forEach(n=>{var f;return(f=n.afterRender)==null?void 0:f.call(n,o)}),e.flush()}function M(){const o=new Map,r=new Map;function e(i){if(o.has(i))return o.get(i);if(r.has(i)){const{value:l,shared:s}=r.get(i),n=l();return s&&t(i,n),n}}function a(i){return o.has(i)||r.has(i)}function t(i,l){o.set(i,l)}function c(i,l){u(i,l,!0)}function u(i,l,s=!1){r.set(i,{value:l,shared:s})}return new Proxy({instances:o,bindings:r,get:e,has:a,set:t,bind:u,singleton:c},{get(i,l,s){return typeof l=="symbol"||l in i?Reflect.get(i,l,s):i.get(l)},has(i,l){return typeof l=="symbol"||l in i?Reflect.has(i,l):i.has(l)},set(i,l,s,n){return typeof l=="symbol"||l in i?Reflect.set(i,l,s,n):(i.set(l,s),!0)}})}function I(o,r){const{gl:e,materials:a,glSlTypes:t}=o,{name:c,vertexShader:u,fragmentShader:i,uniforms:l}=r;if(a.has(c))return;const s=[{type:e.VERTEX_SHADER,source:u},{type:e.FRAGMENT_SHADER,source:i.includes("precision")?i:`precision mediump float;
46
+ ${i}`}].map(({type:T,source:d})=>{const E=e.createShader(T);if(!E)throw new Error("failed to create shader");if(e.shaderSource(E,d),e.compileShader(E),!e.getShaderParameter(E,e.COMPILE_STATUS))throw new Error(`failed to compiling shader:
47
+ ${d}
48
+ ${e.getShaderInfoLog(E)}`);return E}),n=e.createProgram();if(!n)throw new Error("failed to create program");if(s.forEach(T=>e.attachShader(n,T)),e.linkProgram(n),s.forEach(T=>e.deleteShader(T)),!e.getProgramParameter(n,e.LINK_STATUS))throw new Error(`failed to initing program: ${e.getProgramInfoLog(n)}`);const f={};for(let T=e.getProgramParameter(n,e.ACTIVE_ATTRIBUTES),d=0;d<T;d++){const E=e.getActiveAttrib(n,d);if(!E)continue;const g=E.name.replace(/\[.*?]$/,"");f[g]={type:t[E.type],isArray:g!==E.name,location:e.getAttribLocation(n,g)}}const R={};for(let T=e.getProgramParameter(n,e.ACTIVE_UNIFORMS),d=0;d<T;d++){const E=e.getActiveUniform(n,d);if(!E)continue;const g=E.name.replace(/\[.*?]$/,"");R[g]={type:t[E.type],isArray:g!==E.name,location:e.getUniformLocation(n,g)}}const m={...r,program:n,attributes:f,uniforms:R,setAttributes(T){for(const[d,E]of Object.entries(T)){const g=f[d];if(!g)continue;const{type:A,isArray:x,location:b}=g;if(E instanceof WebGLBuffer){e.bindBuffer(e.ARRAY_BUFFER,E);const h=e.getAttribLocation(n,d);switch(A){case"vec2":e.vertexAttribPointer(h,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(h);break;case"vec3":e.vertexAttribPointer(h,3,e.FLOAT,!1,0,0),e.enableVertexAttribArray(h);break}}else switch(A){case"float":x?e.vertexAttrib1fv(b,E):e.vertexAttrib1f(b,E);break;case"vec2":e.vertexAttrib2fv(b,E);break;case"vec3":e.vertexAttrib3fv(b,E);break;case"vec4":e.vertexAttrib4fv(b,E);break}}},setUniforms(T){var d;for(const[E,g]of Object.entries(T)){const A=R[E];if(!A)continue;const{type:x,isArray:b,location:h}=A;switch(x){case"float":b?e.uniform1fv(h,g):e.uniform1f(h,g);break;case"bool":case"int":b?e.uniform1iv(h,g):e.uniform1i(h,g);break;case"vec2":e.uniform2fv(h,g);break;case"vec3":e.uniform3fv(h,g);break;case"vec4":e.uniform4fv(h,g);break;case"mat2":e.uniformMatrix2fv(h,!1,g);break;case"mat3":e.uniformMatrix3fv(h,!1,g);break;case"mat4":e.uniformMatrix4fv(h,!1,g);break;case"sampler2D":e.bindTexture(e.TEXTURE_2D,((d=o.resources.get(g))==null?void 0:d.texture)??o.glDefaultTexture),e.uniform1i(h,0);break}}}};l&&m.setUniforms(l),a.set(c,m)}function y(o,r){o.singleton("gl",()=>{const{view:e}=o,a=e.getContext("webgl",r)||e.getContext("experimental-webgl",r);if(!a)throw new Error("failed to getContext for webgl");return a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL,!0),a.pixelStorei(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),a.clearColor(0,0,0,0),a.enable(a.DEPTH_TEST),a.enable(a.CULL_FACE),a.enable(a.BLEND),a.blendFunc(a.SRC_ALPHA,a.ONE_MINUS_SRC_ALPHA),a}),o.singleton("glDefaultTexture",()=>{const{gl:e,width:a,height:t}=o,c=e.createTexture();return e.bindTexture(e.TEXTURE_2D,c),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,a,t,0,e.RGBA,e.UNSIGNED_BYTE,null),c}),o.singleton("glFramebuffers",()=>{const{gl:e}=o;return Array.from({length:2},()=>{const a=e.createTexture(),t=e.createFramebuffer(),c=e.createRenderbuffer();function u(){const{width:i,height:l}=o;e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,i,l,0,e.RGBA,e.UNSIGNED_BYTE,null),e.bindRenderbuffer(e.RENDERBUFFER,c),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,i,l)}return u(),e.bindTexture(e.TEXTURE_2D,a),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,a,0),e.bindRenderbuffer(e.RENDERBUFFER,c),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,c),{buffer:t,depthBuffer:c,texture:a,resize:u}})}),o.singleton("glDrawModes",()=>{const{gl:e}=o;return{points:e.POINTS,linear:e.LINEAR,triangles:e.TRIANGLES,triangleStrip:e.TRIANGLE_STRIP,triangleFan:e.TRIANGLE_FAN}}),o.singleton("glSlTypes",()=>{const e=o.gl;return{[e.FLOAT]:"float",[e.FLOAT_VEC2]:"vec2",[e.FLOAT_VEC3]:"vec3",[e.FLOAT_VEC4]:"vec4",[e.INT]:"int",[e.INT_VEC2]:"ivec2",[e.INT_VEC3]:"ivec3",[e.INT_VEC4]:"ivec4",[e.UNSIGNED_INT]:"uint",[e.UNSIGNED_INT_VEC2]:"uvec2",[e.UNSIGNED_INT_VEC3]:"uvec3",[e.UNSIGNED_INT_VEC4]:"uvec4",[e.BOOL]:"bool",[e.BOOL_VEC2]:"bvec2",[e.BOOL_VEC3]:"bvec3",[e.BOOL_VEC4]:"bvec4",[e.FLOAT_MAT2]:"mat2",[e.FLOAT_MAT3]:"mat3",[e.FLOAT_MAT4]:"mat4",[e.SAMPLER_2D]:"sampler2D",[e.INT_SAMPLER_2D]:"sampler2D",[e.UNSIGNED_INT_SAMPLER_2D]:"sampler2D",[e.SAMPLER_CUBE]:"samplerCube",[e.INT_SAMPLER_CUBE]:"samplerCube",[e.UNSIGNED_INT_SAMPLER_CUBE]:"samplerCube",[e.SAMPLER_2D_ARRAY]:"sampler2DArray",[e.INT_SAMPLER_2D_ARRAY]:"sampler2DArray",[e.UNSIGNED_INT_SAMPLER_2D_ARRAY]:"sampler2DArray"}}),o.singleton("glExtensions",()=>({loseContext:o.gl.getExtension("WEBGL_lose_context")}))}function B(o,r){const{gl:e,shapes:a,glDrawModes:t}=o,{name:c,type:u="2d",mode:i="triangles",data:l=new Float32Array([])}=r,s=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,s),e.bufferData(e.ARRAY_BUFFER,l,e.STATIC_DRAW),a.set(c,{mode:t[i],count:l.byteLength/l.BYTES_PER_ELEMENT/(u==="2d"?2:3),buffer:s})}function w(o,r){const{gl:e,shapes:a,materials:t,nodeRenderers:c}=o,{name:u,shape:i,material:l}=r,s=typeof i=="string"?i:`${u}-shape`;typeof i!="string"&&o.registerShape({...i,name:s});const n=typeof l=="string"?l:`${u}-material`;typeof l!="string"&&o.registerMaterial({...l,name:n});const f=a.get(s),R=t.get(n);if(!f||!R)return;const{buffer:m}=f;R.setAttributes({aPosition:m}),c.set(u,{...r,shape:s,material:n,render:(T,d)=>{var P;const E=a.get(s),g=t.get(n);if(!E||!g)return;const{program:A}=g,{mode:x,count:b}=E;e.useProgram(A);const h=(P=r.update)==null?void 0:P.call(r,T,d);h&&g.setUniforms(h),e.drawArrays(x,0,b)}})}function O(o,r){const{children:e}=o;function a(t,c=[]){for(let u=t.length-1;u>=0;u--){const i=[...c,u],l=t[u];a(l.children??[],i),r(l,i)}}a(e)}function X(o,r){const{gl:e,resources:a}=o,{name:t,data:c}=r,u={loading:!0,texture:null};function i(){u.texture=e.createTexture(),u.texture&&(e.bindTexture(e.TEXTURE_2D,u.texture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c)),u.loading=!1}c instanceof HTMLImageElement?c.addEventListener("load",i,{once:!0}):i(),a.set(t,u)}function G(o={}){var i,l;const{view:r=document.createElement("canvas"),children:e=[],plugins:a=[]}=o,t=M();t.set("view",r),y(t,o),t.bind("width",()=>t.gl.drawingBufferWidth),t.bind("height",()=>t.gl.drawingBufferHeight),t.singleton("plugins",()=>{const s=new Map;return a.forEach(n=>{var f;(f=n.register)==null||f.call(n,t),s.set(n.name,n)}),s}),t.singleton("beforeRenderPlugins",()=>Array.from(t.plugins.values()).filter(s=>"beforeRender"in s)),t.singleton("afterRenderPlugins",()=>Array.from(t.plugins.values()).filter(s=>"afterRender"in s)),t.set("children",e),t.set("shapes",new Map),t.set("registerShape",s=>B(t,s)),t.set("materials",new Map),t.set("registerMaterial",s=>I(t,s)),t.set("resources",new Map),t.set("registerResource",s=>X(t,s)),t.set("nodeRenderers",new Map),t.set("registerNodeRenderer",s=>w(t,s)),t.set("forEachNode",s=>O(t,s)),t.set("load",async()=>{t.get("plugins");const s=Array.from(t.nodeRenderers.values());for(t.forEachNode((n,f)=>{s.filter(m=>!m.include&&!m.exclude||m.include&&m.include(n,f)||m.exclude&&!m.exclude(n,f)).forEach(m=>{var T;return(T=m.update)==null?void 0:T.call(m,n,0)})});Array.from(t.resources.values()).some(n=>n.loading);)await new Promise(n=>setTimeout(n,100));return!0}),t.set("render",s=>p(t,s)),t.set("startRenderLoop",()=>{let s=0,n=0;f(0);function f(R){requestAnimationFrame(f),p(t,n),R*=.001,n+=R-s,s=R}});function c(s){s.preventDefault(),setTimeout(()=>{var n;t.gl.isContextLost()&&((n=t.glExtensions.loseContext)==null||n.restoreContext())},0)}function u(){}return(i=r.addEventListener)==null||i.call(r,"webglcontextlost",c,!1),(l=r.addEventListener)==null||l.call(r,"webglcontextrestored",u,!1),t.set("destroy",()=>{var s,n,f;(s=r.removeEventListener)==null||s.call(r,"webglcontextlost",c),(n=r.removeEventListener)==null||n.call(r,"webglcontextrestored",u),t.gl.useProgram(null),(f=t.glExtensions.loseContext)==null||f.loseContext()}),t}exports.basePlugin=U;exports.createCanvas=G;exports.fadePlugin=F;exports.nodeImagePlugin=D;exports.nodeTextPlugin=N;exports.plugins=C;exports.selector2dPlugin=L;exports.transform2dPlugin=S;
package/dist/index.js CHANGED
@@ -1 +1,48 @@
1
- (function(e,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(e=typeof globalThis<"u"?globalThis:e||self,n(e.modernCanvas={}))})(this,function(e){"use strict";e.one=1,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
1
+ (function(_,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(_=typeof globalThis<"u"?globalThis:_||self,v(_.modernCanvas={}))})(this,function(_){"use strict";function v(o){return typeof o=="function"?o():o}const p=v(()=>({name:"canvas:base",register(o){o.registerShape({name:"rectangle",type:"2d",mode:"triangles",data:new Float32Array([-1,1,-1,-1,1,-1,1,-1,1,1,-1,1])}),o.registerMaterial({name:"baseMaterial",vertexShader:`attribute vec2 aPosition;
2
+ varying vec2 vTextureCoord;
3
+ void main() {
4
+ vTextureCoord = step(0.0, aPosition);
5
+ gl_Position = vec4(aPosition, 0, 1);
6
+ }`,fragmentShader:`uniform sampler2D uSampler;
7
+ varying vec2 vTextureCoord;
8
+ void main() {
9
+ gl_FragColor = texture2D(uSampler, vTextureCoord);
10
+ }`})}})),U=v(()=>({name:"canvas:node-image",register(o){o.registerNodeRenderer({name:"image",include:r=>Boolean(r.image),shape:"rectangle",material:"baseMaterial",update(r){if(!o.resources.has(r.image)){const e=new Image;e.src=r.image,o.registerResource({name:r.image,data:e})}return{uSampler:r.image}}})}})),D=v(()=>{const o=document.createElement("canvas").getContext("2d");return{name:"canvas:node-text",register(r){r.registerNodeRenderer({name:"text",include:e=>Boolean(e.text),shape:"rectangle",material:"baseMaterial",update(e){const{width:i=100,height:t=100,text:c}=e;return r.resources.has(c)||(o.canvas.width=i,o.canvas.height=t,o.font="20px monospace",o.textAlign="center",o.textBaseline="middle",o.fillStyle="black",o.clearRect(0,0,o.canvas.width,o.canvas.height),o.fillText(c,i/2,t/2),r.registerResource({name:c,data:o.canvas})),{uSampler:e.text}}})}}}),N=v(()=>({name:"canvas:fade",register(o){o.registerNodeRenderer({name:"fade",include:r=>Boolean(r.fade),shape:"rectangle",material:{vertexShader:`attribute vec2 aPosition;
11
+ varying vec2 vTextureCoord;
12
+ void main() {
13
+ vTextureCoord = step(0.0, aPosition);
14
+ gl_Position = vec4(aPosition, 0, 1);
15
+ }`,fragmentShader:`uniform sampler2D uSampler;
16
+ varying vec2 vTextureCoord;
17
+ uniform float uTime;
18
+ float linear(float time, float offset, float change, float duration) {
19
+ return change * (time / duration) + offset;
20
+ }
21
+ void main(void) {
22
+ vec4 color = texture2D(uSampler, vTextureCoord);
23
+ gl_FragColor = vec4(color.rgb, linear(uTime, 0.0, 1.0, 3.0));
24
+ }`},update:(r,e)=>({uTime:e})})}}));class A extends Float32Array{static identity(){return new A([1,0,0,0,1,0,0,0,1])}static translation(r,e){return new A([1,0,0,0,1,0,r,e,1])}static rotation(r){const e=Math.cos(r),i=Math.sin(r);return new A([e,-i,0,i,e,0,0,0,1])}static scaling(r,e){return new A([r,0,0,0,e,0,0,0,1])}multiply(r){const e=this[0],i=this[1],t=this[2],c=this[3],u=this[4],a=this[5],l=this[6],s=this[7],n=this[8],f=r[0],R=r[1],m=r[2],T=r[3],E=r[4],d=r[5],g=r[6],b=r[7],P=r[8];return this[0]=f*e+R*c+m*l,this[1]=f*i+R*u+m*s,this[2]=f*t+R*a+m*n,this[3]=T*e+E*c+d*l,this[4]=T*i+E*u+d*s,this[5]=T*t+E*a+d*n,this[6]=g*e+b*c+P*l,this[7]=g*i+b*u+P*s,this[8]=g*t+b*a+P*n,this}}const F=v(()=>{const o={x:0,y:0};return{name:"canvas:selector2d",register(r){const{view:e}=r;e.addEventListener("mousemove",i=>{const t=e.getBoundingClientRect();o.x=i.clientX-t.left,o.y=i.clientY-t.top}),e.addEventListener("click",()=>{var t;const i=r.get("hovered");i&&((t=r.get("onSelect"))==null||t(i))}),r.registerNodeRenderer({name:"selector2d",include:()=>!1,shape:"rectangle",material:{vertexShader:`attribute vec2 aPosition;
25
+ varying vec2 vTextureCoord;
26
+ uniform mat3 uModelMatrix;
27
+ void main() {
28
+ vTextureCoord = step(0.0, aPosition);
29
+ vec2 position = aPosition;
30
+ gl_Position = vec4((uModelMatrix * vec3(position, 1)).xy, 0, 1);
31
+ }`,fragmentShader:`uniform vec4 uColor;
32
+ void main() {
33
+ gl_FragColor = uColor;
34
+ }`},update:(i,t)=>{const{width:c,height:u}=r;let{x:a=0,y:l=0,width:s=c,height:n=u}=i;const{rotation:f=0}=i;a=a/c,l=l/u,s=s/c,n=n/u;const R=f/180*Math.PI;return{uModelMatrix:A.identity().multiply(A.translation(2*a-(1-s),1-n-2*l)).multiply(A.scaling(s,n)).multiply(A.rotation(R)),uColor:[(t>>>16&255)/255,(t>>>8&255)/255,(t&255)/255,1]}}})},beforeRender(r){var R,m;const{width:e,height:i,gl:t,children:c,nodeRenderers:u}=r;let a=0;const l={};t.bindFramebuffer(t.FRAMEBUFFER,r.glFramebuffers[0].buffer),t.viewport(0,0,e,i),t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT),t.enable(t.DEPTH_TEST),r.forEachNode((T,E)=>{var g;const d=a++;l[d]=E,(g=u.get("selector2d"))==null||g.render(T,d)});const s=new Uint8Array(4);t.readPixels(o.x,i-o.y,1,1,t.RGBA,t.UNSIGNED_BYTE,s);const n=l[(s[0]<<16)+(s[1]<<8)+s[2]];if(((R=r.get("hoveredPath"))==null?void 0:R.join(""))===(n==null?void 0:n.join("")))return;let f;n&&(f={children:c},n.forEach(T=>{var E;return f=(E=f.children)==null?void 0:E[T]})),r.set("hovered",f),r.set("hoveredPath",n),f&&((m=r.get("onHover"))==null||m(f,n))}}}),L=v(()=>({name:"canvas:transform2d",register(o){o.registerNodeRenderer({name:"transform2d",shape:"rectangle",material:{vertexShader:`attribute vec2 aPosition;
35
+ varying vec2 vTextureCoord;
36
+ uniform mat3 uModelMatrix;
37
+ void main() {
38
+ vTextureCoord = step(0.0, aPosition);
39
+ vec2 position = aPosition;
40
+ gl_Position = vec4((uModelMatrix * vec3(position, 1)).xy, 0, 1);
41
+ }`,fragmentShader:`uniform sampler2D uSampler;
42
+ varying vec2 vTextureCoord;
43
+ void main() {
44
+ gl_FragColor = texture2D(uSampler, vTextureCoord);
45
+ }`},update:r=>{const{width:e,height:i}=o;let{x:t=0,y:c=0,width:u=e,height:a=i}=r;const{rotation:l=0}=r;t=t/e,c=c/i,u=u/e,a=a/i;const s=l/180*Math.PI;return{uModelMatrix:A.identity().multiply(A.translation(2*t-(1-u),1-a-2*c)).multiply(A.scaling(u,a)).multiply(A.rotation(s))}}})}})),M=[p,U,D,N,L,F];function S(o,r=0){const{gl:e,width:i,height:t,beforeRenderPlugins:c,afterRenderPlugins:u,nodeRenderers:a,forEachNode:l}=o,s=Array.from(a.values());c.forEach(n=>{var f;return(f=n.beforeRender)==null?void 0:f.call(n,o)}),e.viewport(0,0,i,t),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),l((n,f)=>{e.bindFramebuffer(e.FRAMEBUFFER,null),e.bindTexture(e.TEXTURE_2D,null);const R=s.filter(m=>!m.include&&!m.exclude||m.include&&m.include(n,f)||m.exclude&&!m.exclude(n,f));for(let m=R.length,T=0;T<m;T++){let E=null;T<m-1&&(E=o.glFramebuffers[T%2]),e.bindFramebuffer(e.FRAMEBUFFER,(E==null?void 0:E.buffer)??null),E&&e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),R[T].render(n,r),E&&e.bindTexture(e.TEXTURE_2D,E.texture)}}),u.forEach(n=>{var f;return(f=n.afterRender)==null?void 0:f.call(n,o)}),e.flush()}function I(){const o=new Map,r=new Map;function e(a){if(o.has(a))return o.get(a);if(r.has(a)){const{value:l,shared:s}=r.get(a),n=l();return s&&t(a,n),n}}function i(a){return o.has(a)||r.has(a)}function t(a,l){o.set(a,l)}function c(a,l){u(a,l,!0)}function u(a,l,s=!1){r.set(a,{value:l,shared:s})}return new Proxy({instances:o,bindings:r,get:e,has:i,set:t,bind:u,singleton:c},{get(a,l,s){return typeof l=="symbol"||l in a?Reflect.get(a,l,s):a.get(l)},has(a,l){return typeof l=="symbol"||l in a?Reflect.has(a,l):a.has(l)},set(a,l,s,n){return typeof l=="symbol"||l in a?Reflect.set(a,l,s,n):(a.set(l,s),!0)}})}function y(o,r){const{gl:e,materials:i,glSlTypes:t}=o,{name:c,vertexShader:u,fragmentShader:a,uniforms:l}=r;if(i.has(c))return;const s=[{type:e.VERTEX_SHADER,source:u},{type:e.FRAGMENT_SHADER,source:a.includes("precision")?a:`precision mediump float;
46
+ ${a}`}].map(({type:T,source:E})=>{const d=e.createShader(T);if(!d)throw new Error("failed to create shader");if(e.shaderSource(d,E),e.compileShader(d),!e.getShaderParameter(d,e.COMPILE_STATUS))throw new Error(`failed to compiling shader:
47
+ ${E}
48
+ ${e.getShaderInfoLog(d)}`);return d}),n=e.createProgram();if(!n)throw new Error("failed to create program");if(s.forEach(T=>e.attachShader(n,T)),e.linkProgram(n),s.forEach(T=>e.deleteShader(T)),!e.getProgramParameter(n,e.LINK_STATUS))throw new Error(`failed to initing program: ${e.getProgramInfoLog(n)}`);const f={};for(let T=e.getProgramParameter(n,e.ACTIVE_ATTRIBUTES),E=0;E<T;E++){const d=e.getActiveAttrib(n,E);if(!d)continue;const g=d.name.replace(/\[.*?]$/,"");f[g]={type:t[d.type],isArray:g!==d.name,location:e.getAttribLocation(n,g)}}const R={};for(let T=e.getProgramParameter(n,e.ACTIVE_UNIFORMS),E=0;E<T;E++){const d=e.getActiveUniform(n,E);if(!d)continue;const g=d.name.replace(/\[.*?]$/,"");R[g]={type:t[d.type],isArray:g!==d.name,location:e.getUniformLocation(n,g)}}const m={...r,program:n,attributes:f,uniforms:R,setAttributes(T){for(const[E,d]of Object.entries(T)){const g=f[E];if(!g)continue;const{type:b,isArray:P,location:x}=g;if(d instanceof WebGLBuffer){e.bindBuffer(e.ARRAY_BUFFER,d);const h=e.getAttribLocation(n,E);switch(b){case"vec2":e.vertexAttribPointer(h,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(h);break;case"vec3":e.vertexAttribPointer(h,3,e.FLOAT,!1,0,0),e.enableVertexAttribArray(h);break}}else switch(b){case"float":P?e.vertexAttrib1fv(x,d):e.vertexAttrib1f(x,d);break;case"vec2":e.vertexAttrib2fv(x,d);break;case"vec3":e.vertexAttrib3fv(x,d);break;case"vec4":e.vertexAttrib4fv(x,d);break}}},setUniforms(T){var E;for(const[d,g]of Object.entries(T)){const b=R[d];if(!b)continue;const{type:P,isArray:x,location:h}=b;switch(P){case"float":x?e.uniform1fv(h,g):e.uniform1f(h,g);break;case"bool":case"int":x?e.uniform1iv(h,g):e.uniform1i(h,g);break;case"vec2":e.uniform2fv(h,g);break;case"vec3":e.uniform3fv(h,g);break;case"vec4":e.uniform4fv(h,g);break;case"mat2":e.uniformMatrix2fv(h,!1,g);break;case"mat3":e.uniformMatrix3fv(h,!1,g);break;case"mat4":e.uniformMatrix4fv(h,!1,g);break;case"sampler2D":e.bindTexture(e.TEXTURE_2D,((E=o.resources.get(g))==null?void 0:E.texture)??o.glDefaultTexture),e.uniform1i(h,0);break}}}};l&&m.setUniforms(l),i.set(c,m)}function B(o,r){o.singleton("gl",()=>{const{view:e}=o,i=e.getContext("webgl",r)||e.getContext("experimental-webgl",r);if(!i)throw new Error("failed to getContext for webgl");return i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,!0),i.pixelStorei(i.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),i.clearColor(0,0,0,0),i.enable(i.DEPTH_TEST),i.enable(i.CULL_FACE),i.enable(i.BLEND),i.blendFunc(i.SRC_ALPHA,i.ONE_MINUS_SRC_ALPHA),i}),o.singleton("glDefaultTexture",()=>{const{gl:e,width:i,height:t}=o,c=e.createTexture();return e.bindTexture(e.TEXTURE_2D,c),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,i,t,0,e.RGBA,e.UNSIGNED_BYTE,null),c}),o.singleton("glFramebuffers",()=>{const{gl:e}=o;return Array.from({length:2},()=>{const i=e.createTexture(),t=e.createFramebuffer(),c=e.createRenderbuffer();function u(){const{width:a,height:l}=o;e.bindTexture(e.TEXTURE_2D,i),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,a,l,0,e.RGBA,e.UNSIGNED_BYTE,null),e.bindRenderbuffer(e.RENDERBUFFER,c),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,a,l)}return u(),e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,i,0),e.bindRenderbuffer(e.RENDERBUFFER,c),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,c),{buffer:t,depthBuffer:c,texture:i,resize:u}})}),o.singleton("glDrawModes",()=>{const{gl:e}=o;return{points:e.POINTS,linear:e.LINEAR,triangles:e.TRIANGLES,triangleStrip:e.TRIANGLE_STRIP,triangleFan:e.TRIANGLE_FAN}}),o.singleton("glSlTypes",()=>{const e=o.gl;return{[e.FLOAT]:"float",[e.FLOAT_VEC2]:"vec2",[e.FLOAT_VEC3]:"vec3",[e.FLOAT_VEC4]:"vec4",[e.INT]:"int",[e.INT_VEC2]:"ivec2",[e.INT_VEC3]:"ivec3",[e.INT_VEC4]:"ivec4",[e.UNSIGNED_INT]:"uint",[e.UNSIGNED_INT_VEC2]:"uvec2",[e.UNSIGNED_INT_VEC3]:"uvec3",[e.UNSIGNED_INT_VEC4]:"uvec4",[e.BOOL]:"bool",[e.BOOL_VEC2]:"bvec2",[e.BOOL_VEC3]:"bvec3",[e.BOOL_VEC4]:"bvec4",[e.FLOAT_MAT2]:"mat2",[e.FLOAT_MAT3]:"mat3",[e.FLOAT_MAT4]:"mat4",[e.SAMPLER_2D]:"sampler2D",[e.INT_SAMPLER_2D]:"sampler2D",[e.UNSIGNED_INT_SAMPLER_2D]:"sampler2D",[e.SAMPLER_CUBE]:"samplerCube",[e.INT_SAMPLER_CUBE]:"samplerCube",[e.UNSIGNED_INT_SAMPLER_CUBE]:"samplerCube",[e.SAMPLER_2D_ARRAY]:"sampler2DArray",[e.INT_SAMPLER_2D_ARRAY]:"sampler2DArray",[e.UNSIGNED_INT_SAMPLER_2D_ARRAY]:"sampler2DArray"}}),o.singleton("glExtensions",()=>({loseContext:o.gl.getExtension("WEBGL_lose_context")}))}function w(o,r){const{gl:e,shapes:i,glDrawModes:t}=o,{name:c,type:u="2d",mode:a="triangles",data:l=new Float32Array([])}=r,s=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,s),e.bufferData(e.ARRAY_BUFFER,l,e.STATIC_DRAW),i.set(c,{mode:t[a],count:l.byteLength/l.BYTES_PER_ELEMENT/(u==="2d"?2:3),buffer:s})}function O(o,r){const{gl:e,shapes:i,materials:t,nodeRenderers:c}=o,{name:u,shape:a,material:l}=r,s=typeof a=="string"?a:`${u}-shape`;typeof a!="string"&&o.registerShape({...a,name:s});const n=typeof l=="string"?l:`${u}-material`;typeof l!="string"&&o.registerMaterial({...l,name:n});const f=i.get(s),R=t.get(n);if(!f||!R)return;const{buffer:m}=f;R.setAttributes({aPosition:m}),c.set(u,{...r,shape:s,material:n,render:(T,E)=>{var C;const d=i.get(s),g=t.get(n);if(!d||!g)return;const{program:b}=g,{mode:P,count:x}=d;e.useProgram(b);const h=(C=r.update)==null?void 0:C.call(r,T,E);h&&g.setUniforms(h),e.drawArrays(P,0,x)}})}function X(o,r){const{children:e}=o;function i(t,c=[]){for(let u=t.length-1;u>=0;u--){const a=[...c,u],l=t[u];i(l.children??[],a),r(l,a)}}i(e)}function G(o,r){const{gl:e,resources:i}=o,{name:t,data:c}=r,u={loading:!0,texture:null};function a(){u.texture=e.createTexture(),u.texture&&(e.bindTexture(e.TEXTURE_2D,u.texture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c)),u.loading=!1}c instanceof HTMLImageElement?c.addEventListener("load",a,{once:!0}):a(),i.set(t,u)}function H(o={}){var a,l;const{view:r=document.createElement("canvas"),children:e=[],plugins:i=[]}=o,t=I();t.set("view",r),B(t,o),t.bind("width",()=>t.gl.drawingBufferWidth),t.bind("height",()=>t.gl.drawingBufferHeight),t.singleton("plugins",()=>{const s=new Map;return i.forEach(n=>{var f;(f=n.register)==null||f.call(n,t),s.set(n.name,n)}),s}),t.singleton("beforeRenderPlugins",()=>Array.from(t.plugins.values()).filter(s=>"beforeRender"in s)),t.singleton("afterRenderPlugins",()=>Array.from(t.plugins.values()).filter(s=>"afterRender"in s)),t.set("children",e),t.set("shapes",new Map),t.set("registerShape",s=>w(t,s)),t.set("materials",new Map),t.set("registerMaterial",s=>y(t,s)),t.set("resources",new Map),t.set("registerResource",s=>G(t,s)),t.set("nodeRenderers",new Map),t.set("registerNodeRenderer",s=>O(t,s)),t.set("forEachNode",s=>X(t,s)),t.set("load",async()=>{t.get("plugins");const s=Array.from(t.nodeRenderers.values());for(t.forEachNode((n,f)=>{s.filter(m=>!m.include&&!m.exclude||m.include&&m.include(n,f)||m.exclude&&!m.exclude(n,f)).forEach(m=>{var T;return(T=m.update)==null?void 0:T.call(m,n,0)})});Array.from(t.resources.values()).some(n=>n.loading);)await new Promise(n=>setTimeout(n,100));return!0}),t.set("render",s=>S(t,s)),t.set("startRenderLoop",()=>{let s=0,n=0;f(0);function f(R){requestAnimationFrame(f),S(t,n),R*=.001,n+=R-s,s=R}});function c(s){s.preventDefault(),setTimeout(()=>{var n;t.gl.isContextLost()&&((n=t.glExtensions.loseContext)==null||n.restoreContext())},0)}function u(){}return(a=r.addEventListener)==null||a.call(r,"webglcontextlost",c,!1),(l=r.addEventListener)==null||l.call(r,"webglcontextrestored",u,!1),t.set("destroy",()=>{var s,n,f;(s=r.removeEventListener)==null||s.call(r,"webglcontextlost",c),(n=r.removeEventListener)==null||n.call(r,"webglcontextrestored",u),t.gl.useProgram(null),(f=t.glExtensions.loseContext)==null||f.loseContext()}),t}_.basePlugin=p,_.createCanvas=H,_.fadePlugin=N,_.nodeImagePlugin=U,_.nodeTextPlugin=D,_.plugins=M,_.selector2dPlugin=F,_.transform2dPlugin=L,Object.defineProperty(_,Symbol.toStringTag,{value:"Module"})});
package/dist/index.mjs CHANGED
@@ -1,4 +1,672 @@
1
- const o = 1;
1
+ function v(o) {
2
+ return typeof o == "function" ? o() : o;
3
+ }
4
+ const U = v(() => ({
5
+ name: "canvas:base",
6
+ register(o) {
7
+ o.registerShape({
8
+ name: "rectangle",
9
+ type: "2d",
10
+ mode: "triangles",
11
+ data: new Float32Array([
12
+ -1,
13
+ 1,
14
+ -1,
15
+ -1,
16
+ 1,
17
+ -1,
18
+ 1,
19
+ -1,
20
+ 1,
21
+ 1,
22
+ -1,
23
+ 1
24
+ ])
25
+ }), o.registerMaterial({
26
+ name: "baseMaterial",
27
+ vertexShader: `attribute vec2 aPosition;
28
+ varying vec2 vTextureCoord;
29
+ void main() {
30
+ vTextureCoord = step(0.0, aPosition);
31
+ gl_Position = vec4(aPosition, 0, 1);
32
+ }`,
33
+ fragmentShader: `uniform sampler2D uSampler;
34
+ varying vec2 vTextureCoord;
35
+ void main() {
36
+ gl_FragColor = texture2D(uSampler, vTextureCoord);
37
+ }`
38
+ });
39
+ }
40
+ })), D = v(() => ({
41
+ name: "canvas:node-image",
42
+ register(o) {
43
+ o.registerNodeRenderer({
44
+ name: "image",
45
+ include: (r) => Boolean(r.image),
46
+ shape: "rectangle",
47
+ material: "baseMaterial",
48
+ update(r) {
49
+ if (!o.resources.has(r.image)) {
50
+ const e = new Image();
51
+ e.src = r.image, o.registerResource({
52
+ name: r.image,
53
+ data: e
54
+ });
55
+ }
56
+ return {
57
+ uSampler: r.image
58
+ };
59
+ }
60
+ });
61
+ }
62
+ })), N = v(() => {
63
+ const o = document.createElement("canvas").getContext("2d");
64
+ return {
65
+ name: "canvas:node-text",
66
+ register(r) {
67
+ r.registerNodeRenderer({
68
+ name: "text",
69
+ include: (e) => Boolean(e.text),
70
+ shape: "rectangle",
71
+ material: "baseMaterial",
72
+ update(e) {
73
+ const { width: a = 100, height: t = 100, text: c } = e;
74
+ return r.resources.has(c) || (o.canvas.width = a, o.canvas.height = t, o.font = "20px monospace", o.textAlign = "center", o.textBaseline = "middle", o.fillStyle = "black", o.clearRect(0, 0, o.canvas.width, o.canvas.height), o.fillText(c, a / 2, t / 2), r.registerResource({
75
+ name: c,
76
+ data: o.canvas
77
+ })), {
78
+ uSampler: e.text
79
+ };
80
+ }
81
+ });
82
+ }
83
+ };
84
+ }), F = v(() => ({
85
+ name: "canvas:fade",
86
+ register(o) {
87
+ o.registerNodeRenderer({
88
+ name: "fade",
89
+ include: (r) => Boolean(r.fade),
90
+ shape: "rectangle",
91
+ material: {
92
+ vertexShader: `attribute vec2 aPosition;
93
+ varying vec2 vTextureCoord;
94
+ void main() {
95
+ vTextureCoord = step(0.0, aPosition);
96
+ gl_Position = vec4(aPosition, 0, 1);
97
+ }`,
98
+ fragmentShader: `uniform sampler2D uSampler;
99
+ varying vec2 vTextureCoord;
100
+ uniform float uTime;
101
+ float linear(float time, float offset, float change, float duration) {
102
+ return change * (time / duration) + offset;
103
+ }
104
+ void main(void) {
105
+ vec4 color = texture2D(uSampler, vTextureCoord);
106
+ gl_FragColor = vec4(color.rgb, linear(uTime, 0.0, 1.0, 3.0));
107
+ }`
108
+ },
109
+ update: (r, e) => ({
110
+ uTime: e
111
+ })
112
+ });
113
+ }
114
+ }));
115
+ class _ extends Float32Array {
116
+ static identity() {
117
+ return new _([
118
+ 1,
119
+ 0,
120
+ 0,
121
+ 0,
122
+ 1,
123
+ 0,
124
+ 0,
125
+ 0,
126
+ 1
127
+ ]);
128
+ }
129
+ static translation(r, e) {
130
+ return new _([
131
+ 1,
132
+ 0,
133
+ 0,
134
+ 0,
135
+ 1,
136
+ 0,
137
+ r,
138
+ e,
139
+ 1
140
+ ]);
141
+ }
142
+ static rotation(r) {
143
+ const e = Math.cos(r), a = Math.sin(r);
144
+ return new _([
145
+ e,
146
+ -a,
147
+ 0,
148
+ a,
149
+ e,
150
+ 0,
151
+ 0,
152
+ 0,
153
+ 1
154
+ ]);
155
+ }
156
+ static scaling(r, e) {
157
+ return new _([
158
+ r,
159
+ 0,
160
+ 0,
161
+ 0,
162
+ e,
163
+ 0,
164
+ 0,
165
+ 0,
166
+ 1
167
+ ]);
168
+ }
169
+ multiply(r) {
170
+ const e = this[0], a = this[1], t = this[2], c = this[3], u = this[4], i = this[5], l = this[6], s = this[7], n = this[8], f = r[0], R = r[1], g = r[2], T = r[3], d = r[4], E = r[5], m = r[6], A = r[7], x = r[8];
171
+ return this[0] = f * e + R * c + g * l, this[1] = f * a + R * u + g * s, this[2] = f * t + R * i + g * n, this[3] = T * e + d * c + E * l, this[4] = T * a + d * u + E * s, this[5] = T * t + d * i + E * n, this[6] = m * e + A * c + x * l, this[7] = m * a + A * u + x * s, this[8] = m * t + A * i + x * n, this;
172
+ }
173
+ }
174
+ const L = v(() => {
175
+ const o = { x: 0, y: 0 };
176
+ return {
177
+ name: "canvas:selector2d",
178
+ register(r) {
179
+ const { view: e } = r;
180
+ e.addEventListener("mousemove", (a) => {
181
+ const t = e.getBoundingClientRect();
182
+ o.x = a.clientX - t.left, o.y = a.clientY - t.top;
183
+ }), e.addEventListener("click", () => {
184
+ var t;
185
+ const a = r.get("hovered");
186
+ a && ((t = r.get("onSelect")) == null || t(a));
187
+ }), r.registerNodeRenderer({
188
+ name: "selector2d",
189
+ include: () => !1,
190
+ shape: "rectangle",
191
+ material: {
192
+ vertexShader: `attribute vec2 aPosition;
193
+ varying vec2 vTextureCoord;
194
+ uniform mat3 uModelMatrix;
195
+ void main() {
196
+ vTextureCoord = step(0.0, aPosition);
197
+ vec2 position = aPosition;
198
+ gl_Position = vec4((uModelMatrix * vec3(position, 1)).xy, 0, 1);
199
+ }`,
200
+ fragmentShader: `uniform vec4 uColor;
201
+ void main() {
202
+ gl_FragColor = uColor;
203
+ }`
204
+ },
205
+ update: (a, t) => {
206
+ const { width: c, height: u } = r;
207
+ let {
208
+ x: i = 0,
209
+ y: l = 0,
210
+ width: s = c,
211
+ height: n = u
212
+ } = a;
213
+ const {
214
+ rotation: f = 0
215
+ } = a;
216
+ i = i / c, l = l / u, s = s / c, n = n / u;
217
+ const R = f / 180 * Math.PI;
218
+ return {
219
+ uModelMatrix: _.identity().multiply(_.translation(2 * i - (1 - s), 1 - n - 2 * l)).multiply(_.scaling(s, n)).multiply(_.rotation(R)),
220
+ uColor: [(t >>> 16 & 255) / 255, (t >>> 8 & 255) / 255, (t & 255) / 255, 1]
221
+ };
222
+ }
223
+ });
224
+ },
225
+ beforeRender(r) {
226
+ var R, g;
227
+ const { width: e, height: a, gl: t, children: c, nodeRenderers: u } = r;
228
+ let i = 0;
229
+ const l = {};
230
+ t.bindFramebuffer(t.FRAMEBUFFER, r.glFramebuffers[0].buffer), t.viewport(0, 0, e, a), t.clear(t.COLOR_BUFFER_BIT | t.DEPTH_BUFFER_BIT), t.enable(t.DEPTH_TEST), r.forEachNode((T, d) => {
231
+ var m;
232
+ const E = i++;
233
+ l[E] = d, (m = u.get("selector2d")) == null || m.render(T, E);
234
+ });
235
+ const s = new Uint8Array(4);
236
+ t.readPixels(o.x, a - o.y, 1, 1, t.RGBA, t.UNSIGNED_BYTE, s);
237
+ const n = l[(s[0] << 16) + (s[1] << 8) + s[2]];
238
+ if (((R = r.get("hoveredPath")) == null ? void 0 : R.join("")) === (n == null ? void 0 : n.join("")))
239
+ return;
240
+ let f;
241
+ n && (f = { children: c }, n.forEach((T) => {
242
+ var d;
243
+ return f = (d = f.children) == null ? void 0 : d[T];
244
+ })), r.set("hovered", f), r.set("hoveredPath", n), f && ((g = r.get("onHover")) == null || g(f, n));
245
+ }
246
+ };
247
+ }), S = v(() => ({
248
+ name: "canvas:transform2d",
249
+ register(o) {
250
+ o.registerNodeRenderer({
251
+ name: "transform2d",
252
+ shape: "rectangle",
253
+ material: {
254
+ vertexShader: `attribute vec2 aPosition;
255
+ varying vec2 vTextureCoord;
256
+ uniform mat3 uModelMatrix;
257
+ void main() {
258
+ vTextureCoord = step(0.0, aPosition);
259
+ vec2 position = aPosition;
260
+ gl_Position = vec4((uModelMatrix * vec3(position, 1)).xy, 0, 1);
261
+ }`,
262
+ fragmentShader: `uniform sampler2D uSampler;
263
+ varying vec2 vTextureCoord;
264
+ void main() {
265
+ gl_FragColor = texture2D(uSampler, vTextureCoord);
266
+ }`
267
+ },
268
+ update: (r) => {
269
+ const { width: e, height: a } = o;
270
+ let {
271
+ x: t = 0,
272
+ y: c = 0,
273
+ width: u = e,
274
+ height: i = a
275
+ } = r;
276
+ const {
277
+ rotation: l = 0
278
+ } = r;
279
+ t = t / e, c = c / a, u = u / e, i = i / a;
280
+ const s = l / 180 * Math.PI;
281
+ return {
282
+ uModelMatrix: _.identity().multiply(_.translation(2 * t - (1 - u), 1 - i - 2 * c)).multiply(_.scaling(u, i)).multiply(_.rotation(s))
283
+ };
284
+ }
285
+ });
286
+ }
287
+ })), X = [
288
+ U,
289
+ D,
290
+ N,
291
+ F,
292
+ S,
293
+ L
294
+ ];
295
+ function P(o, r = 0) {
296
+ const {
297
+ gl: e,
298
+ width: a,
299
+ height: t,
300
+ beforeRenderPlugins: c,
301
+ afterRenderPlugins: u,
302
+ nodeRenderers: i,
303
+ forEachNode: l
304
+ } = o, s = Array.from(i.values());
305
+ c.forEach((n) => {
306
+ var f;
307
+ return (f = n.beforeRender) == null ? void 0 : f.call(n, o);
308
+ }), e.viewport(0, 0, a, t), e.clear(e.COLOR_BUFFER_BIT | e.DEPTH_BUFFER_BIT), l((n, f) => {
309
+ e.bindFramebuffer(e.FRAMEBUFFER, null), e.bindTexture(e.TEXTURE_2D, null);
310
+ const R = s.filter((g) => !g.include && !g.exclude || g.include && g.include(n, f) || g.exclude && !g.exclude(n, f));
311
+ for (let g = R.length, T = 0; T < g; T++) {
312
+ let d = null;
313
+ T < g - 1 && (d = o.glFramebuffers[T % 2]), e.bindFramebuffer(e.FRAMEBUFFER, (d == null ? void 0 : d.buffer) ?? null), d && e.clear(e.COLOR_BUFFER_BIT | e.DEPTH_BUFFER_BIT), R[T].render(n, r), d && e.bindTexture(e.TEXTURE_2D, d.texture);
314
+ }
315
+ }), u.forEach((n) => {
316
+ var f;
317
+ return (f = n.afterRender) == null ? void 0 : f.call(n, o);
318
+ }), e.flush();
319
+ }
320
+ function C() {
321
+ const o = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
322
+ function e(i) {
323
+ if (o.has(i))
324
+ return o.get(i);
325
+ if (r.has(i)) {
326
+ const { value: l, shared: s } = r.get(i), n = l();
327
+ return s && t(i, n), n;
328
+ }
329
+ }
330
+ function a(i) {
331
+ return o.has(i) || r.has(i);
332
+ }
333
+ function t(i, l) {
334
+ o.set(i, l);
335
+ }
336
+ function c(i, l) {
337
+ u(i, l, !0);
338
+ }
339
+ function u(i, l, s = !1) {
340
+ r.set(i, { value: l, shared: s });
341
+ }
342
+ return new Proxy(
343
+ { instances: o, bindings: r, get: e, has: a, set: t, bind: u, singleton: c },
344
+ {
345
+ get(i, l, s) {
346
+ return typeof l == "symbol" || l in i ? Reflect.get(i, l, s) : i.get(l);
347
+ },
348
+ has(i, l) {
349
+ return typeof l == "symbol" || l in i ? Reflect.has(i, l) : i.has(l);
350
+ },
351
+ set(i, l, s, n) {
352
+ return typeof l == "symbol" || l in i ? Reflect.set(i, l, s, n) : (i.set(l, s), !0);
353
+ }
354
+ }
355
+ );
356
+ }
357
+ function M(o, r) {
358
+ const { gl: e, materials: a, glSlTypes: t } = o, {
359
+ name: c,
360
+ vertexShader: u,
361
+ fragmentShader: i,
362
+ uniforms: l
363
+ } = r;
364
+ if (a.has(c))
365
+ return;
366
+ const s = [
367
+ { type: e.VERTEX_SHADER, source: u },
368
+ { type: e.FRAGMENT_SHADER, source: i.includes("precision") ? i : `precision mediump float;
369
+ ${i}` }
370
+ ].map(({ type: T, source: d }) => {
371
+ const E = e.createShader(T);
372
+ if (!E)
373
+ throw new Error("failed to create shader");
374
+ if (e.shaderSource(E, d), e.compileShader(E), !e.getShaderParameter(E, e.COMPILE_STATUS))
375
+ throw new Error(`failed to compiling shader:
376
+ ${d}
377
+ ${e.getShaderInfoLog(E)}`);
378
+ return E;
379
+ }), n = e.createProgram();
380
+ if (!n)
381
+ throw new Error("failed to create program");
382
+ if (s.forEach((T) => e.attachShader(n, T)), e.linkProgram(n), s.forEach((T) => e.deleteShader(T)), !e.getProgramParameter(n, e.LINK_STATUS))
383
+ throw new Error(`failed to initing program: ${e.getProgramInfoLog(n)}`);
384
+ const f = {};
385
+ for (let T = e.getProgramParameter(n, e.ACTIVE_ATTRIBUTES), d = 0; d < T; d++) {
386
+ const E = e.getActiveAttrib(n, d);
387
+ if (!E)
388
+ continue;
389
+ const m = E.name.replace(/\[.*?]$/, "");
390
+ f[m] = {
391
+ type: t[E.type],
392
+ isArray: m !== E.name,
393
+ location: e.getAttribLocation(n, m)
394
+ };
395
+ }
396
+ const R = {};
397
+ for (let T = e.getProgramParameter(n, e.ACTIVE_UNIFORMS), d = 0; d < T; d++) {
398
+ const E = e.getActiveUniform(n, d);
399
+ if (!E)
400
+ continue;
401
+ const m = E.name.replace(/\[.*?]$/, "");
402
+ R[m] = {
403
+ type: t[E.type],
404
+ isArray: m !== E.name,
405
+ location: e.getUniformLocation(n, m)
406
+ };
407
+ }
408
+ const g = {
409
+ ...r,
410
+ program: n,
411
+ attributes: f,
412
+ uniforms: R,
413
+ setAttributes(T) {
414
+ for (const [d, E] of Object.entries(T)) {
415
+ const m = f[d];
416
+ if (!m)
417
+ continue;
418
+ const { type: A, isArray: x, location: b } = m;
419
+ if (E instanceof WebGLBuffer) {
420
+ e.bindBuffer(e.ARRAY_BUFFER, E);
421
+ const h = e.getAttribLocation(n, d);
422
+ switch (A) {
423
+ case "vec2":
424
+ e.vertexAttribPointer(h, 2, e.FLOAT, !1, 0, 0), e.enableVertexAttribArray(h);
425
+ break;
426
+ case "vec3":
427
+ e.vertexAttribPointer(h, 3, e.FLOAT, !1, 0, 0), e.enableVertexAttribArray(h);
428
+ break;
429
+ }
430
+ } else
431
+ switch (A) {
432
+ case "float":
433
+ x ? e.vertexAttrib1fv(b, E) : e.vertexAttrib1f(b, E);
434
+ break;
435
+ case "vec2":
436
+ e.vertexAttrib2fv(b, E);
437
+ break;
438
+ case "vec3":
439
+ e.vertexAttrib3fv(b, E);
440
+ break;
441
+ case "vec4":
442
+ e.vertexAttrib4fv(b, E);
443
+ break;
444
+ }
445
+ }
446
+ },
447
+ setUniforms(T) {
448
+ var d;
449
+ for (const [E, m] of Object.entries(T)) {
450
+ const A = R[E];
451
+ if (!A)
452
+ continue;
453
+ const { type: x, isArray: b, location: h } = A;
454
+ switch (x) {
455
+ case "float":
456
+ b ? e.uniform1fv(h, m) : e.uniform1f(h, m);
457
+ break;
458
+ case "bool":
459
+ case "int":
460
+ b ? e.uniform1iv(h, m) : e.uniform1i(h, m);
461
+ break;
462
+ case "vec2":
463
+ e.uniform2fv(h, m);
464
+ break;
465
+ case "vec3":
466
+ e.uniform3fv(h, m);
467
+ break;
468
+ case "vec4":
469
+ e.uniform4fv(h, m);
470
+ break;
471
+ case "mat2":
472
+ e.uniformMatrix2fv(h, !1, m);
473
+ break;
474
+ case "mat3":
475
+ e.uniformMatrix3fv(h, !1, m);
476
+ break;
477
+ case "mat4":
478
+ e.uniformMatrix4fv(h, !1, m);
479
+ break;
480
+ case "sampler2D":
481
+ e.bindTexture(
482
+ e.TEXTURE_2D,
483
+ ((d = o.resources.get(m)) == null ? void 0 : d.texture) ?? o.glDefaultTexture
484
+ ), e.uniform1i(h, 0);
485
+ break;
486
+ }
487
+ }
488
+ }
489
+ };
490
+ l && g.setUniforms(l), a.set(c, g);
491
+ }
492
+ function I(o, r) {
493
+ o.singleton("gl", () => {
494
+ const { view: e } = o, a = e.getContext("webgl", r) || e.getContext("experimental-webgl", r);
495
+ if (!a)
496
+ throw new Error("failed to getContext for webgl");
497
+ return a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL, !0), a.pixelStorei(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !0), a.clearColor(0, 0, 0, 0), a.enable(a.DEPTH_TEST), a.enable(a.CULL_FACE), a.enable(a.BLEND), a.blendFunc(a.SRC_ALPHA, a.ONE_MINUS_SRC_ALPHA), a;
498
+ }), o.singleton("glDefaultTexture", () => {
499
+ const { gl: e, width: a, height: t } = o, c = e.createTexture();
500
+ return e.bindTexture(e.TEXTURE_2D, c), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, a, t, 0, e.RGBA, e.UNSIGNED_BYTE, null), c;
501
+ }), o.singleton("glFramebuffers", () => {
502
+ const { gl: e } = o;
503
+ return Array.from({ length: 2 }, () => {
504
+ const a = e.createTexture(), t = e.createFramebuffer(), c = e.createRenderbuffer();
505
+ function u() {
506
+ const { width: i, height: l } = o;
507
+ e.bindTexture(e.TEXTURE_2D, a), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, i, l, 0, e.RGBA, e.UNSIGNED_BYTE, null), e.bindRenderbuffer(e.RENDERBUFFER, c), e.renderbufferStorage(e.RENDERBUFFER, e.DEPTH_COMPONENT16, i, l);
508
+ }
509
+ return u(), e.bindTexture(e.TEXTURE_2D, a), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.bindFramebuffer(e.FRAMEBUFFER, t), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, a, 0), e.bindRenderbuffer(e.RENDERBUFFER, c), e.framebufferRenderbuffer(e.FRAMEBUFFER, e.DEPTH_ATTACHMENT, e.RENDERBUFFER, c), {
510
+ buffer: t,
511
+ depthBuffer: c,
512
+ texture: a,
513
+ resize: u
514
+ };
515
+ });
516
+ }), o.singleton("glDrawModes", () => {
517
+ const { gl: e } = o;
518
+ return {
519
+ points: e.POINTS,
520
+ linear: e.LINEAR,
521
+ triangles: e.TRIANGLES,
522
+ triangleStrip: e.TRIANGLE_STRIP,
523
+ triangleFan: e.TRIANGLE_FAN
524
+ };
525
+ }), o.singleton("glSlTypes", () => {
526
+ const e = o.gl;
527
+ return {
528
+ [e.FLOAT]: "float",
529
+ [e.FLOAT_VEC2]: "vec2",
530
+ [e.FLOAT_VEC3]: "vec3",
531
+ [e.FLOAT_VEC4]: "vec4",
532
+ [e.INT]: "int",
533
+ [e.INT_VEC2]: "ivec2",
534
+ [e.INT_VEC3]: "ivec3",
535
+ [e.INT_VEC4]: "ivec4",
536
+ [e.UNSIGNED_INT]: "uint",
537
+ [e.UNSIGNED_INT_VEC2]: "uvec2",
538
+ [e.UNSIGNED_INT_VEC3]: "uvec3",
539
+ [e.UNSIGNED_INT_VEC4]: "uvec4",
540
+ [e.BOOL]: "bool",
541
+ [e.BOOL_VEC2]: "bvec2",
542
+ [e.BOOL_VEC3]: "bvec3",
543
+ [e.BOOL_VEC4]: "bvec4",
544
+ [e.FLOAT_MAT2]: "mat2",
545
+ [e.FLOAT_MAT3]: "mat3",
546
+ [e.FLOAT_MAT4]: "mat4",
547
+ [e.SAMPLER_2D]: "sampler2D",
548
+ [e.INT_SAMPLER_2D]: "sampler2D",
549
+ [e.UNSIGNED_INT_SAMPLER_2D]: "sampler2D",
550
+ [e.SAMPLER_CUBE]: "samplerCube",
551
+ [e.INT_SAMPLER_CUBE]: "samplerCube",
552
+ [e.UNSIGNED_INT_SAMPLER_CUBE]: "samplerCube",
553
+ [e.SAMPLER_2D_ARRAY]: "sampler2DArray",
554
+ [e.INT_SAMPLER_2D_ARRAY]: "sampler2DArray",
555
+ [e.UNSIGNED_INT_SAMPLER_2D_ARRAY]: "sampler2DArray"
556
+ };
557
+ }), o.singleton("glExtensions", () => ({
558
+ loseContext: o.gl.getExtension("WEBGL_lose_context")
559
+ }));
560
+ }
561
+ function B(o, r) {
562
+ const { gl: e, shapes: a, glDrawModes: t } = o, {
563
+ name: c,
564
+ type: u = "2d",
565
+ mode: i = "triangles",
566
+ data: l = new Float32Array([])
567
+ } = r, s = e.createBuffer();
568
+ e.bindBuffer(e.ARRAY_BUFFER, s), e.bufferData(e.ARRAY_BUFFER, l, e.STATIC_DRAW), a.set(c, {
569
+ mode: t[i],
570
+ count: l.byteLength / l.BYTES_PER_ELEMENT / (u === "2d" ? 2 : 3),
571
+ buffer: s
572
+ });
573
+ }
574
+ function y(o, r) {
575
+ const { gl: e, shapes: a, materials: t, nodeRenderers: c } = o, { name: u, shape: i, material: l } = r, s = typeof i == "string" ? i : `${u}-shape`;
576
+ typeof i != "string" && o.registerShape({ ...i, name: s });
577
+ const n = typeof l == "string" ? l : `${u}-material`;
578
+ typeof l != "string" && o.registerMaterial({ ...l, name: n });
579
+ const f = a.get(s), R = t.get(n);
580
+ if (!f || !R)
581
+ return;
582
+ const { buffer: g } = f;
583
+ R.setAttributes({ aPosition: g }), c.set(u, {
584
+ ...r,
585
+ shape: s,
586
+ material: n,
587
+ render: (T, d) => {
588
+ var p;
589
+ const E = a.get(s), m = t.get(n);
590
+ if (!E || !m)
591
+ return;
592
+ const { program: A } = m, { mode: x, count: b } = E;
593
+ e.useProgram(A);
594
+ const h = (p = r.update) == null ? void 0 : p.call(r, T, d);
595
+ h && m.setUniforms(h), e.drawArrays(x, 0, b);
596
+ }
597
+ });
598
+ }
599
+ function w(o, r) {
600
+ const { children: e } = o;
601
+ function a(t, c = []) {
602
+ for (let u = t.length - 1; u >= 0; u--) {
603
+ const i = [...c, u], l = t[u];
604
+ a(l.children ?? [], i), r(l, i);
605
+ }
606
+ }
607
+ a(e);
608
+ }
609
+ function O(o, r) {
610
+ const { gl: e, resources: a } = o, { name: t, data: c } = r, u = {
611
+ loading: !0,
612
+ texture: null
613
+ };
614
+ function i() {
615
+ u.texture = e.createTexture(), u.texture && (e.bindTexture(e.TEXTURE_2D, u.texture), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, c)), u.loading = !1;
616
+ }
617
+ c instanceof HTMLImageElement ? c.addEventListener("load", i, { once: !0 }) : i(), a.set(t, u);
618
+ }
619
+ function G(o = {}) {
620
+ var i, l;
621
+ const {
622
+ view: r = document.createElement("canvas"),
623
+ children: e = [],
624
+ plugins: a = []
625
+ } = o, t = C();
626
+ t.set("view", r), I(t, o), t.bind("width", () => t.gl.drawingBufferWidth), t.bind("height", () => t.gl.drawingBufferHeight), t.singleton("plugins", () => {
627
+ const s = /* @__PURE__ */ new Map();
628
+ return a.forEach((n) => {
629
+ var f;
630
+ (f = n.register) == null || f.call(n, t), s.set(n.name, n);
631
+ }), s;
632
+ }), t.singleton("beforeRenderPlugins", () => Array.from(t.plugins.values()).filter((s) => "beforeRender" in s)), t.singleton("afterRenderPlugins", () => Array.from(t.plugins.values()).filter((s) => "afterRender" in s)), t.set("children", e), t.set("shapes", /* @__PURE__ */ new Map()), t.set("registerShape", (s) => B(t, s)), t.set("materials", /* @__PURE__ */ new Map()), t.set("registerMaterial", (s) => M(t, s)), t.set("resources", /* @__PURE__ */ new Map()), t.set("registerResource", (s) => O(t, s)), t.set("nodeRenderers", /* @__PURE__ */ new Map()), t.set("registerNodeRenderer", (s) => y(t, s)), t.set("forEachNode", (s) => w(t, s)), t.set("load", async () => {
633
+ t.get("plugins");
634
+ const s = Array.from(t.nodeRenderers.values());
635
+ for (t.forEachNode((n, f) => {
636
+ s.filter((g) => !g.include && !g.exclude || g.include && g.include(n, f) || g.exclude && !g.exclude(n, f)).forEach((g) => {
637
+ var T;
638
+ return (T = g.update) == null ? void 0 : T.call(g, n, 0);
639
+ });
640
+ }); Array.from(t.resources.values()).some((n) => n.loading); )
641
+ await new Promise((n) => setTimeout(n, 100));
642
+ return !0;
643
+ }), t.set("render", (s) => P(t, s)), t.set("startRenderLoop", () => {
644
+ let s = 0, n = 0;
645
+ f(0);
646
+ function f(R) {
647
+ requestAnimationFrame(f), P(t, n), R *= 1e-3, n += R - s, s = R;
648
+ }
649
+ });
650
+ function c(s) {
651
+ s.preventDefault(), setTimeout(() => {
652
+ var n;
653
+ t.gl.isContextLost() && ((n = t.glExtensions.loseContext) == null || n.restoreContext());
654
+ }, 0);
655
+ }
656
+ function u() {
657
+ }
658
+ return (i = r.addEventListener) == null || i.call(r, "webglcontextlost", c, !1), (l = r.addEventListener) == null || l.call(r, "webglcontextrestored", u, !1), t.set("destroy", () => {
659
+ var s, n, f;
660
+ (s = r.removeEventListener) == null || s.call(r, "webglcontextlost", c), (n = r.removeEventListener) == null || n.call(r, "webglcontextrestored", u), t.gl.useProgram(null), (f = t.glExtensions.loseContext) == null || f.loseContext();
661
+ }), t;
662
+ }
2
663
  export {
3
- o as one
664
+ U as basePlugin,
665
+ G as createCanvas,
666
+ F as fadePlugin,
667
+ D as nodeImagePlugin,
668
+ N as nodeTextPlugin,
669
+ X as plugins,
670
+ L as selector2dPlugin,
671
+ S as transform2dPlugin
4
672
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modern-canvas",
3
3
  "type": "module",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "packageManager": "pnpm@7.26.2",
6
6
  "description": "A data driven modern canvas library",
7
7
  "author": "wxm",
@@ -45,21 +45,24 @@
45
45
  "types"
46
46
  ],
47
47
  "scripts": {
48
- "dev": "vite",
48
+ "dev": "vite docs",
49
49
  "lint": "eslint src",
50
50
  "test": "vitest --no-threads --no-isolate",
51
51
  "build": "vite build && tsc --project tsconfig.build.json",
52
+ "build:docs": "vite build docs",
52
53
  "version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
53
54
  "release": "bumpp package.json --commit \"release: v%s\" --push --all --tag"
54
55
  },
55
56
  "devDependencies": {
56
57
  "@qq15725/eslint-config": "^1.1.0",
57
58
  "@types/node": "^18.14.0",
59
+ "@vitejs/plugin-vue": "^4.1.0",
58
60
  "bumpp": "^8.2.1",
59
61
  "conventional-changelog-cli": "^2.2.2",
60
62
  "eslint": "^8.34.0",
61
63
  "typescript": "^4.9.5",
62
64
  "vite": "^4.1.2",
63
- "vitest": "^0.28.5"
65
+ "vitest": "^0.28.5",
66
+ "vue": "^3.2.47"
64
67
  }
65
68
  }
@@ -0,0 +1,42 @@
1
+ import type { InternalResource, Resource } from './resource';
2
+ import type { InternalShape, Shape } from './shape';
3
+ import type { GlDrawModes, GlExtensions, GlFramebuffer, GlSlTypes } from './gl';
4
+ import type { InternalNodeRenderer, NodeRenderer } from './node-renderer';
5
+ import type { Node } from './node';
6
+ import type { InternalMaterial, Material } from './material';
7
+ import type { Plugin } from './plugin';
8
+ import type { Container } from './container';
9
+ export interface CanvasOptions extends WebGLContextAttributes {
10
+ view?: HTMLCanvasElement;
11
+ children?: Node[];
12
+ plugins?: Plugin[];
13
+ }
14
+ export interface Canvas extends Container {
15
+ view: HTMLCanvasElement;
16
+ children: Node[];
17
+ gl: WebGLRenderingContext;
18
+ glDefaultTexture: WebGLTexture;
19
+ glFramebuffers: GlFramebuffer[];
20
+ glDrawModes: GlDrawModes;
21
+ glSlTypes: GlSlTypes;
22
+ glExtensions: GlExtensions;
23
+ width: number;
24
+ height: number;
25
+ plugins: Map<string, Plugin>;
26
+ beforeRenderPlugins: Plugin[];
27
+ afterRenderPlugins: Plugin[];
28
+ shapes: Map<string, InternalShape>;
29
+ registerShape(shape: Shape): void;
30
+ materials: Map<string, InternalMaterial>;
31
+ registerMaterial(options: Material): void;
32
+ resources: Map<string, InternalResource>;
33
+ registerResource(options: Resource): void;
34
+ nodeRenderers: Map<string, InternalNodeRenderer>;
35
+ registerNodeRenderer(options: NodeRenderer): void;
36
+ forEachNode(callbackFn: (node: Node, path: number[]) => void): void;
37
+ load(): Promise<void>;
38
+ render(time?: number): void;
39
+ startRenderLoop(): void;
40
+ destroy(): void;
41
+ }
42
+ export declare function createCanvas(options?: CanvasOptions): Canvas;
@@ -0,0 +1,14 @@
1
+ export interface Container {
2
+ instances: Map<string, any>;
3
+ bindings: Map<string, {
4
+ value: () => any;
5
+ shared: boolean;
6
+ }>;
7
+ get<T = any>(key: string): T;
8
+ has(key: string): boolean;
9
+ set<T = any>(key: string, value: T): void;
10
+ bind<T = any>(key: string, value: () => T, shared?: boolean): void;
11
+ singleton<T = any>(key: string, value: () => T): void;
12
+ [key: string]: any;
13
+ }
14
+ export declare function createContainer(): Container;
package/types/gl.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import type { Canvas } from './canvas';
2
+ export interface GlDrawModes {
3
+ points: GLenum;
4
+ linear: GLenum;
5
+ triangles: GLenum;
6
+ triangleStrip: GLenum;
7
+ triangleFan: GLenum;
8
+ }
9
+ export type GlSlType = 'float' | 'vec2' | 'vec3' | 'vec4' | 'int' | 'ivec2' | 'ivec3' | 'ivec4' | 'uint' | 'uvec2' | 'uvec3' | 'uvec4' | 'bool' | 'bvec2' | 'bvec3' | 'bvec4' | 'mat2' | 'mat3' | 'mat4' | 'sampler2D' | 'samplerCube' | 'sampler2DArray';
10
+ export type GlSlTypes = Record<number, GlSlType>;
11
+ export interface GlFramebuffer {
12
+ buffer: WebGLFramebuffer | null;
13
+ depthBuffer: WebGLRenderbuffer | null;
14
+ texture: WebGLTexture | null;
15
+ resize(): void;
16
+ }
17
+ export interface GlExtensions {
18
+ loseContext: WEBGL_lose_context | null;
19
+ }
20
+ export declare function provideGl(canvas: Canvas, options?: WebGLContextAttributes): void;
package/types/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export declare const one = 1;
1
+ export * from './plugins';
2
+ export * from './canvas';
@@ -0,0 +1,26 @@
1
+ import type { GlSlType } from './gl';
2
+ import type { Canvas } from './canvas';
3
+ export interface Material {
4
+ name: string;
5
+ vertexShader: string;
6
+ fragmentShader: string;
7
+ uniforms?: Record<string, any>;
8
+ }
9
+ export type InternalMaterial = Material & {
10
+ program: WebGLProgram;
11
+ attributes: Record<string, MaterialAttribute>;
12
+ uniforms: Record<string, MaterialUniform>;
13
+ setAttributes(attributes: Record<string, any>): void;
14
+ setUniforms(uniforms: Record<string, any>): void;
15
+ };
16
+ export interface MaterialAttribute {
17
+ type: GlSlType;
18
+ isArray: boolean;
19
+ location: GLint;
20
+ }
21
+ export interface MaterialUniform {
22
+ type: GlSlType;
23
+ isArray: boolean;
24
+ location: WebGLUniformLocation | null;
25
+ }
26
+ export declare function registerMaterial(canvas: Canvas, material: Material): void;
@@ -0,0 +1,18 @@
1
+ import type { Canvas } from './canvas';
2
+ import type { Material } from './material';
3
+ import type { Shape } from './shape';
4
+ import type { Node } from './node';
5
+ export interface NodeRenderer {
6
+ name: string;
7
+ include?: (node: Node, path: number[]) => boolean;
8
+ exclude?: (node: Node, path: number[]) => boolean;
9
+ shape: string | Omit<Shape, 'name'>;
10
+ material: string | Omit<Material, 'name'>;
11
+ update?(node: Node, time: number): undefined | Record<string, any>;
12
+ }
13
+ export interface InternalNodeRenderer extends NodeRenderer {
14
+ shape: string;
15
+ material: string;
16
+ render(node: Node, time: number): void;
17
+ }
18
+ export declare function registerNodeRenderer(canvas: Canvas, renderer: NodeRenderer): void;
@@ -0,0 +1,10 @@
1
+ import type { Canvas } from './canvas';
2
+ export interface Node {
3
+ [key: string]: any;
4
+ x?: number;
5
+ y?: number;
6
+ width?: number;
7
+ height?: number;
8
+ children?: Node[];
9
+ }
10
+ export declare function forEachNode(canvas: Canvas, callbackFn: (node: Node, path: number[]) => void): void;
@@ -0,0 +1,8 @@
1
+ import type { Canvas } from './canvas';
2
+ export interface Plugin {
3
+ name: string;
4
+ register?(canvas: Canvas): void;
5
+ beforeRender?(canvas: Canvas): void;
6
+ afterRender?(canvas: Canvas): void;
7
+ }
8
+ export declare function definePlugin(plugin: Plugin | (() => Plugin)): Plugin;
@@ -0,0 +1 @@
1
+ export declare const basePlugin: import("../plugin").Plugin;
@@ -0,0 +1 @@
1
+ export declare const fadePlugin: import("../plugin").Plugin;
@@ -0,0 +1,7 @@
1
+ export * from './base';
2
+ export * from './fade';
3
+ export * from './node-image';
4
+ export * from './node-text';
5
+ export * from './selector2d';
6
+ export * from './transform2d';
7
+ export declare const plugins: import("../plugin").Plugin[];
@@ -0,0 +1 @@
1
+ export declare const nodeImagePlugin: import("../plugin").Plugin;
@@ -0,0 +1 @@
1
+ export declare const nodeTextPlugin: import("../plugin").Plugin;
@@ -0,0 +1 @@
1
+ export declare const selector2dPlugin: import("../plugin").Plugin;
@@ -0,0 +1 @@
1
+ export declare const transform2dPlugin: import("../plugin").Plugin;
@@ -0,0 +1,2 @@
1
+ import type { Canvas } from './canvas';
2
+ export declare function render(canvas: Canvas, time?: number): void;
@@ -0,0 +1,10 @@
1
+ import type { Canvas } from './canvas';
2
+ export interface Resource {
3
+ name: string;
4
+ data: TexImageSource;
5
+ }
6
+ export type InternalResource = {
7
+ loading: boolean;
8
+ texture: WebGLTexture | null;
9
+ };
10
+ export declare function registerResource(canvas: Canvas, resource: Resource): void;
@@ -0,0 +1,14 @@
1
+ import type { GlDrawModes } from './gl';
2
+ import type { Canvas } from './canvas';
3
+ export interface Shape {
4
+ name: string;
5
+ type?: '2d' | '3d';
6
+ mode?: keyof GlDrawModes;
7
+ data?: Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array | Int8Array | Int16Array | Int32Array | BigUint64Array | BigInt64Array | Float32Array | Float64Array;
8
+ }
9
+ export interface InternalShape {
10
+ mode: GLenum;
11
+ count: number;
12
+ buffer: WebGLBuffer | null;
13
+ }
14
+ export declare function registerShape(canvas: Canvas, shape: Shape): void;
@@ -0,0 +1 @@
1
+ export * from './matrix3';
@@ -0,0 +1,7 @@
1
+ export declare class Matrix3 extends Float32Array {
2
+ static identity(): Matrix3;
3
+ static translation(tx: number, ty: number): Matrix3;
4
+ static rotation(radians: number): Matrix3;
5
+ static scaling(sx: number, sy: number): Matrix3;
6
+ multiply(matrix3: Matrix3): this;
7
+ }