shaderpad 1.0.0-alpha.5 → 1.0.0-alpha.6
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 +24 -19
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,25 +18,25 @@ const fragmentShaderSrc = `
|
|
|
18
18
|
precision highp float;
|
|
19
19
|
|
|
20
20
|
// Built-in variables.
|
|
21
|
-
varying vec2
|
|
22
|
-
uniform float
|
|
23
|
-
uniform vec2
|
|
24
|
-
uniform vec4
|
|
21
|
+
varying vec2 v_uv;
|
|
22
|
+
uniform float u_time;
|
|
23
|
+
uniform vec2 u_resolution;
|
|
24
|
+
uniform vec4 u_cursor; // [cursorX, cursorY, scrollX, scrollY]
|
|
25
25
|
|
|
26
26
|
// Custom variables.
|
|
27
|
-
uniform vec3
|
|
27
|
+
uniform vec3 u_cursorColor;
|
|
28
28
|
|
|
29
29
|
void main() {
|
|
30
|
-
vec2 uv =
|
|
30
|
+
vec2 uv = v_uv * u_resolution;
|
|
31
31
|
vec2 dotGrid = mod(uv, 50.) - 25.;
|
|
32
32
|
float dotDist = length(dotGrid);
|
|
33
33
|
float dot = step(dotDist, 5.);
|
|
34
34
|
|
|
35
|
-
float cursorDist = distance(uv,
|
|
36
|
-
float cursor = step(cursorDist, 25. + sin(
|
|
35
|
+
float cursorDist = distance(uv, u_cursor.xy * u_resolution);
|
|
36
|
+
float cursor = step(cursorDist, 25. + sin(u_time * 5.) * 5.);
|
|
37
37
|
|
|
38
38
|
vec3 color = mix(vec3(0., 0., 1.), vec3(1.), dot);
|
|
39
|
-
color = mix(color,
|
|
39
|
+
color = mix(color, u_cursorColor, cursor);
|
|
40
40
|
|
|
41
41
|
gl_FragColor = vec4(color, 1.);
|
|
42
42
|
}
|
|
@@ -48,11 +48,11 @@ const shader = new ShaderPad(fragmentShaderSrc /* , canvasElement */);
|
|
|
48
48
|
// Add your own custom uniforms.
|
|
49
49
|
const getColor = (time: number) =>
|
|
50
50
|
[time, time + (Math.PI * 2) / 3, time + (Math.PI * 4) / 3].map(x => 1 + Math.sin(x) / 2);
|
|
51
|
-
shader.initializeUniform('
|
|
51
|
+
shader.initializeUniform('u_cursorColor', 'float', getColor(0));
|
|
52
52
|
|
|
53
53
|
// Start the render loop.
|
|
54
54
|
shader.play(time => {
|
|
55
|
-
shader.updateUniforms({
|
|
55
|
+
shader.updateUniforms({ u_cursorColor: getColor(time) });
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
// Optionally pause the render loop.
|
|
@@ -63,14 +63,19 @@ See the [`examples/` directory](./examples/) for more.
|
|
|
63
63
|
|
|
64
64
|
## Included uniforms
|
|
65
65
|
|
|
66
|
-
| Uniform
|
|
67
|
-
|
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
|
|
66
|
+
| Uniform | Type | Description |
|
|
67
|
+
| -------------- | -------- | -------------------------------------------------- |
|
|
68
|
+
| `u_time` | float | The current time in seconds. |
|
|
69
|
+
| `u_frame` | int | The current frame number. |
|
|
70
|
+
| `u_resolution` | float[2] | The canvas element's dimensions. |
|
|
71
|
+
| `u_cursor` | float[4] | Cursor position (x, y) and scroll position (z, w). |
|
|
72
|
+
| `u_click` | float[3] | Click position (x, y) and left click state (z). |
|
|
73
|
+
|
|
74
|
+
## Included varyings
|
|
75
|
+
|
|
76
|
+
| Varying | Type | Description |
|
|
77
|
+
| ------- | -------- | ----------------------------------- |
|
|
78
|
+
| `v_uv` | float[2] | The UV coordinates of the fragment. |
|
|
74
79
|
|
|
75
80
|
## Contributing
|
|
76
81
|
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";var h=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var d=(n,e)=>{for(var s in e)h(n,s,{get:e[s],enumerable:!0})},f=(n,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of u(e))!m.call(n,i)&&i!==s&&h(n,i,{get:()=>e[i],enumerable:!(t=g(e,i))||t.enumerable});return n};var v=n=>f(h({},"__esModule",{value:!0}),n);var T={};d(T,{default:()=>p});module.exports=v(T);var E=`
|
|
2
2
|
attribute vec2 aPosition;
|
|
3
|
-
varying vec2
|
|
3
|
+
varying vec2 v_uv;
|
|
4
4
|
void main() {
|
|
5
|
-
|
|
5
|
+
v_uv = aPosition * 0.5 + 0.5;
|
|
6
6
|
gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
7
7
|
}
|
|
8
|
-
`,o=class{constructor(e,s=null){this.isInternalCanvas=!1;this.isTouchDevice=!1;this.uniforms=new Map;this.textures=new Map;this.buffer=null;this.program=null;this.eventListeners=new Map;this.frame=0;this.cursorPosition=[.5,.5];this.scrollX=0;this.scrollY=0;this.clickPosition=[.5,.5];this.isMouseDown=!1;this.canvas=s||document.createElement("canvas"),s||(this.isInternalCanvas=!0,document.body.appendChild(this.canvas),this.canvas.style.position="fixed",this.canvas.style.inset="0",this.canvas.style.height="100dvh",this.canvas.style.width="100dvw"),this.gl=this.canvas.getContext("webgl"),this.downloadLink=document.createElement("a"),this.fragmentShaderSrc=e,this.animationFrameId=null,this.resizeObserver=new ResizeObserver(()=>this.resizeCanvas()),this.resizeObserver.observe(this.canvas),this.init(),this.addEventListeners()}init(){let e=E;if(this.program=this.gl.createProgram(),!this.program)throw new Error("Failed to create WebGL program");let s=this.createShader(this.gl.VERTEX_SHADER,e),t=this.createShader(this.gl.FRAGMENT_SHADER,this.fragmentShaderSrc);if(this.gl.attachShader(this.program,s),this.gl.attachShader(this.program,t),this.gl.linkProgram(this.program),this.gl.deleteShader(s),this.gl.deleteShader(t),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw console.error("Program link error:",this.gl.getProgramInfoLog(this.program)),this.gl.deleteProgram(this.program),new Error("Failed to link WebGL program");let i=this.gl.getAttribLocation(this.program,"aPosition");this.setupBuffer(i),this.resizeCanvas(),this.gl.useProgram(this.program),this.initializeUniform("
|
|
8
|
+
`,o=class{constructor(e,s=null){this.isInternalCanvas=!1;this.isTouchDevice=!1;this.uniforms=new Map;this.textures=new Map;this.buffer=null;this.program=null;this.eventListeners=new Map;this.frame=0;this.cursorPosition=[.5,.5];this.scrollX=0;this.scrollY=0;this.clickPosition=[.5,.5];this.isMouseDown=!1;this.canvas=s||document.createElement("canvas"),s||(this.isInternalCanvas=!0,document.body.appendChild(this.canvas),this.canvas.style.position="fixed",this.canvas.style.inset="0",this.canvas.style.height="100dvh",this.canvas.style.width="100dvw"),this.gl=this.canvas.getContext("webgl"),this.downloadLink=document.createElement("a"),this.fragmentShaderSrc=e,this.animationFrameId=null,this.resizeObserver=new ResizeObserver(()=>this.resizeCanvas()),this.resizeObserver.observe(this.canvas),this.init(),this.addEventListeners()}init(){let e=E;if(this.program=this.gl.createProgram(),!this.program)throw new Error("Failed to create WebGL program");let s=this.createShader(this.gl.VERTEX_SHADER,e),t=this.createShader(this.gl.FRAGMENT_SHADER,this.fragmentShaderSrc);if(this.gl.attachShader(this.program,s),this.gl.attachShader(this.program,t),this.gl.linkProgram(this.program),this.gl.deleteShader(s),this.gl.deleteShader(t),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw console.error("Program link error:",this.gl.getProgramInfoLog(this.program)),this.gl.deleteProgram(this.program),new Error("Failed to link WebGL program");let i=this.gl.getAttribLocation(this.program,"aPosition");this.setupBuffer(i),this.resizeCanvas(),this.gl.useProgram(this.program),this.initializeUniform("u_resolution","float",[this.canvas.width,this.canvas.height]),this.initializeUniform("u_cursor","float",[...this.cursorPosition,this.scrollX,this.scrollY]),this.initializeUniform("u_click","float",[...this.clickPosition,this.isMouseDown?1:0]),this.initializeUniform("u_time","float",0),this.initializeUniform("u_frame","int",0)}createShader(e,s){let t=this.gl.createShader(e);if(this.gl.shaderSource(t,s),this.gl.compileShader(t),!this.gl.getShaderParameter(t,this.gl.COMPILE_STATUS))throw console.error("Shader compilation failed:",s),console.error(this.gl.getShaderInfoLog(t)),this.gl.deleteShader(t),new Error("Shader compilation failed");return t}setupBuffer(e){let s=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]);this.buffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.buffer),this.gl.bufferData(this.gl.ARRAY_BUFFER,s,this.gl.STATIC_DRAW),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.enableVertexAttribArray(e),this.gl.vertexAttribPointer(e,2,this.gl.FLOAT,!1,0,0)}resizeCanvas(){let e=window.devicePixelRatio||1,s=this.canvas.clientWidth*e,t=this.canvas.clientHeight*e,i=getComputedStyle(this.canvas),r=i.width!==`${this.canvas.width}px`&&i.width!=="auto",a=i.height!==`${this.canvas.height}px`&&i.height!=="auto";(!r||!a)&&(this.canvas.style.width=`${this.canvas.clientWidth}px`,this.canvas.style.height=`${this.canvas.clientHeight}px`),(this.canvas.width!==s||this.canvas.height!==t)&&(this.canvas.width=s,this.canvas.height=t,this.gl.viewport(0,0,this.gl.drawingBufferWidth,this.gl.drawingBufferHeight),this.uniforms.has("u_resolution")&&this.updateUniforms({u_resolution:[this.canvas.width,this.canvas.height]}))}addEventListeners(){let e=(t,i)=>{if(!this.uniforms.has("u_cursor"))return;let r=this.canvas.getBoundingClientRect();this.cursorPosition[0]=(t-r.left)/r.width,this.cursorPosition[1]=1-(i-r.top)/r.height,this.updateUniforms({u_cursor:[this.cursorPosition[0],this.cursorPosition[1],this.scrollX,this.scrollY]})},s=(t,i,r)=>{if(this.isMouseDown=t,t){let a=this.canvas.getBoundingClientRect(),l=i,c=r;this.clickPosition[0]=(l-a.left)/a.width,this.clickPosition[1]=1-(c-a.top)/a.height}this.updateUniforms({u_click:[this.clickPosition[0],this.clickPosition[1],this.isMouseDown?1:0]})};this.eventListeners.set("mousemove",t=>{let i=t;this.isTouchDevice||e(i.clientX,i.clientY)}),this.eventListeners.set("mousedown",t=>{let i=t;this.isTouchDevice||i.button===0&&(this.isMouseDown=!0,s(!0,i.clientX,i.clientY))}),this.eventListeners.set("mouseup",t=>{let i=t;this.isTouchDevice||i.button===0&&s(!1)}),this.eventListeners.set("wheel",t=>{let i=t;this.scrollX+=i.deltaX*.01,this.scrollY+=i.deltaY*.01,e(i.clientX,i.clientY)}),this.eventListeners.set("touchmove",t=>{let i=t;i.touches.length>0&&e(i.touches[0].clientX,i.touches[0].clientY)}),this.eventListeners.set("touchstart",t=>{let i=t;this.isTouchDevice=!0,i.touches.length>0&&(s(!0,i.touches[0].clientX,i.touches[0].clientY),e(i.touches[0].clientX,i.touches[0].clientY))}),this.eventListeners.set("touchend",t=>{t.touches.length===0&&s(!1)}),this.eventListeners.forEach((t,i)=>{this.canvas.addEventListener(i,t)})}initializeUniform(e,s,t){if(this.uniforms.has(e))throw new Error(`Uniform '${e}' is already initialized.`);if(s!=="float"&&s!=="int")throw new Error(`Invalid uniform type: ${s}. Expected 'float' or 'int'.`);let i=this.gl.getUniformLocation(this.program,e);if(!i){console.debug(`Uniform ${e} not found in fragment shader. Skipping initialization.`);return}if(Array.isArray(t)||(t=[t]),t.length<1||t.length>4)throw new Error(`Invalid uniform value length: ${t.length}. Expected a length between 1 and 4.`);let r=t.length;this.uniforms.set(e,{type:s,length:r,location:i}),this.updateUniforms({[e]:t})}updateUniforms(e){Object.entries(e).forEach(([s,t])=>{if(!this.uniforms.has(s))throw new Error(`Uniform '${s}' is not initialized.`);let i=this.uniforms.get(s);if(Array.isArray(t)||(t=[t]),t.length!==i.length)throw new Error(`Invalid uniform value length: ${t.length}. Expected ${i.length}.`);this.gl[`uniform${i.length}${i.type.charAt(0)}`](i.location,...t)})}step(e){this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.uniforms.has("u_time")&&this.updateUniforms({u_time:e}),this.uniforms.has("u_frame")&&this.updateUniforms({u_frame:this.frame}),++this.frame,this.gl.drawArrays(this.gl.TRIANGLES,0,6)}play(e){let s=t=>{t/=1e3,this.step(t),e&&e(t,this.frame),this.animationFrameId=requestAnimationFrame(s)};this.animationFrameId=requestAnimationFrame(s)}pause(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}save(e){this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.drawArrays(this.gl.TRIANGLES,0,6);let s=this.canvas.toDataURL();e&&!`${e}`.toLowerCase().endsWith(".png")&&(e=`${e}.png`),this.downloadLink.download=e||"export.png",this.downloadLink.href=s,this.downloadLink.click()}initializeTexture(e,s){if(this.textures.has(e))throw new Error(`Texture '${e}' is already initialized.`);let t=this.gl.createTexture();if(!t)throw new Error("Failed to create texture");let i=this.textures.size;this.gl.activeTexture(this.gl.TEXTURE0+i),this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,!0),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.textures.set(e,{texture:t,unitIndex:i}),this.updateTextures({[e]:s});let r=this.gl.getUniformLocation(this.program,e);r&&this.gl.uniform1i(r,i)}updateTextures(e){Object.entries(e).forEach(([s,t])=>{let i=this.textures.get(s);if(!i)throw new Error(`Texture '${s}' is not initialized.`);this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,i.texture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,t)})}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.resizeObserver.unobserve(this.canvas),this.eventListeners.forEach((e,s)=>{this.canvas.removeEventListener(s,e)}),this.program&&this.gl.deleteProgram(this.program),this.textures.forEach(e=>{this.gl.deleteTexture(e.texture)}),this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null),this.isInternalCanvas&&this.canvas.remove()}},p=o;
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const defaultVertexShaderSrc = `\nattribute vec2 aPosition;\nvarying vec2 vUv;\nvoid main() {\n vUv = aPosition * 0.5 + 0.5;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}\n`;\n\ninterface Uniform {\n\ttype: 'float' | 'int';\n\tlength: 1 | 2 | 3 | 4;\n\tlocation: WebGLUniformLocation;\n}\n\ninterface Texture {\n\ttexture: WebGLTexture;\n\tunitIndex: number;\n}\n\nclass ShaderPad {\n\tprivate isInternalCanvas = false;\n\tprivate isTouchDevice = false;\n\tprivate canvas: HTMLCanvasElement;\n\tprivate gl: WebGLRenderingContext;\n\tprivate downloadLink: HTMLAnchorElement;\n\tprivate fragmentShaderSrc: string;\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string, Texture> = new Map();\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tprivate animationFrameId: number | null;\n\tprivate resizeObserver: ResizeObserver;\n\tprivate eventListeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate cursorPosition = [0.5, 0.5];\n\tprivate scrollX = 0;\n\tprivate scrollY = 0;\n\tprivate clickPosition = [0.5, 0.5];\n\tprivate isMouseDown = false;\n\n\tconstructor(fragmentShaderSrc: string, canvas: HTMLCanvasElement | null = null) {\n\t\tthis.canvas = canvas || document.createElement('canvas');\n\t\tif (!canvas) {\n\t\t\tthis.isInternalCanvas = true;\n\t\t\tdocument.body.appendChild(this.canvas);\n\t\t\tthis.canvas.style.position = 'fixed';\n\t\t\tthis.canvas.style.inset = '0';\n\t\t\tthis.canvas.style.height = '100dvh';\n\t\t\tthis.canvas.style.width = '100dvw';\n\t\t}\n\t\tthis.gl = this.canvas.getContext('webgl')!;\n\t\tthis.downloadLink = document.createElement('a');\n\t\tthis.fragmentShaderSrc = fragmentShaderSrc;\n\t\tthis.animationFrameId = null;\n\t\tthis.resizeObserver = new ResizeObserver(() => this.resizeCanvas());\n\t\tthis.resizeObserver.observe(this.canvas);\n\t\tthis.init();\n\t\tthis.addEventListeners();\n\t}\n\n\tprivate init() {\n\t\tconst vertexShaderSrc = defaultVertexShaderSrc;\n\n\t\tthis.program = this.gl.createProgram();\n\t\tif (!this.program) {\n\t\t\tthrow new Error('Failed to create WebGL program');\n\t\t}\n\t\tconst vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexShaderSrc);\n\t\tconst fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, this.fragmentShaderSrc);\n\n\t\tthis.gl.attachShader(this.program, vertexShader);\n\t\tthis.gl.attachShader(this.program, fragmentShader);\n\t\tthis.gl.linkProgram(this.program);\n\t\tthis.gl.deleteShader(vertexShader);\n\t\tthis.gl.deleteShader(fragmentShader);\n\n\t\tif (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {\n\t\t\tconsole.error('Program link error:', this.gl.getProgramInfoLog(this.program));\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t\tthrow new Error('Failed to link WebGL program');\n\t\t}\n\n\t\tconst aPosition = this.gl.getAttribLocation(this.program, 'aPosition');\n\t\tthis.setupBuffer(aPosition);\n\t\tthis.resizeCanvas();\n\n\t\tthis.gl.useProgram(this.program);\n\n\t\tthis.initializeUniform('uResolution', 'float', [this.canvas.width, this.canvas.height]);\n\t\tthis.initializeUniform('uCursor', 'float', [...this.cursorPosition, this.scrollX, this.scrollY]); // [cursorX, cursorY, scrollX, scrollY]\n\t\tthis.initializeUniform('uClick', 'float', [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0]); // [clickX, clickY, leftClick]\n\t\tthis.initializeUniform('uTime', 'float', 0);\n\t\tthis.initializeUniform('uFrame', 'int', 0);\n\t}\n\n\tprivate createShader(type: number, source: string): WebGLShader {\n\t\tconst shader = this.gl.createShader(type)!;\n\t\tthis.gl.shaderSource(shader, source);\n\t\tthis.gl.compileShader(shader);\n\t\tif (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n\t\t\tconsole.error('Shader compilation failed:', source);\n\t\t\tconsole.error(this.gl.getShaderInfoLog(shader));\n\t\t\tthis.gl.deleteShader(shader);\n\t\t\tthrow new Error('Shader compilation failed');\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate setupBuffer(aPosition: number) {\n\t\tconst quadVertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n\n\t\tthis.buffer = this.gl.createBuffer();\n\t\tthis.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);\n\t\tthis.gl.bufferData(this.gl.ARRAY_BUFFER, quadVertices, this.gl.STATIC_DRAW);\n\t\tthis.gl.viewport(0, 0, this.canvas.width, this.canvas.height);\n\t\tthis.gl.enableVertexAttribArray(aPosition);\n\t\tthis.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0);\n\t}\n\n\t// TODO: This breaks for `position: fixed; inset: 0` canvases.\n\tprivate resizeCanvas() {\n\t\tconst pixelRatio = window.devicePixelRatio || 1;\n\t\tconst width = this.canvas.clientWidth * pixelRatio;\n\t\tconst height = this.canvas.clientHeight * pixelRatio;\n\n\t\tconst computedStyle = getComputedStyle(this.canvas);\n\t\tconst hasExplicitWidth = computedStyle.width !== `${this.canvas.width}px` && computedStyle.width !== 'auto';\n\t\tconst hasExplicitHeight = computedStyle.height !== `${this.canvas.height}px` && computedStyle.height !== 'auto';\n\t\tif (!hasExplicitWidth || !hasExplicitHeight) {\n\t\t\tthis.canvas.style.width = `${this.canvas.clientWidth}px`;\n\t\t\tthis.canvas.style.height = `${this.canvas.clientHeight}px`;\n\t\t}\n\n\t\tif (this.canvas.width !== width || this.canvas.height !== height) {\n\t\t\tthis.canvas.width = width;\n\t\t\tthis.canvas.height = height;\n\t\t\tthis.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);\n\t\t\tif (this.uniforms.has('uResolution')) {\n\t\t\t\tthis.updateUniforms({ uResolution: [this.canvas.width, this.canvas.height] });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addEventListeners() {\n\t\tconst updateCursor = (x: number, y: number) => {\n\t\t\tif (!this.uniforms.has('uCursor')) return;\n\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\tthis.cursorPosition[0] = (x - rect.left) / rect.width;\n\t\t\tthis.cursorPosition[1] = 1 - (y - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\tthis.updateUniforms({\n\t\t\t\tuCursor: [this.cursorPosition[0], this.cursorPosition[1], this.scrollX, this.scrollY],\n\t\t\t});\n\t\t};\n\n\t\tconst updateClick = (isMouseDown: boolean, x?: number, y?: number) => {\n\t\t\tthis.isMouseDown = isMouseDown;\n\t\t\tif (isMouseDown) {\n\t\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPosition[0] = (xVal - rect.left) / rect.width;\n\t\t\t\tthis.clickPosition[1] = 1 - (yVal - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\t}\n\t\t\tthis.updateUniforms({\n\t\t\t\tuClick: [this.clickPosition[0], this.clickPosition[1], this.isMouseDown ? 1.0 : 0.0],\n\t\t\t});\n\t\t};\n\n\t\tthis.eventListeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isMouseDown = true;\n\t\t\t\t\tupdateClick(true, mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tupdateClick(false);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('wheel', event => {\n\t\t\tconst wheelEvent = event as WheelEvent;\n\t\t\tthis.scrollX += wheelEvent.deltaX * 0.01;\n\t\t\tthis.scrollY += wheelEvent.deltaY * 0.01;\n\t\t\tupdateCursor(wheelEvent.clientX, wheelEvent.clientY);\n\t\t});\n\n\t\tthis.eventListeners.set('touchmove', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouchDevice = true;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateClick(true, touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchend', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length === 0) {\n\t\t\t\tupdateClick(false);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tinitializeUniform(name: string, type: 'float' | 'int', value: number | number[]) {\n\t\tif (this.uniforms.has(name)) {\n\t\t\tthrow new Error(`Uniform '${name}' is already initialized.`);\n\t\t}\n\n\t\tif (type !== 'float' && type !== 'int') {\n\t\t\tthrow new Error(`Invalid uniform type: ${type}. Expected 'float' or 'int'.`);\n\t\t}\n\n\t\tconst location = this.gl.getUniformLocation(this.program!, name);\n\t\tif (!location) {\n\t\t\tconsole.debug(`Uniform ${name} not found in fragment shader. Skipping initialization.`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!Array.isArray(value)) {\n\t\t\tvalue = [value];\n\t\t}\n\t\tif (value.length < 1 || value.length > 4) {\n\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected a length between 1 and 4.`);\n\t\t}\n\n\t\tconst length = value.length as 1 | 2 | 3 | 4;\n\t\tthis.uniforms.set(name, { type, length, location });\n\t\tthis.updateUniforms({ [name]: value });\n\t}\n\n\tupdateUniforms(updates: Record<string, number | number[]>) {\n\t\tObject.entries(updates).forEach(([name, value]: [string, number | number[]]) => {\n\t\t\tif (!this.uniforms.has(name)) {\n\t\t\t\tthrow new Error(`Uniform '${name}' is not initialized.`);\n\t\t\t}\n\n\t\t\tconst uniform = this.uniforms.get(name)!;\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tvalue = [value];\n\t\t\t}\n\t\t\tif (value.length !== uniform.length) {\n\t\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected ${uniform.length}.`);\n\t\t\t}\n\t\t\t(this.gl as any)[`uniform${uniform.length}${uniform.type.charAt(0)}`](uniform.location, ...value);\n\t\t});\n\t}\n\n\tstep(time: number) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\n\t\tif (this.uniforms.has('uTime')) {\n\t\t\tthis.updateUniforms({ uTime: time });\n\t\t}\n\n\t\tif (this.uniforms.has('uFrame')) {\n\t\t\tthis.updateUniforms({ uFrame: this.frame });\n\t\t}\n\n\t\t++this.frame;\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\t}\n\n\tplay(callback?: (time: number, frame: number) => void) {\n\t\tconst loop = (time: number) => {\n\t\t\ttime /= 1000; // Convert from milliseconds to seconds.\n\t\t\tthis.step(time);\n\t\t\tif (callback) callback(time, this.frame);\n\t\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t\t};\n\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t}\n\n\tpause() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\t}\n\n\tsave(filename: string) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\n\t\tconst image = this.canvas.toDataURL();\n\t\tif (filename && !`${filename}`.toLowerCase().endsWith('.png')) {\n\t\t\tfilename = `${filename}.png`;\n\t\t}\n\t\tthis.downloadLink.download = filename || 'export.png';\n\t\tthis.downloadLink.href = image;\n\t\tthis.downloadLink.click();\n\t}\n\n\tinitializeTexture(name: string, source: HTMLImageElement | HTMLVideoElement) {\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow new Error(`Texture '${name}' is already initialized.`);\n\t\t}\n\n\t\tconst texture = this.gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow new Error('Failed to create texture');\n\t\t}\n\t\tconst unitIndex = this.textures.size;\n\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + unitIndex);\n\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n\t\t// Flip the texture vertically since vUv is flipped, and set up filters and wrapping.\n\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n\n\t\tthis.textures.set(name, { texture, unitIndex });\n\t\tthis.updateTextures({ [name]: source });\n\n\t\tconst uSampler = this.gl.getUniformLocation(this.program!, name);\n\t\tif (uSampler) {\n\t\t\tthis.gl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tupdateTextures(updates: Record<string, HTMLImageElement | HTMLVideoElement>) {\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tconst info = this.textures.get(name);\n\t\t\tif (!info) {\n\t\t\t\tthrow new Error(`Texture '${name}' is not initialized.`);\n\t\t\t}\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, info.texture);\n\t\t\tthis.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, source);\n\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\n\t\tthis.resizeObserver.unobserve(this.canvas);\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.removeEventListener(event, listener);\n\t\t});\n\n\t\tif (this.program) {\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.gl.deleteTexture(texture.texture);\n\t\t});\n\n\t\tif (this.buffer) {\n\t\t\tthis.gl.deleteBuffer(this.buffer);\n\t\t\tthis.buffer = null;\n\t\t}\n\n\t\tif (this.isInternalCanvas) {\n\t\t\tthis.canvas.remove();\n\t\t}\n\t}\n}\n\nexport default ShaderPad;\n"],"mappings":"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","names":["index_exports","__export","index_default","__toCommonJS","defaultVertexShaderSrc","ShaderPad","fragmentShaderSrc","canvas","vertexShaderSrc","vertexShader","fragmentShader","aPosition","type","source","shader","quadVertices","pixelRatio","width","height","computedStyle","hasExplicitWidth","hasExplicitHeight","updateCursor","x","y","rect","updateClick","isMouseDown","xVal","yVal","event","mouseEvent","wheelEvent","touchEvent","listener","name","value","location","length","updates","uniform","time","callback","loop","filename","image","texture","unitIndex","uSampler","info"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const defaultVertexShaderSrc = `\nattribute vec2 aPosition;\nvarying vec2 v_uv;\nvoid main() {\n v_uv = aPosition * 0.5 + 0.5;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}\n`;\n\ninterface Uniform {\n\ttype: 'float' | 'int';\n\tlength: 1 | 2 | 3 | 4;\n\tlocation: WebGLUniformLocation;\n}\n\ninterface Texture {\n\ttexture: WebGLTexture;\n\tunitIndex: number;\n}\n\nclass ShaderPad {\n\tprivate isInternalCanvas = false;\n\tprivate isTouchDevice = false;\n\tprivate canvas: HTMLCanvasElement;\n\tprivate gl: WebGLRenderingContext;\n\tprivate downloadLink: HTMLAnchorElement;\n\tprivate fragmentShaderSrc: string;\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string, Texture> = new Map();\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tprivate animationFrameId: number | null;\n\tprivate resizeObserver: ResizeObserver;\n\tprivate eventListeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate cursorPosition = [0.5, 0.5];\n\tprivate scrollX = 0;\n\tprivate scrollY = 0;\n\tprivate clickPosition = [0.5, 0.5];\n\tprivate isMouseDown = false;\n\n\tconstructor(fragmentShaderSrc: string, canvas: HTMLCanvasElement | null = null) {\n\t\tthis.canvas = canvas || document.createElement('canvas');\n\t\tif (!canvas) {\n\t\t\tthis.isInternalCanvas = true;\n\t\t\tdocument.body.appendChild(this.canvas);\n\t\t\tthis.canvas.style.position = 'fixed';\n\t\t\tthis.canvas.style.inset = '0';\n\t\t\tthis.canvas.style.height = '100dvh';\n\t\t\tthis.canvas.style.width = '100dvw';\n\t\t}\n\t\tthis.gl = this.canvas.getContext('webgl')!;\n\t\tthis.downloadLink = document.createElement('a');\n\t\tthis.fragmentShaderSrc = fragmentShaderSrc;\n\t\tthis.animationFrameId = null;\n\t\tthis.resizeObserver = new ResizeObserver(() => this.resizeCanvas());\n\t\tthis.resizeObserver.observe(this.canvas);\n\t\tthis.init();\n\t\tthis.addEventListeners();\n\t}\n\n\tprivate init() {\n\t\tconst vertexShaderSrc = defaultVertexShaderSrc;\n\n\t\tthis.program = this.gl.createProgram();\n\t\tif (!this.program) {\n\t\t\tthrow new Error('Failed to create WebGL program');\n\t\t}\n\t\tconst vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexShaderSrc);\n\t\tconst fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, this.fragmentShaderSrc);\n\n\t\tthis.gl.attachShader(this.program, vertexShader);\n\t\tthis.gl.attachShader(this.program, fragmentShader);\n\t\tthis.gl.linkProgram(this.program);\n\t\tthis.gl.deleteShader(vertexShader);\n\t\tthis.gl.deleteShader(fragmentShader);\n\n\t\tif (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {\n\t\t\tconsole.error('Program link error:', this.gl.getProgramInfoLog(this.program));\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t\tthrow new Error('Failed to link WebGL program');\n\t\t}\n\n\t\tconst aPosition = this.gl.getAttribLocation(this.program, 'aPosition');\n\t\tthis.setupBuffer(aPosition);\n\t\tthis.resizeCanvas();\n\n\t\tthis.gl.useProgram(this.program);\n\n\t\tthis.initializeUniform('u_resolution', 'float', [this.canvas.width, this.canvas.height]);\n\t\tthis.initializeUniform('u_cursor', 'float', [...this.cursorPosition, this.scrollX, this.scrollY]); // [cursorX, cursorY, scrollX, scrollY]\n\t\tthis.initializeUniform('u_click', 'float', [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0]); // [clickX, clickY, leftClick]\n\t\tthis.initializeUniform('u_time', 'float', 0);\n\t\tthis.initializeUniform('u_frame', 'int', 0);\n\t}\n\n\tprivate createShader(type: number, source: string): WebGLShader {\n\t\tconst shader = this.gl.createShader(type)!;\n\t\tthis.gl.shaderSource(shader, source);\n\t\tthis.gl.compileShader(shader);\n\t\tif (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n\t\t\tconsole.error('Shader compilation failed:', source);\n\t\t\tconsole.error(this.gl.getShaderInfoLog(shader));\n\t\t\tthis.gl.deleteShader(shader);\n\t\t\tthrow new Error('Shader compilation failed');\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate setupBuffer(aPosition: number) {\n\t\tconst quadVertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n\n\t\tthis.buffer = this.gl.createBuffer();\n\t\tthis.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);\n\t\tthis.gl.bufferData(this.gl.ARRAY_BUFFER, quadVertices, this.gl.STATIC_DRAW);\n\t\tthis.gl.viewport(0, 0, this.canvas.width, this.canvas.height);\n\t\tthis.gl.enableVertexAttribArray(aPosition);\n\t\tthis.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0);\n\t}\n\n\t// TODO: This breaks for `position: fixed; inset: 0` canvases.\n\tprivate resizeCanvas() {\n\t\tconst pixelRatio = window.devicePixelRatio || 1;\n\t\tconst width = this.canvas.clientWidth * pixelRatio;\n\t\tconst height = this.canvas.clientHeight * pixelRatio;\n\n\t\tconst computedStyle = getComputedStyle(this.canvas);\n\t\tconst hasExplicitWidth = computedStyle.width !== `${this.canvas.width}px` && computedStyle.width !== 'auto';\n\t\tconst hasExplicitHeight = computedStyle.height !== `${this.canvas.height}px` && computedStyle.height !== 'auto';\n\t\tif (!hasExplicitWidth || !hasExplicitHeight) {\n\t\t\tthis.canvas.style.width = `${this.canvas.clientWidth}px`;\n\t\t\tthis.canvas.style.height = `${this.canvas.clientHeight}px`;\n\t\t}\n\n\t\tif (this.canvas.width !== width || this.canvas.height !== height) {\n\t\t\tthis.canvas.width = width;\n\t\t\tthis.canvas.height = height;\n\t\t\tthis.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);\n\t\t\tif (this.uniforms.has('u_resolution')) {\n\t\t\t\tthis.updateUniforms({ u_resolution: [this.canvas.width, this.canvas.height] });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addEventListeners() {\n\t\tconst updateCursor = (x: number, y: number) => {\n\t\t\tif (!this.uniforms.has('u_cursor')) return;\n\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\tthis.cursorPosition[0] = (x - rect.left) / rect.width;\n\t\t\tthis.cursorPosition[1] = 1 - (y - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\tthis.updateUniforms({\n\t\t\t\tu_cursor: [this.cursorPosition[0], this.cursorPosition[1], this.scrollX, this.scrollY],\n\t\t\t});\n\t\t};\n\n\t\tconst updateClick = (isMouseDown: boolean, x?: number, y?: number) => {\n\t\t\tthis.isMouseDown = isMouseDown;\n\t\t\tif (isMouseDown) {\n\t\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPosition[0] = (xVal - rect.left) / rect.width;\n\t\t\t\tthis.clickPosition[1] = 1 - (yVal - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\t}\n\t\t\tthis.updateUniforms({\n\t\t\t\tu_click: [this.clickPosition[0], this.clickPosition[1], this.isMouseDown ? 1.0 : 0.0],\n\t\t\t});\n\t\t};\n\n\t\tthis.eventListeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isMouseDown = true;\n\t\t\t\t\tupdateClick(true, mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tupdateClick(false);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('wheel', event => {\n\t\t\tconst wheelEvent = event as WheelEvent;\n\t\t\tthis.scrollX += wheelEvent.deltaX * 0.01;\n\t\t\tthis.scrollY += wheelEvent.deltaY * 0.01;\n\t\t\tupdateCursor(wheelEvent.clientX, wheelEvent.clientY);\n\t\t});\n\n\t\tthis.eventListeners.set('touchmove', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouchDevice = true;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateClick(true, touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchend', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length === 0) {\n\t\t\t\tupdateClick(false);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tinitializeUniform(name: string, type: 'float' | 'int', value: number | number[]) {\n\t\tif (this.uniforms.has(name)) {\n\t\t\tthrow new Error(`Uniform '${name}' is already initialized.`);\n\t\t}\n\n\t\tif (type !== 'float' && type !== 'int') {\n\t\t\tthrow new Error(`Invalid uniform type: ${type}. Expected 'float' or 'int'.`);\n\t\t}\n\n\t\tconst location = this.gl.getUniformLocation(this.program!, name);\n\t\tif (!location) {\n\t\t\tconsole.debug(`Uniform ${name} not found in fragment shader. Skipping initialization.`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!Array.isArray(value)) {\n\t\t\tvalue = [value];\n\t\t}\n\t\tif (value.length < 1 || value.length > 4) {\n\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected a length between 1 and 4.`);\n\t\t}\n\n\t\tconst length = value.length as 1 | 2 | 3 | 4;\n\t\tthis.uniforms.set(name, { type, length, location });\n\t\tthis.updateUniforms({ [name]: value });\n\t}\n\n\tupdateUniforms(updates: Record<string, number | number[]>) {\n\t\tObject.entries(updates).forEach(([name, value]: [string, number | number[]]) => {\n\t\t\tif (!this.uniforms.has(name)) {\n\t\t\t\tthrow new Error(`Uniform '${name}' is not initialized.`);\n\t\t\t}\n\n\t\t\tconst uniform = this.uniforms.get(name)!;\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tvalue = [value];\n\t\t\t}\n\t\t\tif (value.length !== uniform.length) {\n\t\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected ${uniform.length}.`);\n\t\t\t}\n\t\t\t(this.gl as any)[`uniform${uniform.length}${uniform.type.charAt(0)}`](uniform.location, ...value);\n\t\t});\n\t}\n\n\tstep(time: number) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\n\t\tif (this.uniforms.has('u_time')) {\n\t\t\tthis.updateUniforms({ u_time: time });\n\t\t}\n\n\t\tif (this.uniforms.has('u_frame')) {\n\t\t\tthis.updateUniforms({ u_frame: this.frame });\n\t\t}\n\n\t\t++this.frame;\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\t}\n\n\tplay(callback?: (time: number, frame: number) => void) {\n\t\tconst loop = (time: number) => {\n\t\t\ttime /= 1000; // Convert from milliseconds to seconds.\n\t\t\tthis.step(time);\n\t\t\tif (callback) callback(time, this.frame);\n\t\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t\t};\n\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t}\n\n\tpause() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\t}\n\n\tsave(filename: string) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\n\t\tconst image = this.canvas.toDataURL();\n\t\tif (filename && !`${filename}`.toLowerCase().endsWith('.png')) {\n\t\t\tfilename = `${filename}.png`;\n\t\t}\n\t\tthis.downloadLink.download = filename || 'export.png';\n\t\tthis.downloadLink.href = image;\n\t\tthis.downloadLink.click();\n\t}\n\n\tinitializeTexture(name: string, source: HTMLImageElement | HTMLVideoElement) {\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow new Error(`Texture '${name}' is already initialized.`);\n\t\t}\n\n\t\tconst texture = this.gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow new Error('Failed to create texture');\n\t\t}\n\t\tconst unitIndex = this.textures.size;\n\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + unitIndex);\n\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n\t\t// Flip the texture vertically since v_uv is flipped, and set up filters and wrapping.\n\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n\n\t\tthis.textures.set(name, { texture, unitIndex });\n\t\tthis.updateTextures({ [name]: source });\n\n\t\tconst uSampler = this.gl.getUniformLocation(this.program!, name);\n\t\tif (uSampler) {\n\t\t\tthis.gl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tupdateTextures(updates: Record<string, HTMLImageElement | HTMLVideoElement>) {\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tconst info = this.textures.get(name);\n\t\t\tif (!info) {\n\t\t\t\tthrow new Error(`Texture '${name}' is not initialized.`);\n\t\t\t}\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, info.texture);\n\t\t\tthis.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, source);\n\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\n\t\tthis.resizeObserver.unobserve(this.canvas);\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.removeEventListener(event, listener);\n\t\t});\n\n\t\tif (this.program) {\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.gl.deleteTexture(texture.texture);\n\t\t});\n\n\t\tif (this.buffer) {\n\t\t\tthis.gl.deleteBuffer(this.buffer);\n\t\t\tthis.buffer = null;\n\t\t}\n\n\t\tif (this.isInternalCanvas) {\n\t\t\tthis.canvas.remove();\n\t\t}\n\t}\n}\n\nexport default ShaderPad;\n"],"mappings":"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","names":["index_exports","__export","index_default","__toCommonJS","defaultVertexShaderSrc","ShaderPad","fragmentShaderSrc","canvas","vertexShaderSrc","vertexShader","fragmentShader","aPosition","type","source","shader","quadVertices","pixelRatio","width","height","computedStyle","hasExplicitWidth","hasExplicitHeight","updateCursor","x","y","rect","updateClick","isMouseDown","xVal","yVal","event","mouseEvent","wheelEvent","touchEvent","listener","name","value","location","length","updates","uniform","time","callback","loop","filename","image","texture","unitIndex","uSampler","info"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var l=`
|
|
2
2
|
attribute vec2 aPosition;
|
|
3
|
-
varying vec2
|
|
3
|
+
varying vec2 v_uv;
|
|
4
4
|
void main() {
|
|
5
|
-
|
|
5
|
+
v_uv = aPosition * 0.5 + 0.5;
|
|
6
6
|
gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
7
7
|
}
|
|
8
|
-
`,a=class{constructor(e,s=null){this.isInternalCanvas=!1;this.isTouchDevice=!1;this.uniforms=new Map;this.textures=new Map;this.buffer=null;this.program=null;this.eventListeners=new Map;this.frame=0;this.cursorPosition=[.5,.5];this.scrollX=0;this.scrollY=0;this.clickPosition=[.5,.5];this.isMouseDown=!1;this.canvas=s||document.createElement("canvas"),s||(this.isInternalCanvas=!0,document.body.appendChild(this.canvas),this.canvas.style.position="fixed",this.canvas.style.inset="0",this.canvas.style.height="100dvh",this.canvas.style.width="100dvw"),this.gl=this.canvas.getContext("webgl"),this.downloadLink=document.createElement("a"),this.fragmentShaderSrc=e,this.animationFrameId=null,this.resizeObserver=new ResizeObserver(()=>this.resizeCanvas()),this.resizeObserver.observe(this.canvas),this.init(),this.addEventListeners()}init(){let e=l;if(this.program=this.gl.createProgram(),!this.program)throw new Error("Failed to create WebGL program");let s=this.createShader(this.gl.VERTEX_SHADER,e),t=this.createShader(this.gl.FRAGMENT_SHADER,this.fragmentShaderSrc);if(this.gl.attachShader(this.program,s),this.gl.attachShader(this.program,t),this.gl.linkProgram(this.program),this.gl.deleteShader(s),this.gl.deleteShader(t),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw console.error("Program link error:",this.gl.getProgramInfoLog(this.program)),this.gl.deleteProgram(this.program),new Error("Failed to link WebGL program");let i=this.gl.getAttribLocation(this.program,"aPosition");this.setupBuffer(i),this.resizeCanvas(),this.gl.useProgram(this.program),this.initializeUniform("
|
|
8
|
+
`,a=class{constructor(e,s=null){this.isInternalCanvas=!1;this.isTouchDevice=!1;this.uniforms=new Map;this.textures=new Map;this.buffer=null;this.program=null;this.eventListeners=new Map;this.frame=0;this.cursorPosition=[.5,.5];this.scrollX=0;this.scrollY=0;this.clickPosition=[.5,.5];this.isMouseDown=!1;this.canvas=s||document.createElement("canvas"),s||(this.isInternalCanvas=!0,document.body.appendChild(this.canvas),this.canvas.style.position="fixed",this.canvas.style.inset="0",this.canvas.style.height="100dvh",this.canvas.style.width="100dvw"),this.gl=this.canvas.getContext("webgl"),this.downloadLink=document.createElement("a"),this.fragmentShaderSrc=e,this.animationFrameId=null,this.resizeObserver=new ResizeObserver(()=>this.resizeCanvas()),this.resizeObserver.observe(this.canvas),this.init(),this.addEventListeners()}init(){let e=l;if(this.program=this.gl.createProgram(),!this.program)throw new Error("Failed to create WebGL program");let s=this.createShader(this.gl.VERTEX_SHADER,e),t=this.createShader(this.gl.FRAGMENT_SHADER,this.fragmentShaderSrc);if(this.gl.attachShader(this.program,s),this.gl.attachShader(this.program,t),this.gl.linkProgram(this.program),this.gl.deleteShader(s),this.gl.deleteShader(t),!this.gl.getProgramParameter(this.program,this.gl.LINK_STATUS))throw console.error("Program link error:",this.gl.getProgramInfoLog(this.program)),this.gl.deleteProgram(this.program),new Error("Failed to link WebGL program");let i=this.gl.getAttribLocation(this.program,"aPosition");this.setupBuffer(i),this.resizeCanvas(),this.gl.useProgram(this.program),this.initializeUniform("u_resolution","float",[this.canvas.width,this.canvas.height]),this.initializeUniform("u_cursor","float",[...this.cursorPosition,this.scrollX,this.scrollY]),this.initializeUniform("u_click","float",[...this.clickPosition,this.isMouseDown?1:0]),this.initializeUniform("u_time","float",0),this.initializeUniform("u_frame","int",0)}createShader(e,s){let t=this.gl.createShader(e);if(this.gl.shaderSource(t,s),this.gl.compileShader(t),!this.gl.getShaderParameter(t,this.gl.COMPILE_STATUS))throw console.error("Shader compilation failed:",s),console.error(this.gl.getShaderInfoLog(t)),this.gl.deleteShader(t),new Error("Shader compilation failed");return t}setupBuffer(e){let s=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]);this.buffer=this.gl.createBuffer(),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.buffer),this.gl.bufferData(this.gl.ARRAY_BUFFER,s,this.gl.STATIC_DRAW),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.enableVertexAttribArray(e),this.gl.vertexAttribPointer(e,2,this.gl.FLOAT,!1,0,0)}resizeCanvas(){let e=window.devicePixelRatio||1,s=this.canvas.clientWidth*e,t=this.canvas.clientHeight*e,i=getComputedStyle(this.canvas),r=i.width!==`${this.canvas.width}px`&&i.width!=="auto",n=i.height!==`${this.canvas.height}px`&&i.height!=="auto";(!r||!n)&&(this.canvas.style.width=`${this.canvas.clientWidth}px`,this.canvas.style.height=`${this.canvas.clientHeight}px`),(this.canvas.width!==s||this.canvas.height!==t)&&(this.canvas.width=s,this.canvas.height=t,this.gl.viewport(0,0,this.gl.drawingBufferWidth,this.gl.drawingBufferHeight),this.uniforms.has("u_resolution")&&this.updateUniforms({u_resolution:[this.canvas.width,this.canvas.height]}))}addEventListeners(){let e=(t,i)=>{if(!this.uniforms.has("u_cursor"))return;let r=this.canvas.getBoundingClientRect();this.cursorPosition[0]=(t-r.left)/r.width,this.cursorPosition[1]=1-(i-r.top)/r.height,this.updateUniforms({u_cursor:[this.cursorPosition[0],this.cursorPosition[1],this.scrollX,this.scrollY]})},s=(t,i,r)=>{if(this.isMouseDown=t,t){let n=this.canvas.getBoundingClientRect(),h=i,o=r;this.clickPosition[0]=(h-n.left)/n.width,this.clickPosition[1]=1-(o-n.top)/n.height}this.updateUniforms({u_click:[this.clickPosition[0],this.clickPosition[1],this.isMouseDown?1:0]})};this.eventListeners.set("mousemove",t=>{let i=t;this.isTouchDevice||e(i.clientX,i.clientY)}),this.eventListeners.set("mousedown",t=>{let i=t;this.isTouchDevice||i.button===0&&(this.isMouseDown=!0,s(!0,i.clientX,i.clientY))}),this.eventListeners.set("mouseup",t=>{let i=t;this.isTouchDevice||i.button===0&&s(!1)}),this.eventListeners.set("wheel",t=>{let i=t;this.scrollX+=i.deltaX*.01,this.scrollY+=i.deltaY*.01,e(i.clientX,i.clientY)}),this.eventListeners.set("touchmove",t=>{let i=t;i.touches.length>0&&e(i.touches[0].clientX,i.touches[0].clientY)}),this.eventListeners.set("touchstart",t=>{let i=t;this.isTouchDevice=!0,i.touches.length>0&&(s(!0,i.touches[0].clientX,i.touches[0].clientY),e(i.touches[0].clientX,i.touches[0].clientY))}),this.eventListeners.set("touchend",t=>{t.touches.length===0&&s(!1)}),this.eventListeners.forEach((t,i)=>{this.canvas.addEventListener(i,t)})}initializeUniform(e,s,t){if(this.uniforms.has(e))throw new Error(`Uniform '${e}' is already initialized.`);if(s!=="float"&&s!=="int")throw new Error(`Invalid uniform type: ${s}. Expected 'float' or 'int'.`);let i=this.gl.getUniformLocation(this.program,e);if(!i){console.debug(`Uniform ${e} not found in fragment shader. Skipping initialization.`);return}if(Array.isArray(t)||(t=[t]),t.length<1||t.length>4)throw new Error(`Invalid uniform value length: ${t.length}. Expected a length between 1 and 4.`);let r=t.length;this.uniforms.set(e,{type:s,length:r,location:i}),this.updateUniforms({[e]:t})}updateUniforms(e){Object.entries(e).forEach(([s,t])=>{if(!this.uniforms.has(s))throw new Error(`Uniform '${s}' is not initialized.`);let i=this.uniforms.get(s);if(Array.isArray(t)||(t=[t]),t.length!==i.length)throw new Error(`Invalid uniform value length: ${t.length}. Expected ${i.length}.`);this.gl[`uniform${i.length}${i.type.charAt(0)}`](i.location,...t)})}step(e){this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.uniforms.has("u_time")&&this.updateUniforms({u_time:e}),this.uniforms.has("u_frame")&&this.updateUniforms({u_frame:this.frame}),++this.frame,this.gl.drawArrays(this.gl.TRIANGLES,0,6)}play(e){let s=t=>{t/=1e3,this.step(t),e&&e(t,this.frame),this.animationFrameId=requestAnimationFrame(s)};this.animationFrameId=requestAnimationFrame(s)}pause(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}save(e){this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.drawArrays(this.gl.TRIANGLES,0,6);let s=this.canvas.toDataURL();e&&!`${e}`.toLowerCase().endsWith(".png")&&(e=`${e}.png`),this.downloadLink.download=e||"export.png",this.downloadLink.href=s,this.downloadLink.click()}initializeTexture(e,s){if(this.textures.has(e))throw new Error(`Texture '${e}' is already initialized.`);let t=this.gl.createTexture();if(!t)throw new Error("Failed to create texture");let i=this.textures.size;this.gl.activeTexture(this.gl.TEXTURE0+i),this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,!0),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.textures.set(e,{texture:t,unitIndex:i}),this.updateTextures({[e]:s});let r=this.gl.getUniformLocation(this.program,e);r&&this.gl.uniform1i(r,i)}updateTextures(e){Object.entries(e).forEach(([s,t])=>{let i=this.textures.get(s);if(!i)throw new Error(`Texture '${s}' is not initialized.`);this.gl.activeTexture(this.gl.TEXTURE0+i.unitIndex),this.gl.bindTexture(this.gl.TEXTURE_2D,i.texture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,t)})}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.resizeObserver.unobserve(this.canvas),this.eventListeners.forEach((e,s)=>{this.canvas.removeEventListener(s,e)}),this.program&&this.gl.deleteProgram(this.program),this.textures.forEach(e=>{this.gl.deleteTexture(e.texture)}),this.buffer&&(this.gl.deleteBuffer(this.buffer),this.buffer=null),this.isInternalCanvas&&this.canvas.remove()}},g=a;export{g as default};
|
|
9
9
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const defaultVertexShaderSrc = `\nattribute vec2 aPosition;\nvarying vec2 vUv;\nvoid main() {\n vUv = aPosition * 0.5 + 0.5;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}\n`;\n\ninterface Uniform {\n\ttype: 'float' | 'int';\n\tlength: 1 | 2 | 3 | 4;\n\tlocation: WebGLUniformLocation;\n}\n\ninterface Texture {\n\ttexture: WebGLTexture;\n\tunitIndex: number;\n}\n\nclass ShaderPad {\n\tprivate isInternalCanvas = false;\n\tprivate isTouchDevice = false;\n\tprivate canvas: HTMLCanvasElement;\n\tprivate gl: WebGLRenderingContext;\n\tprivate downloadLink: HTMLAnchorElement;\n\tprivate fragmentShaderSrc: string;\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string, Texture> = new Map();\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tprivate animationFrameId: number | null;\n\tprivate resizeObserver: ResizeObserver;\n\tprivate eventListeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate cursorPosition = [0.5, 0.5];\n\tprivate scrollX = 0;\n\tprivate scrollY = 0;\n\tprivate clickPosition = [0.5, 0.5];\n\tprivate isMouseDown = false;\n\n\tconstructor(fragmentShaderSrc: string, canvas: HTMLCanvasElement | null = null) {\n\t\tthis.canvas = canvas || document.createElement('canvas');\n\t\tif (!canvas) {\n\t\t\tthis.isInternalCanvas = true;\n\t\t\tdocument.body.appendChild(this.canvas);\n\t\t\tthis.canvas.style.position = 'fixed';\n\t\t\tthis.canvas.style.inset = '0';\n\t\t\tthis.canvas.style.height = '100dvh';\n\t\t\tthis.canvas.style.width = '100dvw';\n\t\t}\n\t\tthis.gl = this.canvas.getContext('webgl')!;\n\t\tthis.downloadLink = document.createElement('a');\n\t\tthis.fragmentShaderSrc = fragmentShaderSrc;\n\t\tthis.animationFrameId = null;\n\t\tthis.resizeObserver = new ResizeObserver(() => this.resizeCanvas());\n\t\tthis.resizeObserver.observe(this.canvas);\n\t\tthis.init();\n\t\tthis.addEventListeners();\n\t}\n\n\tprivate init() {\n\t\tconst vertexShaderSrc = defaultVertexShaderSrc;\n\n\t\tthis.program = this.gl.createProgram();\n\t\tif (!this.program) {\n\t\t\tthrow new Error('Failed to create WebGL program');\n\t\t}\n\t\tconst vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexShaderSrc);\n\t\tconst fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, this.fragmentShaderSrc);\n\n\t\tthis.gl.attachShader(this.program, vertexShader);\n\t\tthis.gl.attachShader(this.program, fragmentShader);\n\t\tthis.gl.linkProgram(this.program);\n\t\tthis.gl.deleteShader(vertexShader);\n\t\tthis.gl.deleteShader(fragmentShader);\n\n\t\tif (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {\n\t\t\tconsole.error('Program link error:', this.gl.getProgramInfoLog(this.program));\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t\tthrow new Error('Failed to link WebGL program');\n\t\t}\n\n\t\tconst aPosition = this.gl.getAttribLocation(this.program, 'aPosition');\n\t\tthis.setupBuffer(aPosition);\n\t\tthis.resizeCanvas();\n\n\t\tthis.gl.useProgram(this.program);\n\n\t\tthis.initializeUniform('uResolution', 'float', [this.canvas.width, this.canvas.height]);\n\t\tthis.initializeUniform('uCursor', 'float', [...this.cursorPosition, this.scrollX, this.scrollY]); // [cursorX, cursorY, scrollX, scrollY]\n\t\tthis.initializeUniform('uClick', 'float', [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0]); // [clickX, clickY, leftClick]\n\t\tthis.initializeUniform('uTime', 'float', 0);\n\t\tthis.initializeUniform('uFrame', 'int', 0);\n\t}\n\n\tprivate createShader(type: number, source: string): WebGLShader {\n\t\tconst shader = this.gl.createShader(type)!;\n\t\tthis.gl.shaderSource(shader, source);\n\t\tthis.gl.compileShader(shader);\n\t\tif (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n\t\t\tconsole.error('Shader compilation failed:', source);\n\t\t\tconsole.error(this.gl.getShaderInfoLog(shader));\n\t\t\tthis.gl.deleteShader(shader);\n\t\t\tthrow new Error('Shader compilation failed');\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate setupBuffer(aPosition: number) {\n\t\tconst quadVertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n\n\t\tthis.buffer = this.gl.createBuffer();\n\t\tthis.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);\n\t\tthis.gl.bufferData(this.gl.ARRAY_BUFFER, quadVertices, this.gl.STATIC_DRAW);\n\t\tthis.gl.viewport(0, 0, this.canvas.width, this.canvas.height);\n\t\tthis.gl.enableVertexAttribArray(aPosition);\n\t\tthis.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0);\n\t}\n\n\t// TODO: This breaks for `position: fixed; inset: 0` canvases.\n\tprivate resizeCanvas() {\n\t\tconst pixelRatio = window.devicePixelRatio || 1;\n\t\tconst width = this.canvas.clientWidth * pixelRatio;\n\t\tconst height = this.canvas.clientHeight * pixelRatio;\n\n\t\tconst computedStyle = getComputedStyle(this.canvas);\n\t\tconst hasExplicitWidth = computedStyle.width !== `${this.canvas.width}px` && computedStyle.width !== 'auto';\n\t\tconst hasExplicitHeight = computedStyle.height !== `${this.canvas.height}px` && computedStyle.height !== 'auto';\n\t\tif (!hasExplicitWidth || !hasExplicitHeight) {\n\t\t\tthis.canvas.style.width = `${this.canvas.clientWidth}px`;\n\t\t\tthis.canvas.style.height = `${this.canvas.clientHeight}px`;\n\t\t}\n\n\t\tif (this.canvas.width !== width || this.canvas.height !== height) {\n\t\t\tthis.canvas.width = width;\n\t\t\tthis.canvas.height = height;\n\t\t\tthis.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);\n\t\t\tif (this.uniforms.has('uResolution')) {\n\t\t\t\tthis.updateUniforms({ uResolution: [this.canvas.width, this.canvas.height] });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addEventListeners() {\n\t\tconst updateCursor = (x: number, y: number) => {\n\t\t\tif (!this.uniforms.has('uCursor')) return;\n\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\tthis.cursorPosition[0] = (x - rect.left) / rect.width;\n\t\t\tthis.cursorPosition[1] = 1 - (y - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\tthis.updateUniforms({\n\t\t\t\tuCursor: [this.cursorPosition[0], this.cursorPosition[1], this.scrollX, this.scrollY],\n\t\t\t});\n\t\t};\n\n\t\tconst updateClick = (isMouseDown: boolean, x?: number, y?: number) => {\n\t\t\tthis.isMouseDown = isMouseDown;\n\t\t\tif (isMouseDown) {\n\t\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPosition[0] = (xVal - rect.left) / rect.width;\n\t\t\t\tthis.clickPosition[1] = 1 - (yVal - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\t}\n\t\t\tthis.updateUniforms({\n\t\t\t\tuClick: [this.clickPosition[0], this.clickPosition[1], this.isMouseDown ? 1.0 : 0.0],\n\t\t\t});\n\t\t};\n\n\t\tthis.eventListeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isMouseDown = true;\n\t\t\t\t\tupdateClick(true, mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tupdateClick(false);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('wheel', event => {\n\t\t\tconst wheelEvent = event as WheelEvent;\n\t\t\tthis.scrollX += wheelEvent.deltaX * 0.01;\n\t\t\tthis.scrollY += wheelEvent.deltaY * 0.01;\n\t\t\tupdateCursor(wheelEvent.clientX, wheelEvent.clientY);\n\t\t});\n\n\t\tthis.eventListeners.set('touchmove', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouchDevice = true;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateClick(true, touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchend', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length === 0) {\n\t\t\t\tupdateClick(false);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tinitializeUniform(name: string, type: 'float' | 'int', value: number | number[]) {\n\t\tif (this.uniforms.has(name)) {\n\t\t\tthrow new Error(`Uniform '${name}' is already initialized.`);\n\t\t}\n\n\t\tif (type !== 'float' && type !== 'int') {\n\t\t\tthrow new Error(`Invalid uniform type: ${type}. Expected 'float' or 'int'.`);\n\t\t}\n\n\t\tconst location = this.gl.getUniformLocation(this.program!, name);\n\t\tif (!location) {\n\t\t\tconsole.debug(`Uniform ${name} not found in fragment shader. Skipping initialization.`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!Array.isArray(value)) {\n\t\t\tvalue = [value];\n\t\t}\n\t\tif (value.length < 1 || value.length > 4) {\n\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected a length between 1 and 4.`);\n\t\t}\n\n\t\tconst length = value.length as 1 | 2 | 3 | 4;\n\t\tthis.uniforms.set(name, { type, length, location });\n\t\tthis.updateUniforms({ [name]: value });\n\t}\n\n\tupdateUniforms(updates: Record<string, number | number[]>) {\n\t\tObject.entries(updates).forEach(([name, value]: [string, number | number[]]) => {\n\t\t\tif (!this.uniforms.has(name)) {\n\t\t\t\tthrow new Error(`Uniform '${name}' is not initialized.`);\n\t\t\t}\n\n\t\t\tconst uniform = this.uniforms.get(name)!;\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tvalue = [value];\n\t\t\t}\n\t\t\tif (value.length !== uniform.length) {\n\t\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected ${uniform.length}.`);\n\t\t\t}\n\t\t\t(this.gl as any)[`uniform${uniform.length}${uniform.type.charAt(0)}`](uniform.location, ...value);\n\t\t});\n\t}\n\n\tstep(time: number) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\n\t\tif (this.uniforms.has('uTime')) {\n\t\t\tthis.updateUniforms({ uTime: time });\n\t\t}\n\n\t\tif (this.uniforms.has('uFrame')) {\n\t\t\tthis.updateUniforms({ uFrame: this.frame });\n\t\t}\n\n\t\t++this.frame;\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\t}\n\n\tplay(callback?: (time: number, frame: number) => void) {\n\t\tconst loop = (time: number) => {\n\t\t\ttime /= 1000; // Convert from milliseconds to seconds.\n\t\t\tthis.step(time);\n\t\t\tif (callback) callback(time, this.frame);\n\t\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t\t};\n\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t}\n\n\tpause() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\t}\n\n\tsave(filename: string) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\n\t\tconst image = this.canvas.toDataURL();\n\t\tif (filename && !`${filename}`.toLowerCase().endsWith('.png')) {\n\t\t\tfilename = `${filename}.png`;\n\t\t}\n\t\tthis.downloadLink.download = filename || 'export.png';\n\t\tthis.downloadLink.href = image;\n\t\tthis.downloadLink.click();\n\t}\n\n\tinitializeTexture(name: string, source: HTMLImageElement | HTMLVideoElement) {\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow new Error(`Texture '${name}' is already initialized.`);\n\t\t}\n\n\t\tconst texture = this.gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow new Error('Failed to create texture');\n\t\t}\n\t\tconst unitIndex = this.textures.size;\n\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + unitIndex);\n\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n\t\t// Flip the texture vertically since vUv is flipped, and set up filters and wrapping.\n\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n\n\t\tthis.textures.set(name, { texture, unitIndex });\n\t\tthis.updateTextures({ [name]: source });\n\n\t\tconst uSampler = this.gl.getUniformLocation(this.program!, name);\n\t\tif (uSampler) {\n\t\t\tthis.gl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tupdateTextures(updates: Record<string, HTMLImageElement | HTMLVideoElement>) {\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tconst info = this.textures.get(name);\n\t\t\tif (!info) {\n\t\t\t\tthrow new Error(`Texture '${name}' is not initialized.`);\n\t\t\t}\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, info.texture);\n\t\t\tthis.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, source);\n\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\n\t\tthis.resizeObserver.unobserve(this.canvas);\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.removeEventListener(event, listener);\n\t\t});\n\n\t\tif (this.program) {\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.gl.deleteTexture(texture.texture);\n\t\t});\n\n\t\tif (this.buffer) {\n\t\t\tthis.gl.deleteBuffer(this.buffer);\n\t\t\tthis.buffer = null;\n\t\t}\n\n\t\tif (this.isInternalCanvas) {\n\t\t\tthis.canvas.remove();\n\t\t}\n\t}\n}\n\nexport default ShaderPad;\n"],"mappings":"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","names":["defaultVertexShaderSrc","ShaderPad","fragmentShaderSrc","canvas","vertexShaderSrc","vertexShader","fragmentShader","aPosition","type","source","shader","quadVertices","pixelRatio","width","height","computedStyle","hasExplicitWidth","hasExplicitHeight","updateCursor","x","y","rect","updateClick","isMouseDown","xVal","yVal","event","mouseEvent","wheelEvent","touchEvent","listener","name","value","location","length","updates","uniform","time","callback","loop","filename","image","texture","unitIndex","uSampler","info","index_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const defaultVertexShaderSrc = `\nattribute vec2 aPosition;\nvarying vec2 v_uv;\nvoid main() {\n v_uv = aPosition * 0.5 + 0.5;\n gl_Position = vec4(aPosition, 0.0, 1.0);\n}\n`;\n\ninterface Uniform {\n\ttype: 'float' | 'int';\n\tlength: 1 | 2 | 3 | 4;\n\tlocation: WebGLUniformLocation;\n}\n\ninterface Texture {\n\ttexture: WebGLTexture;\n\tunitIndex: number;\n}\n\nclass ShaderPad {\n\tprivate isInternalCanvas = false;\n\tprivate isTouchDevice = false;\n\tprivate canvas: HTMLCanvasElement;\n\tprivate gl: WebGLRenderingContext;\n\tprivate downloadLink: HTMLAnchorElement;\n\tprivate fragmentShaderSrc: string;\n\tprivate uniforms: Map<string, Uniform> = new Map();\n\tprivate textures: Map<string, Texture> = new Map();\n\tprivate buffer: WebGLBuffer | null = null;\n\tprivate program: WebGLProgram | null = null;\n\tprivate animationFrameId: number | null;\n\tprivate resizeObserver: ResizeObserver;\n\tprivate eventListeners: Map<string, EventListener> = new Map();\n\tprivate frame = 0;\n\tprivate cursorPosition = [0.5, 0.5];\n\tprivate scrollX = 0;\n\tprivate scrollY = 0;\n\tprivate clickPosition = [0.5, 0.5];\n\tprivate isMouseDown = false;\n\n\tconstructor(fragmentShaderSrc: string, canvas: HTMLCanvasElement | null = null) {\n\t\tthis.canvas = canvas || document.createElement('canvas');\n\t\tif (!canvas) {\n\t\t\tthis.isInternalCanvas = true;\n\t\t\tdocument.body.appendChild(this.canvas);\n\t\t\tthis.canvas.style.position = 'fixed';\n\t\t\tthis.canvas.style.inset = '0';\n\t\t\tthis.canvas.style.height = '100dvh';\n\t\t\tthis.canvas.style.width = '100dvw';\n\t\t}\n\t\tthis.gl = this.canvas.getContext('webgl')!;\n\t\tthis.downloadLink = document.createElement('a');\n\t\tthis.fragmentShaderSrc = fragmentShaderSrc;\n\t\tthis.animationFrameId = null;\n\t\tthis.resizeObserver = new ResizeObserver(() => this.resizeCanvas());\n\t\tthis.resizeObserver.observe(this.canvas);\n\t\tthis.init();\n\t\tthis.addEventListeners();\n\t}\n\n\tprivate init() {\n\t\tconst vertexShaderSrc = defaultVertexShaderSrc;\n\n\t\tthis.program = this.gl.createProgram();\n\t\tif (!this.program) {\n\t\t\tthrow new Error('Failed to create WebGL program');\n\t\t}\n\t\tconst vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexShaderSrc);\n\t\tconst fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, this.fragmentShaderSrc);\n\n\t\tthis.gl.attachShader(this.program, vertexShader);\n\t\tthis.gl.attachShader(this.program, fragmentShader);\n\t\tthis.gl.linkProgram(this.program);\n\t\tthis.gl.deleteShader(vertexShader);\n\t\tthis.gl.deleteShader(fragmentShader);\n\n\t\tif (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {\n\t\t\tconsole.error('Program link error:', this.gl.getProgramInfoLog(this.program));\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t\tthrow new Error('Failed to link WebGL program');\n\t\t}\n\n\t\tconst aPosition = this.gl.getAttribLocation(this.program, 'aPosition');\n\t\tthis.setupBuffer(aPosition);\n\t\tthis.resizeCanvas();\n\n\t\tthis.gl.useProgram(this.program);\n\n\t\tthis.initializeUniform('u_resolution', 'float', [this.canvas.width, this.canvas.height]);\n\t\tthis.initializeUniform('u_cursor', 'float', [...this.cursorPosition, this.scrollX, this.scrollY]); // [cursorX, cursorY, scrollX, scrollY]\n\t\tthis.initializeUniform('u_click', 'float', [...this.clickPosition, this.isMouseDown ? 1.0 : 0.0]); // [clickX, clickY, leftClick]\n\t\tthis.initializeUniform('u_time', 'float', 0);\n\t\tthis.initializeUniform('u_frame', 'int', 0);\n\t}\n\n\tprivate createShader(type: number, source: string): WebGLShader {\n\t\tconst shader = this.gl.createShader(type)!;\n\t\tthis.gl.shaderSource(shader, source);\n\t\tthis.gl.compileShader(shader);\n\t\tif (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n\t\t\tconsole.error('Shader compilation failed:', source);\n\t\t\tconsole.error(this.gl.getShaderInfoLog(shader));\n\t\t\tthis.gl.deleteShader(shader);\n\t\t\tthrow new Error('Shader compilation failed');\n\t\t}\n\t\treturn shader;\n\t}\n\n\tprivate setupBuffer(aPosition: number) {\n\t\tconst quadVertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n\n\t\tthis.buffer = this.gl.createBuffer();\n\t\tthis.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);\n\t\tthis.gl.bufferData(this.gl.ARRAY_BUFFER, quadVertices, this.gl.STATIC_DRAW);\n\t\tthis.gl.viewport(0, 0, this.canvas.width, this.canvas.height);\n\t\tthis.gl.enableVertexAttribArray(aPosition);\n\t\tthis.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0);\n\t}\n\n\t// TODO: This breaks for `position: fixed; inset: 0` canvases.\n\tprivate resizeCanvas() {\n\t\tconst pixelRatio = window.devicePixelRatio || 1;\n\t\tconst width = this.canvas.clientWidth * pixelRatio;\n\t\tconst height = this.canvas.clientHeight * pixelRatio;\n\n\t\tconst computedStyle = getComputedStyle(this.canvas);\n\t\tconst hasExplicitWidth = computedStyle.width !== `${this.canvas.width}px` && computedStyle.width !== 'auto';\n\t\tconst hasExplicitHeight = computedStyle.height !== `${this.canvas.height}px` && computedStyle.height !== 'auto';\n\t\tif (!hasExplicitWidth || !hasExplicitHeight) {\n\t\t\tthis.canvas.style.width = `${this.canvas.clientWidth}px`;\n\t\t\tthis.canvas.style.height = `${this.canvas.clientHeight}px`;\n\t\t}\n\n\t\tif (this.canvas.width !== width || this.canvas.height !== height) {\n\t\t\tthis.canvas.width = width;\n\t\t\tthis.canvas.height = height;\n\t\t\tthis.gl.viewport(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight);\n\t\t\tif (this.uniforms.has('u_resolution')) {\n\t\t\t\tthis.updateUniforms({ u_resolution: [this.canvas.width, this.canvas.height] });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addEventListeners() {\n\t\tconst updateCursor = (x: number, y: number) => {\n\t\t\tif (!this.uniforms.has('u_cursor')) return;\n\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\tthis.cursorPosition[0] = (x - rect.left) / rect.width;\n\t\t\tthis.cursorPosition[1] = 1 - (y - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\tthis.updateUniforms({\n\t\t\t\tu_cursor: [this.cursorPosition[0], this.cursorPosition[1], this.scrollX, this.scrollY],\n\t\t\t});\n\t\t};\n\n\t\tconst updateClick = (isMouseDown: boolean, x?: number, y?: number) => {\n\t\t\tthis.isMouseDown = isMouseDown;\n\t\t\tif (isMouseDown) {\n\t\t\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\t\t\tconst xVal = x as number;\n\t\t\t\tconst yVal = y as number;\n\t\t\t\tthis.clickPosition[0] = (xVal - rect.left) / rect.width;\n\t\t\t\tthis.clickPosition[1] = 1 - (yVal - rect.top) / rect.height; // Flip Y for WebGL\n\t\t\t}\n\t\t\tthis.updateUniforms({\n\t\t\t\tu_click: [this.clickPosition[0], this.clickPosition[1], this.isMouseDown ? 1.0 : 0.0],\n\t\t\t});\n\t\t};\n\n\t\tthis.eventListeners.set('mousemove', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tupdateCursor(mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mousedown', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tthis.isMouseDown = true;\n\t\t\t\t\tupdateClick(true, mouseEvent.clientX, mouseEvent.clientY);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('mouseup', event => {\n\t\t\tconst mouseEvent = event as MouseEvent;\n\t\t\tif (!this.isTouchDevice) {\n\t\t\t\tif (mouseEvent.button === 0) {\n\t\t\t\t\tupdateClick(false);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('wheel', event => {\n\t\t\tconst wheelEvent = event as WheelEvent;\n\t\t\tthis.scrollX += wheelEvent.deltaX * 0.01;\n\t\t\tthis.scrollY += wheelEvent.deltaY * 0.01;\n\t\t\tupdateCursor(wheelEvent.clientX, wheelEvent.clientY);\n\t\t});\n\n\t\tthis.eventListeners.set('touchmove', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchstart', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tthis.isTouchDevice = true;\n\t\t\tif (touchEvent.touches.length > 0) {\n\t\t\t\tupdateClick(true, touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t\tupdateCursor(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.set('touchend', event => {\n\t\t\tconst touchEvent = event as TouchEvent;\n\t\t\tif (touchEvent.touches.length === 0) {\n\t\t\t\tupdateClick(false);\n\t\t\t}\n\t\t});\n\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.addEventListener(event, listener);\n\t\t});\n\t}\n\n\tinitializeUniform(name: string, type: 'float' | 'int', value: number | number[]) {\n\t\tif (this.uniforms.has(name)) {\n\t\t\tthrow new Error(`Uniform '${name}' is already initialized.`);\n\t\t}\n\n\t\tif (type !== 'float' && type !== 'int') {\n\t\t\tthrow new Error(`Invalid uniform type: ${type}. Expected 'float' or 'int'.`);\n\t\t}\n\n\t\tconst location = this.gl.getUniformLocation(this.program!, name);\n\t\tif (!location) {\n\t\t\tconsole.debug(`Uniform ${name} not found in fragment shader. Skipping initialization.`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!Array.isArray(value)) {\n\t\t\tvalue = [value];\n\t\t}\n\t\tif (value.length < 1 || value.length > 4) {\n\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected a length between 1 and 4.`);\n\t\t}\n\n\t\tconst length = value.length as 1 | 2 | 3 | 4;\n\t\tthis.uniforms.set(name, { type, length, location });\n\t\tthis.updateUniforms({ [name]: value });\n\t}\n\n\tupdateUniforms(updates: Record<string, number | number[]>) {\n\t\tObject.entries(updates).forEach(([name, value]: [string, number | number[]]) => {\n\t\t\tif (!this.uniforms.has(name)) {\n\t\t\t\tthrow new Error(`Uniform '${name}' is not initialized.`);\n\t\t\t}\n\n\t\t\tconst uniform = this.uniforms.get(name)!;\n\t\t\tif (!Array.isArray(value)) {\n\t\t\t\tvalue = [value];\n\t\t\t}\n\t\t\tif (value.length !== uniform.length) {\n\t\t\t\tthrow new Error(`Invalid uniform value length: ${value.length}. Expected ${uniform.length}.`);\n\t\t\t}\n\t\t\t(this.gl as any)[`uniform${uniform.length}${uniform.type.charAt(0)}`](uniform.location, ...value);\n\t\t});\n\t}\n\n\tstep(time: number) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\n\t\tif (this.uniforms.has('u_time')) {\n\t\t\tthis.updateUniforms({ u_time: time });\n\t\t}\n\n\t\tif (this.uniforms.has('u_frame')) {\n\t\t\tthis.updateUniforms({ u_frame: this.frame });\n\t\t}\n\n\t\t++this.frame;\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\t}\n\n\tplay(callback?: (time: number, frame: number) => void) {\n\t\tconst loop = (time: number) => {\n\t\t\ttime /= 1000; // Convert from milliseconds to seconds.\n\t\t\tthis.step(time);\n\t\t\tif (callback) callback(time, this.frame);\n\t\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t\t};\n\t\tthis.animationFrameId = requestAnimationFrame(loop);\n\t}\n\n\tpause() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\t}\n\n\tsave(filename: string) {\n\t\tthis.gl.clear(this.gl.COLOR_BUFFER_BIT);\n\t\tthis.gl.drawArrays(this.gl.TRIANGLES, 0, 6);\n\n\t\tconst image = this.canvas.toDataURL();\n\t\tif (filename && !`${filename}`.toLowerCase().endsWith('.png')) {\n\t\t\tfilename = `${filename}.png`;\n\t\t}\n\t\tthis.downloadLink.download = filename || 'export.png';\n\t\tthis.downloadLink.href = image;\n\t\tthis.downloadLink.click();\n\t}\n\n\tinitializeTexture(name: string, source: HTMLImageElement | HTMLVideoElement) {\n\t\tif (this.textures.has(name)) {\n\t\t\tthrow new Error(`Texture '${name}' is already initialized.`);\n\t\t}\n\n\t\tconst texture = this.gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow new Error('Failed to create texture');\n\t\t}\n\t\tconst unitIndex = this.textures.size;\n\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + unitIndex);\n\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n\t\t// Flip the texture vertically since v_uv is flipped, and set up filters and wrapping.\n\t\tthis.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n\t\tthis.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n\n\t\tthis.textures.set(name, { texture, unitIndex });\n\t\tthis.updateTextures({ [name]: source });\n\n\t\tconst uSampler = this.gl.getUniformLocation(this.program!, name);\n\t\tif (uSampler) {\n\t\t\tthis.gl.uniform1i(uSampler, unitIndex);\n\t\t}\n\t}\n\n\tupdateTextures(updates: Record<string, HTMLImageElement | HTMLVideoElement>) {\n\t\tObject.entries(updates).forEach(([name, source]) => {\n\t\t\tconst info = this.textures.get(name);\n\t\t\tif (!info) {\n\t\t\t\tthrow new Error(`Texture '${name}' is not initialized.`);\n\t\t\t}\n\t\t\tthis.gl.activeTexture(this.gl.TEXTURE0 + info.unitIndex);\n\t\t\tthis.gl.bindTexture(this.gl.TEXTURE_2D, info.texture);\n\t\t\tthis.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, source);\n\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this.animationFrameId) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\n\t\tthis.resizeObserver.unobserve(this.canvas);\n\t\tthis.eventListeners.forEach((listener, event) => {\n\t\t\tthis.canvas.removeEventListener(event, listener);\n\t\t});\n\n\t\tif (this.program) {\n\t\t\tthis.gl.deleteProgram(this.program);\n\t\t}\n\n\t\tthis.textures.forEach(texture => {\n\t\t\tthis.gl.deleteTexture(texture.texture);\n\t\t});\n\n\t\tif (this.buffer) {\n\t\t\tthis.gl.deleteBuffer(this.buffer);\n\t\t\tthis.buffer = null;\n\t\t}\n\n\t\tif (this.isInternalCanvas) {\n\t\t\tthis.canvas.remove();\n\t\t}\n\t}\n}\n\nexport default ShaderPad;\n"],"mappings":"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","names":["defaultVertexShaderSrc","ShaderPad","fragmentShaderSrc","canvas","vertexShaderSrc","vertexShader","fragmentShader","aPosition","type","source","shader","quadVertices","pixelRatio","width","height","computedStyle","hasExplicitWidth","hasExplicitHeight","updateCursor","x","y","rect","updateClick","isMouseDown","xVal","yVal","event","mouseEvent","wheelEvent","touchEvent","listener","name","value","location","length","updates","uniform","time","callback","loop","filename","image","texture","unitIndex","uSampler","info","index_default"]}
|