rapid-render 0.0.5 → 0.0.7

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
@@ -10,6 +10,7 @@ A highly efficient and lightweight WebGL renderer capable of rendering 10k sprit
10
10
  [demo](https://nightre.github.io/Rapid.js/demo/) ( [source code](./demo/index.js) )
11
11
 
12
12
  [matrix stack demo](https://nightre.github.io/Rapid.js/demo/matrix_stack.html) ( [source code](./demo/matrix_stack.js) )
13
+
13
14
  [custom shader demo](https://nightre.github.io/Rapid.js/demo/custom-shader.html) ( [source code](./demo/custom-shader.js) )
14
15
 
15
16
 
@@ -19,7 +20,9 @@ A highly efficient and lightweight WebGL renderer capable of rendering 10k sprit
19
20
  * Multi-texture support ( Batch rendering based on the GPU's maximum texture units )
20
21
  * Graphic
21
22
  * Matrix stack
22
- * Color
23
+ * Text
24
+ * Line
25
+ * custom Shader
23
26
 
24
27
  # Install
25
28
 
@@ -71,9 +74,9 @@ rapid.matrixStack.scale(1)
71
74
  rapid.matrixStack.rotate(0)
72
75
 
73
76
  // texture offset color
74
- rapid.renderSprite(cat,0,0, color) // draw Sprite
77
+ rapid.renderSprite(cat, 0, 0, color) // draw Sprite
78
+ // or rapid.renderSprite(cat, 0, 0, { color })
75
79
  rapid.restore() // back to the previous saved state
76
-
77
80
  // draw graphic
78
81
  // vertices can have different colors
79
82
  rapid.startGraphicDraw()
@@ -97,8 +100,7 @@ View demo and watch detailed shader code [custom shader demo](https://nightre.gi
97
100
  const vertexShaderSource = `...`
98
101
  const fragmentShaderSource = `...`
99
102
 
100
- const customShader = new GLShader(rapid, vertexShaderSource, fragmentShaderSource, spriteAttributes)
101
- // If you want to create a custom shader for graphic, please use graphicAttributes
103
+ const customShader = new GLShader(rapid, vertexShaderSource, fragmentShaderSource)
102
104
  rapid.startRender()
103
105
 
104
106
  rapid.renderSprite(plane, 100, 100, {
package/dist/index.d.ts CHANGED
@@ -2,7 +2,8 @@ import { graphicAttributes } from "./regions/graphic_region";
2
2
  import { spriteAttributes } from "./regions/sprite_region";
3
3
  import Rapid from "./render";
4
4
  import GLShader from "./webgl/glshader";
5
- export { Rapid, GLShader, spriteAttributes, graphicAttributes, };
5
+ import { Text } from "./texture";
6
+ export { Text, Rapid, GLShader, spriteAttributes, graphicAttributes, };
6
7
  export * from "./math";
7
8
  export * from "./interface";
8
9
  export * from "./texture";
@@ -1,4 +1,4 @@
1
- import { Color } from "./math";
1
+ import { Color, Vec2 } from "./math";
2
2
  import GLShader from "./webgl/glshader";
3
3
  export type WebGLContext = WebGL2RenderingContext | WebGLRenderingContext;
4
4
  export interface IRapiadOptions {
@@ -21,5 +21,63 @@ export interface IRenderSpriteOptions {
21
21
  shader?: GLShader;
22
22
  uniforms?: UniformType;
23
23
  }
24
+ export interface ITextOptions {
25
+ /**
26
+ * The text string to be rendered.
27
+ */
28
+ text: string;
29
+ /**
30
+ * The font size for the text.
31
+ * Default is 16.
32
+ */
33
+ fontSize?: number;
34
+ /**
35
+ * The font family for the text.
36
+ * Default is 'Arial'.
37
+ */
38
+ fontFamily?: string;
39
+ /**
40
+ * The color of the text.
41
+ * Default is '#000000' (black).
42
+ */
43
+ color?: string;
44
+ /**
45
+ * The alignment of the text.
46
+ * Possible values: 'left', 'right', 'center', 'start', 'end'.
47
+ * Default is 'left'.
48
+ */
49
+ textAlign?: CanvasTextAlign;
50
+ /**
51
+ * The baseline of the text.
52
+ * Possible values: 'top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom'.
53
+ * Default is 'top'.
54
+ */
55
+ textBaseline?: CanvasTextBaseline;
56
+ /**
57
+ * Whether to apply antialiasing to the texture.
58
+ * Default is `false`.
59
+ */
60
+ antialias?: boolean;
61
+ }
62
+ export declare enum JoinTyps {
63
+ BEVEL = 0,
64
+ ROUND = 1,
65
+ MITER = 2
66
+ }
67
+ export declare enum CapTyps {
68
+ BUTT = 0,
69
+ ROUND = 1,
70
+ SQUARE = 2
71
+ }
72
+ export interface ILineOptions {
73
+ cap?: CapTyps;
74
+ join?: JoinTyps;
75
+ width?: number;
76
+ miterLimit?: number;
77
+ }
78
+ export interface IRenderLineOptions extends ILineOptions {
79
+ points: Vec2[];
80
+ color?: Color;
81
+ }
24
82
  export type UniformType = Record<string, number | Array<any>>;
25
83
  export type Images = ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | OffscreenCanvas;
package/dist/line.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { ILineOptions } from "./interface";
2
+ import { Vec2 } from "./math";
3
+ export declare const getStrokeGeometry: (points: Vec2[], attrs: ILineOptions) => Vec2[];
package/dist/math.d.ts CHANGED
@@ -80,7 +80,7 @@ export declare class MatrixStack extends DynamicArrayBuffer {
80
80
  * @param x - The amount to translate horizontally.
81
81
  * @param y - The amount to translate vertically.
82
82
  */
83
- translate(x: number, y: number): void;
83
+ translate(x: number | Vec2, y: number): void;
84
84
  /**
85
85
  * Rotates the current matrix by the specified angle.
86
86
  * @param angle - The angle, in radians, to rotate the matrix by.
@@ -91,8 +91,8 @@ export declare class MatrixStack extends DynamicArrayBuffer {
91
91
  * @param x - The amount to scale the matrix horizontally.
92
92
  * @param y - The amount to scale the matrix vertically. If not specified, x is used for both horizontal and vertical scaling.
93
93
  */
94
- scale(x: number, y?: number): void;
95
- apply(x: number, y: number): number[];
94
+ scale(x: number | Vec2, y: number): void;
95
+ apply(x: number | Vec2, y: number): Vec2 | number[];
96
96
  getInverse(): Float32Array;
97
97
  getTransform(): Float32Array;
98
98
  setTransform(array: Float32Array | number[]): void;
@@ -197,4 +197,19 @@ export declare class Color {
197
197
  */
198
198
  subtract(color: Color): Color;
199
199
  }
200
+ export declare class Vec2 {
201
+ x: number;
202
+ y: number;
203
+ constructor(x?: number, y?: number);
204
+ scalarMult(f: number): this;
205
+ perpendicular(): this;
206
+ invert(): this;
207
+ length(): number;
208
+ normalize(): this;
209
+ angle(): number;
210
+ static Angle(p0: Vec2, p1: Vec2): number;
211
+ static Add(p0: Vec2, p1: Vec2): Vec2;
212
+ static Sub(p1: Vec2, p0: Vec2): Vec2;
213
+ static Middle(p0: Vec2, p1: Vec2): Vec2;
214
+ }
200
215
  export {};
@@ -1 +1 @@
1
- var rapid=function(t){"use strict";const e=(t,e,r)=>{const i=t.createShader(r);if(!i)throw new Error("Unable to create webgl shader");t.shaderSource(i,e),t.compileShader(i);if(!t.getShaderParameter(i,t.COMPILE_STATUS)){const r=t.getShaderInfoLog(i);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+e)}return i};const r=5126;class i{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=t.BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new t(this.arraybuffer),t==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(e)}push(t){this.typedArray[this.usedElemNum++]=t}pushUint(t){this.uint32[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.typedArray.length}}class s extends i{constructor(t,e,r=t.ARRAY_BUFFER){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=r}push(t){super.push(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),t.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class a extends i{constructor(){super(Float32Array)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.push(e[t+0]),this.push(e[t+1]),this.push(e[t+2]),this.push(e[t+3]),this.push(e[t+4]),this.push(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(t,e){const r=this.usedElemNum-6,i=this.typedArray;i[r+4]=i[r+0]*t+i[r+2]*e+i[r+4],i[r+5]=i[r+1]*t+i[r+3]*e+i[r+5]}rotate(t){const e=this.usedElemNum-6,r=this.typedArray,i=Math.cos(t),s=Math.sin(t),a=r[e+0],n=r[e+1],h=r[e+2],o=r[e+3];r[e+0]=a*i-n*s,r[e+1]=a*s+n*i,r[e+2]=h*i-o*s,r[e+3]=h*s+o*i}scale(t,e=t){const r=this.usedElemNum-6,i=this.typedArray;i[r+0]=i[r+0]*t,i[r+1]=i[r+1]*t,i[r+2]=i[r+2]*e,i[r+3]=i[r+3]*e}apply(t,e){const r=this.usedElemNum-6,i=this.typedArray;return[i[r+0]*t+i[r+2]*e+i[r+4],i[r+1]*t+i[r+3]*e+i[r+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,r=e[t+0],i=e[t+1],s=e[t+2],a=e[t+3],n=e[t+4],h=e[t+5],o=r*a-i*s;return new Float32Array([a/o,-i/o,-s/o,r/o,(s*h-a*n)/o,(i*n-r*h)/o])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,r=this.typedArray;r[e+0]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}}class n extends s{constructor(t,e,r,i){super(t,Uint16Array,t.ELEMENT_ARRAY_BUFFER),this.setMaxSize(e*i);for(let t=0;t<i;t++)this.addObject(t*r);this.bindBuffer(),this.bufferData()}addObject(t){}}class h{constructor(t,e,r,i){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,r,i){this.r=t,this.g=e,this.b=r,this.a=i,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),i=parseInt(t.slice(4,6),16);let s=255;return t.length>=8&&(s=parseInt(t.slice(6,8),16)),new h(e,r,i,s)}add(t){return new h(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new h(Math.max(this.r-t.r,0),Math.max(this.g-t.g,0),Math.max(this.b-t.b,0),Math.max(this.a-t.a,0))}}class o{constructor(t,r,i,s){this.attributeLoc={},this.uniformLoc={};const a=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let r="";for(let t=0;t<e;t++)r+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,r+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",r)}return t}(i,t.maxTextureUnits);this.program=((t,r,i)=>{var s=t.createProgram(),a=e(t,r,35633),n=e(t,i,35632);if(!s)throw new Error("Unable to create program shader");return t.attachShader(s,a),t.attachShader(s,n),t.linkProgram(s),s})(t.gl,r,a),this.gl=t.gl,this.attribute=s,this.parseShader(r),this.parseShader(a)}setUniforms(t){const e=this.gl;for(const r in t){const i=t[r],s=this.getUniform(r);if("number"==typeof i)e.uniform1f(s,i);else if(Array.isArray(i))switch(i.length){case 1:Number.isInteger(i[0])?e.uniform1i(s,i[0]):e.uniform1f(s,i[0]);break;case 2:Number.isInteger(i[0])?e.uniform2iv(s,i):e.uniform2fv(s,i);break;case 3:Number.isInteger(i[0])?e.uniform3iv(s,i):e.uniform3fv(s,i);break;case 4:Number.isInteger(i[0])?e.uniform4iv(s,i):e.uniform4fv(s,i);break;case 9:e.uniformMatrix3fv(s,!1,i);break;case 16:e.uniformMatrix4fv(s,!1,i);break;default:console.error(`Unsupported uniform array length for ${r}:`,i.length)}else"boolean"==typeof i?e.uniform1i(s,i?1:0):console.error(`Unsupported uniform type for ${r}:`,typeof i)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const t of r){const r=t.split(" ")[2],i=e.getAttribLocation(this.program,r);-1!=i&&(this.attributeLoc[r]=i)}const i=t.match(/uniform\s+\w+\s+(\w+)/g);if(i)for(const t of i){const r=t.split(" ")[2];this.uniformLoc[r]=e.getUniformLocation(this.program,r)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const r=this.gl;r.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),r.enableVertexAttribArray(e)}}}class u{constructor(t,e){this.usedTextures=[],this.needBind=new Set,this.attribute=e,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new s(t.gl,Float32Array,t.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:t.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...r){const[i,s]=this.rapid.transformPoint(t,e);this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s)}useTexture(t){let e=this.usedTextures.indexOf(t);return-1===e&&(this.usedTextures.length>=this.rapid.maxTextureUnits&&this.render(),this.usedTextures.push(t),e=this.usedTextures.length-1,this.needBind.add(e)),e}enterRegion(t){this.currentShader=null!=t?t:this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer();for(const t of this.attribute)this.currentShader.setAttribute(t);this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(t,e){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new o(this.rapid,t,e,this.attribute)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const t=this.gl;for(const e of this.needBind)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.needBind.clear()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class c extends u{constructor(t){super(t,l),this.vertex=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(t,e,r){this.webglArrayBuffer.resize(3),super.addVertex(t,e),this.webglArrayBuffer.pushUint(r),this.vertex+=1}drawCircle(t,e,r,i){const s=2*Math.PI/30;this.startRender(),this.addVertex(t,e,i);for(let a=0;a<=30;a++){const n=a*s,h=t+r*Math.cos(n),o=e+r*Math.sin(n);this.addVertex(h,o,i)}this.executeRender()}executeRender(){super.executeRender();const t=this.gl;t.drawArrays(t.TRIANGLE_FAN,0,this.vertex),this.vertex=0}}const l=[{name:"aPosition",size:2,type:r,stride:12},{name:"aColor",size:4,type:5121,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class d extends n{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.push(t),this.push(t+3),this.push(t+2),this.push(t),this.push(t+1),this.push(t+2)}}class f extends u{constructor(t){const e=t.gl;super(t,g),this.batchSprite=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}","precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}"),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new d(e,this.MAX_BATCH)}addVertex(t,e,r,i,s,a){super.addVertex(t,e),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s),this.webglArrayBuffer.pushUint(a)}renderSprite(t,e,r,i,s,a,n,h,o,u,c){var l;c&&(null===(l=this.currentShader)||void 0===l||l.setUniforms(c)),this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const d=this.useTexture(t),f=h+e,g=o+r,m=i+a,p=s+n;this.addVertex(h,o,i,s,d,u),this.addVertex(f,o,m,s,d,u),this.addVertex(f,g,m,p,d,u),this.addVertex(h,g,i,p,d,u)}executeRender(){super.executeRender();const t=this.gl;t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}}const g=[{name:"aPosition",size:2,type:r,stride:24},{name:"aRegion",size:2,type:r,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:r,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class m{constructor(t){this.cache=new Map,this.render=t}async textureFromUrl(t,e=!1){let r=this.cache.get(t);if(!r){const i=await this.loadImage(t);r=p.fromImageSource(this.render,i,e),this.cache.set(t,r)}return new x(r)}async loadImage(t){return new Promise((e=>{const r=new Image;r.onload=()=>{e(r)},r.src=t}))}}class p{constructor(t,e,r){this.texture=t,this.width=e,this.height=r}static fromImageSource(t,e,r=!1){return new p(function(t,e,r){const i=t.createTexture();if(t.bindTexture(t.TEXTURE_2D,i),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),!i)throw new Error("unable to create texture");return i}(t.gl,e,r),e.width,e.height)}}class x{constructor(t){this.base=t,this.setClipRegion(0,0,t.width,t.height)}setClipRegion(t,e,r,i){this.clipX=t/this.base.width,this.clipY=e/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+i/this.base.width,this.width=r,this.height=i}static fromImageSource(t,e,r=!1){return new x(p.fromImageSource(t,e,r))}static fromUrl(t,e){return t.textures.textureFromUrl(e)}}return t.BaseTexture=p,t.Color=h,t.DynamicArrayBuffer=i,t.GLShader=o,t.MatrixStack=a,t.Rapid=class{constructor(t){this.projectionDirty=!0,this.matrixStack=new a,this.textures=new m(this),this.devicePixelRatio=window.devicePixelRatio||1,this.defaultColor=new h(255,255,255,255),this.regions=new Map;const e=(t=>{const e=t.getContext("webgl2")||t.getContext("webgl");if(!e)throw new Error("TODO");return e})(t.canvas);this.gl=e,this.canvas=t.canvas,this.maxTextureUnits=e.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=t.width||this.canvas.width,this.height=t.width||this.canvas.height,this.backgroundColor=t.backgroundColor||new h(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(e)}initWebgl(t){this.resize(this.width,this.height),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",f),this.registerRegion("graphic",c)}registerRegion(t,e){this.regions.set(t,new e(this))}setRegion(t,e){if(t!=this.currentRegionName||e&&e!==this.currentRegion.currentShader){const r=this.regions.get(t);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=t,r.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(t=!0){t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){var t;null===(t=this.currentRegion)||void 0===t||t.render(),this.projectionDirty=!1}renderSprite(t,e=0,r=0,i){if(i instanceof h)return this.renderSprite(t,e,r,{color:i});this.setRegion("sprite",null==i?void 0:i.shader),this.currentRegion.renderSprite(t.base.texture,t.width,t.height,t.clipX,t.clipY,t.clipW,t.clipH,e,r,((null==i?void 0:i.color)||this.defaultColor).uint32,null==i?void 0:i.uniforms)}startGraphicDraw(t){this.setRegion("graphic",t),this.currentRegion.startRender()}addGraphicVertex(t,e,r){this.currentRegion.addVertex(t,e,r.uint32)}endGraphicDraw(){this.currentRegion.render()}resize(t,e){this.width=t,this.height=e;const r=t*this.devicePixelRatio,i=e*this.devicePixelRatio;this.canvas.width=r,this.canvas.height=i,this.gl.viewport(0,0,r,i),this.projection=this.createOrthMatrix(0,t,e,0),this.projectionDirty=!0}clear(){const t=this.gl,e=this.backgroundColor;t.clearColor(e.r,e.g,e.b,e.a),t.clear(t.COLOR_BUFFER_BIT)}createOrthMatrix(t,e,r,i){return new Float32Array([2/(e-t),0,0,0,0,2/(i-r),0,0,0,0,-1,0,-(e+t)/(e-t),-(i+r)/(i-r),0,1])}transformPoint(t,e){return this.matrixStack.apply(t,e)}},t.Texture=x,t.TextureCache=m,t.WebglBufferArray=s,t.WebglElementBufferArray=n,t.graphicAttributes=l,t.spriteAttributes=g,t}({});
1
+ var rapid=function(t){"use strict";const e=(t,e,r)=>{const i=t.createShader(r);if(!i)throw new Error("Unable to create webgl shader");t.shaderSource(i,e),t.compileShader(i);if(!t.getShaderParameter(i,t.COMPILE_STATUS)){const r=t.getShaderInfoLog(i);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+e)}return i};const r=5126;class i{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=t.BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new t(this.arraybuffer),t==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(e)}push(t){this.typedArray[this.usedElemNum++]=t}pushUint(t){this.uint32[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.typedArray.length}}class s extends i{constructor(t,e,r=t.ARRAY_BUFFER){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=r}push(t){super.push(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),t.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class n extends i{constructor(){super(Float32Array)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.push(e[t+0]),this.push(e[t+1]),this.push(e[t+2]),this.push(e[t+3]),this.push(e[t+4]),this.push(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(t,e){if(t instanceof o)return this.translate(t.x,t.y);const r=this.usedElemNum-6,i=this.typedArray;i[r+4]=i[r+0]*t+i[r+2]*e+i[r+4],i[r+5]=i[r+1]*t+i[r+3]*e+i[r+5]}rotate(t){const e=this.usedElemNum-6,r=this.typedArray,i=Math.cos(t),s=Math.sin(t),n=r[e+0],h=r[e+1],a=r[e+2],o=r[e+3];r[e+0]=n*i-h*s,r[e+1]=n*s+h*i,r[e+2]=a*i-o*s,r[e+3]=a*s+o*i}scale(t,e){if(t instanceof o)return this.scale(t.x,t.y);const r=this.usedElemNum-6,i=this.typedArray;i[r+0]=i[r+0]*t,i[r+1]=i[r+1]*t,i[r+2]=i[r+2]*e,i[r+3]=i[r+3]*e}apply(t,e){if(t instanceof o)return new o(...this.apply(t.x,t.y));const r=this.usedElemNum-6,i=this.typedArray;return[i[r+0]*t+i[r+2]*e+i[r+4],i[r+1]*t+i[r+3]*e+i[r+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,r=e[t+0],i=e[t+1],s=e[t+2],n=e[t+3],h=e[t+4],a=e[t+5],o=r*n-i*s;return new Float32Array([n/o,-i/o,-s/o,r/o,(s*a-n*h)/o,(i*h-r*a)/o])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,r=this.typedArray;r[e+0]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}}class h extends s{constructor(t,e,r,i){super(t,Uint16Array,t.ELEMENT_ARRAY_BUFFER),this.setMaxSize(e*i);for(let t=0;t<i;t++)this.addObject(t*r);this.bindBuffer(),this.bufferData()}addObject(t){}}class a{constructor(t,e,r,i){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,r,i){this.r=t,this.g=e,this.b=r,this.a=i,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),i=parseInt(t.slice(4,6),16);let s=255;return t.length>=8&&(s=parseInt(t.slice(6,8),16)),new a(e,r,i,s)}add(t){return new a(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new a(Math.max(this.r-t.r,0),Math.max(this.g-t.g,0),Math.max(this.b-t.b,0),Math.max(this.a-t.a,0))}}class o{constructor(t,e){this.x=void 0!==t?t:0,this.y=void 0!==e?e:0}scalarMult(t){return this.x*=t,this.y*=t,this}perpendicular(){const t=this.x;return this.x=-this.y,this.y=t,this}invert(){return this.x=-this.x,this.y=-this.y,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}normalize(){const t=this.length();return this.x/=t,this.y/=t,this}angle(){return this.y/this.x}static Angle(t,e){return Math.atan2(e.x-t.x,e.y-t.y)}static Add(t,e){return new o(t.x+e.x,t.y+e.y)}static Sub(t,e){return new o(t.x-e.x,t.y-e.y)}static Middle(t,e){return o.Add(t,e).scalarMult(.5)}}class u{constructor(t){this.cache=new Map,this.render=t}async textureFromUrl(t,e=!1){let r=this.cache.get(t);if(!r){const i=await this.loadImage(t);r=l.fromImageSource(this.render,i,e),this.cache.set(t,r)}return new d(r)}async loadImage(t){return new Promise((e=>{const r=new Image;r.onload=()=>{e(r)},r.src=t}))}createText(t){return new c(this.render,t)}}class l{constructor(t,e,r){this.texture=t,this.width=e,this.height=r}static fromImageSource(t,e,r=!1){return new l(function(t,e,r){const i=t.createTexture();if(t.bindTexture(t.TEXTURE_2D,i),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),!i)throw new Error("unable to create texture");return i}(t.gl,e,r),e.width,e.height)}}class d{constructor(t){this.scale=1,this.setBase(t)}setBase(t,e=1){t&&(this.base=t,this.setClipRegion(0,0,t.width*e,t.height*e))}setClipRegion(t,e,r,i){this.base&&(this.clipX=t/this.base.width,this.clipY=e/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+i/this.base.height,this.width=r*this.scale,this.height=i*this.scale)}static fromImageSource(t,e,r=!1){return new d(l.fromImageSource(t,e,r))}static fromUrl(t,e){return t.textures.textureFromUrl(e)}}class c extends d{constructor(t,e){super(),this.scale=.5,this.rapid=t,this.options=e,this.text=e.text||"",this.updateTextImage()}updateTextImage(){const t=this.createTextCanvas();this.setBase(l.fromImageSource(this.rapid,t,!0))}createTextCanvas(){const t=document.createElement("canvas"),e=t.getContext("2d");if(!e)throw new Error("Failed to get canvas context");e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";const r=this.text.split("\n");let i=0,s=0;for(const t of r){const r=e.measureText(t);i=Math.max(i,r.width),s+=this.options.fontSize||16}t.width=2*i,t.height=2*s,e.scale(2,2),e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";let n=0;for(const t of r)e.fillText(t,0,n),n+=this.options.fontSize||16;return t}setText(t){this.text=t,this.updateTextImage()}}class p{constructor(t,r,i){this.attributeLoc={},this.uniformLoc={};const s=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let r="";for(let t=0;t<e;t++)r+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,r+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",r)}return t}(i,t.maxTextureUnits);this.program=((t,r,i)=>{var s=t.createProgram(),n=e(t,r,35633),h=e(t,i,35632);if(!s)throw new Error("Unable to create program shader");return t.attachShader(s,n),t.attachShader(s,h),t.linkProgram(s),s})(t.gl,r,s),this.gl=t.gl,this.parseShader(r),this.parseShader(s)}setUniforms(t,e){var r;const i=this.gl;for(const s in t){const n=t[s],h=this.getUniform(s);if(n instanceof d&&(null===(r=n.base)||void 0===r?void 0:r.texture))i.activeTexture(i.TEXTURE0+e),i.bindTexture(i.TEXTURE_2D,n.base.texture),i.uniform1i(h,e),e+=1;else if("number"==typeof n)i.uniform1f(h,n);else if(Array.isArray(n))switch(n.length){case 1:Number.isInteger(n[0])?i.uniform1i(h,n[0]):i.uniform1f(h,n[0]);break;case 2:Number.isInteger(n[0])?i.uniform2iv(h,n):i.uniform2fv(h,n);break;case 3:Number.isInteger(n[0])?i.uniform3iv(h,n):i.uniform3fv(h,n);break;case 4:Number.isInteger(n[0])?i.uniform4iv(h,n):i.uniform4fv(h,n);break;case 9:i.uniformMatrix3fv(h,!1,n);break;case 16:i.uniformMatrix4fv(h,!1,n);break;default:console.error(`Unsupported uniform array length for ${s}:`,n.length)}else"boolean"==typeof n?i.uniform1i(h,n?1:0):console.error(`Unsupported uniform type for ${s}:`,typeof n)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const t of r){const r=t.split(" ")[2],i=e.getAttribLocation(this.program,r);-1!=i&&(this.attributeLoc[r]=i)}const i=t.match(/uniform\s+\w+\s+(\w+)/g);if(i)for(const t of i){const r=t.split(" ")[2];this.uniformLoc[r]=e.getUniformLocation(this.program,r)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const r=this.gl;r.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),r.enableVertexAttribArray(e)}}}class f{constructor(t,e){this.usedTextures=[],this.needBind=new Set,this.attribute=e,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new s(t.gl,Float32Array,t.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:t.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...r){const[i,s]=this.rapid.transformPoint(t,e);this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s)}useTexture(t){let e=this.usedTextures.indexOf(t);return-1===e&&(this.usedTextures.length>=this.rapid.maxTextureUnits&&this.render(),this.usedTextures.push(t),e=this.usedTextures.length-1,this.needBind.add(e)),e}enterRegion(t){this.currentShader=null!=t?t:this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer();for(const t of this.attribute)this.currentShader.setAttribute(t);this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(t,e){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new p(this.rapid,t,e)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const t=this.gl;for(const e of this.needBind)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.needBind.clear()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class g extends f{constructor(t){super(t,m),this.vertex=0,this.drawType=t.gl.TRIANGLE_FAN,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(t,e,r){this.webglArrayBuffer.resize(3),super.addVertex(t,e),this.webglArrayBuffer.pushUint(r),this.vertex+=1}drawCircle(t,e,r,i){const s=2*Math.PI/30;this.startRender(),this.addVertex(t,e,i);for(let n=0;n<=30;n++){const h=n*s,a=t+r*Math.cos(h),o=e+r*Math.sin(h);this.addVertex(a,o,i)}this.executeRender()}executeRender(){super.executeRender();this.gl.drawArrays(this.drawType,0,this.vertex),this.drawType=this.rapid.gl.TRIANGLE_FAN,this.vertex=0}}const m=[{name:"aPosition",size:2,type:r,stride:12},{name:"aColor",size:4,type:5121,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class x extends h{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.push(t),this.push(t+3),this.push(t+2),this.push(t),this.push(t+1),this.push(t+2)}}class y extends f{constructor(t){const e=t.gl;super(t,T),this.batchSprite=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}","precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}"),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new x(e,this.MAX_BATCH)}addVertex(t,e,r,i,s,n){super.addVertex(t,e),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s),this.webglArrayBuffer.pushUint(n)}renderSprite(t,e,r,i,s,n,h,a,o,u,l){var d;l&&(null===(d=this.currentShader)||void 0===d||d.setUniforms(l,1)),this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const c=this.useTexture(t),p=a+e,f=o+r,g=i+n,m=s+h;this.addVertex(a,o,i,s,c,u),this.addVertex(p,o,g,s,c,u),this.addVertex(p,f,g,m,c,u),this.addVertex(a,f,i,m,c,u)}executeRender(){super.executeRender();const t=this.gl;t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}}const T=[{name:"aPosition",size:2,type:r,stride:24},{name:"aRegion",size:2,type:r,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:r,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];var E,b;t.JoinTyps=void 0,(E=t.JoinTyps||(t.JoinTyps={}))[E.BEVEL=0]="BEVEL",E[E.ROUND=1]="ROUND",E[E.MITER=2]="MITER",t.CapTyps=void 0,(b=t.CapTyps||(t.CapTyps={}))[b.BUTT=0]="BUTT",b[b.ROUND=1]="ROUND",b[b.SQUARE=2]="SQUARE";const A=1e-4,R=(t,e,r,i)=>{i.push(t),i.push(o.Add(t,r)),i.push(o.Add(e,r)),i.push(e),i.push(o.Add(e,r)),i.push(t)},S=(t,e,r,i,s)=>{const n=o.Sub(t,e).length();let h=Math.atan2(r.y-t.y,r.x-t.x),a=Math.atan2(e.y-t.y,e.x-t.x);const u=h;a>h?a-h>=Math.PI-A&&(a-=2*Math.PI):h-a>=Math.PI-A&&(h-=2*Math.PI);let l=a-h;if(Math.abs(l)>=Math.PI-A&&Math.abs(l)<=Math.PI+A){const e=o.Sub(t,i);0===e.x?e.y>0&&(l=-l):e.x>=-1e-4&&(l=-l)}const d=(Math.abs(l*n)/7>>0)+1,c=l/d;for(let e=0;e<d;e++)s.push(new o(t.x,t.y)),s.push(new o(t.x+n*Math.cos(u+c*e),t.y+n*Math.sin(u+c*e))),s.push(new o(t.x+n*Math.cos(u+c*(1+e)),t.y+n*Math.sin(u+c*(1+e))))},v=(e,r,i,s,n,h,a)=>{const u=o.Sub(r,e).perpendicular(),l=o.Sub(i,r).perpendicular();((t,e,r)=>(e.x-t.x)*(r.y-t.y)-(r.x-t.x)*(e.y-t.y))(e,r,i)>0&&(u.invert(),l.invert()),u.normalize().scalarMult(n),l.normalize().scalarMult(n);const d=((t,e,r,i)=>{const s=e.y-t.y,n=t.x-e.x,h=i.y-r.y,a=r.x-i.x,u=s*a-h*n;if(u>-1e-4&&u<A)return null;{const e=s*t.x+n*t.y,i=h*r.x+a*r.y;return new o((a*e-n*i)/u,(s*i-h*e)/u)}})(o.Add(u,e),o.Add(u,r),o.Add(l,i),o.Add(l,r));let c=null,p=Number.MAX_VALUE;d&&(c=o.Sub(d,r),p=c.length());const f=p/n|0,g=o.Sub(e,r).length(),m=o.Sub(r,i).length();if(p>g||p>m)s.push(o.Add(e,u)),s.push(o.Sub(e,u)),s.push(o.Add(r,u)),s.push(o.Sub(e,u)),s.push(o.Add(r,u)),s.push(o.Sub(r,u)),h===t.JoinTyps.ROUND?S(r,o.Add(r,u),o.Add(r,l),i,s):h===t.JoinTyps.BEVEL||h===t.JoinTyps.MITER&&f>=a?(s.push(r),s.push(o.Add(r,u)),s.push(o.Add(r,l))):h===t.JoinTyps.MITER&&f<a&&d&&(s.push(o.Add(r,u)),s.push(r),s.push(d),s.push(o.Add(r,l)),s.push(r),s.push(d)),s.push(o.Add(i,l)),s.push(o.Sub(r,l)),s.push(o.Add(r,l)),s.push(o.Add(i,l)),s.push(o.Sub(r,l)),s.push(o.Sub(i,l));else{if(s.push(o.Add(e,u)),s.push(o.Sub(e,u)),s.push(o.Sub(r,c)),s.push(o.Add(e,u)),s.push(o.Sub(r,c)),s.push(o.Add(r,u)),h===t.JoinTyps.ROUND){const t=o.Add(r,u),e=o.Add(r,l),i=o.Sub(r,c),n=r;s.push(t),s.push(n),s.push(i),S(n,t,e,i,s),s.push(n),s.push(e),s.push(i)}else(h===t.JoinTyps.BEVEL||h===t.JoinTyps.MITER&&f>=a)&&(s.push(o.Add(r,u)),s.push(o.Add(r,l)),s.push(o.Sub(r,c))),h===t.JoinTyps.MITER&&f<a&&(s.push(d),s.push(o.Add(r,u)),s.push(o.Add(r,l)));s.push(o.Add(i,l)),s.push(o.Sub(r,c)),s.push(o.Add(r,l)),s.push(o.Add(i,l)),s.push(o.Sub(r,c)),s.push(o.Sub(i,l))}};return t.BaseTexture=l,t.Color=a,t.DynamicArrayBuffer=i,t.GLShader=p,t.MatrixStack=n,t.Rapid=class{constructor(t){this.projectionDirty=!0,this.matrixStack=new n,this.textures=new u(this),this.devicePixelRatio=window.devicePixelRatio||1,this.defaultColor=new a(255,255,255,255),this.defaultColorBlack=new a(0,0,0,255),this.regions=new Map;const e=(t=>{const e=t.getContext("webgl2")||t.getContext("webgl");if(!e)throw new Error("TODO");return e})(t.canvas);this.gl=e,this.canvas=t.canvas,this.maxTextureUnits=e.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=t.width||this.canvas.width,this.height=t.width||this.canvas.height,this.backgroundColor=t.backgroundColor||new a(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(e)}initWebgl(t){this.resize(this.width,this.height),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",y),this.registerRegion("graphic",g)}registerRegion(t,e){this.regions.set(t,new e(this))}setRegion(t,e){if(t!=this.currentRegionName||e&&e!==this.currentRegion.currentShader){const r=this.regions.get(t);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=t,r.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(t=!0){t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){var t;null===(t=this.currentRegion)||void 0===t||t.render(),this.projectionDirty=!1}renderSprite(t,e=0,r=0,i){if(t.base){if(i instanceof a)return this.renderSprite(t,e,r,{color:i});this.setRegion("sprite",null==i?void 0:i.shader),this.currentRegion.renderSprite(t.base.texture,t.width,t.height,t.clipX,t.clipY,t.clipW,t.clipH,e,r,((null==i?void 0:i.color)||this.defaultColor).uint32,null==i?void 0:i.uniforms)}}renderLine(e=0,r=0,i){const s=((e,r)=>{if(e.length<2)return[];let i=r.cap||t.CapTyps.BUTT,s=r.join||t.JoinTyps.BEVEL,n=(r.width||1)/2,h=r.miterLimit||10,a=[],u=[];if(2===e.length)s=t.JoinTyps.BEVEL,v(e[0],o.Middle(e[0],e[1]),e[1],a,n,s,h);else{for(let t=0;t<e.length-1;t++)0===t?u.push(e[0]):t===e.length-2?u.push(e[e.length-1]):u.push(o.Middle(e[t],e[t+1]));for(let t=1;t<u.length;t++)v(u[t-1],e[t],u[t],a,n,s,h)}if(i===t.CapTyps.ROUND){let t=a[0],r=a[1],i=e[1],s=a[a.length-1],n=a[a.length-3],h=e[e.length-2];S(e[0],t,r,i,a),S(e[e.length-1],s,n,h,a)}else if(i===t.CapTyps.SQUARE){let t=a[a.length-1],r=a[a.length-3];R(a[0],a[1],o.Sub(e[0],e[1]).normalize().scalarMult(o.Sub(e[0],a[0]).length()),a),R(t,r,o.Sub(e[e.length-1],e[e.length-2]).normalize().scalarMult(o.Sub(r,e[e.length-1]).length()),a)}return a})(i.points,i);this.renderGraphic(e,r,s,i.color,this.gl.TRIANGLES)}renderGraphic(t=0,e=0,r,i,s){this.startGraphicDraw(),s&&(this.currentRegion.drawType=s),r.forEach((r=>{this.addGraphicVertex(r.x+t,r.y+e,i||this.defaultColorBlack)})),this.endGraphicDraw()}startGraphicDraw(t){this.setRegion("graphic",t),this.currentRegion.startRender()}addGraphicVertex(t,e,r){if(t instanceof o)return this.addGraphicVertex(t.x,t.y,e);this.currentRegion.addVertex(t,e,r.uint32)}endGraphicDraw(){this.currentRegion.render()}resize(t,e){this.width=t,this.height=e;const r=t*this.devicePixelRatio,i=e*this.devicePixelRatio;this.canvas.width=r,this.canvas.height=i,this.gl.viewport(0,0,r,i),this.projection=this.createOrthMatrix(0,t,e,0),this.projectionDirty=!0}clear(){const t=this.gl,e=this.backgroundColor;t.clearColor(e.r,e.g,e.b,e.a),t.clear(t.COLOR_BUFFER_BIT)}createOrthMatrix(t,e,r,i){return new Float32Array([2/(e-t),0,0,0,0,2/(i-r),0,0,0,0,-1,0,-(e+t)/(e-t),-(i+r)/(i-r),0,1])}transformPoint(t,e){return this.matrixStack.apply(t,e)}},t.SCALEFACTOR=2,t.Text=c,t.Texture=d,t.TextureCache=u,t.Vec2=o,t.WebglBufferArray=s,t.WebglElementBufferArray=h,t.graphicAttributes=m,t.spriteAttributes=T,t}({});
package/dist/rapid.js CHANGED
@@ -1 +1 @@
1
- const t=(t,e,r)=>{const i=t.createShader(r);if(!i)throw new Error("Unable to create webgl shader");t.shaderSource(i,e),t.compileShader(i);if(!t.getShaderParameter(i,t.COMPILE_STATUS)){const r=t.getShaderInfoLog(i);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+e)}return i};const e=5126;class r{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=t.BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new t(this.arraybuffer),t==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(e)}push(t){this.typedArray[this.usedElemNum++]=t}pushUint(t){this.uint32[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.typedArray.length}}class i extends r{constructor(t,e,r=t.ARRAY_BUFFER){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=r}push(t){super.push(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),t.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class s extends r{constructor(){super(Float32Array)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.push(e[t+0]),this.push(e[t+1]),this.push(e[t+2]),this.push(e[t+3]),this.push(e[t+4]),this.push(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(t,e){const r=this.usedElemNum-6,i=this.typedArray;i[r+4]=i[r+0]*t+i[r+2]*e+i[r+4],i[r+5]=i[r+1]*t+i[r+3]*e+i[r+5]}rotate(t){const e=this.usedElemNum-6,r=this.typedArray,i=Math.cos(t),s=Math.sin(t),n=r[e+0],a=r[e+1],h=r[e+2],o=r[e+3];r[e+0]=n*i-a*s,r[e+1]=n*s+a*i,r[e+2]=h*i-o*s,r[e+3]=h*s+o*i}scale(t,e=t){const r=this.usedElemNum-6,i=this.typedArray;i[r+0]=i[r+0]*t,i[r+1]=i[r+1]*t,i[r+2]=i[r+2]*e,i[r+3]=i[r+3]*e}apply(t,e){const r=this.usedElemNum-6,i=this.typedArray;return[i[r+0]*t+i[r+2]*e+i[r+4],i[r+1]*t+i[r+3]*e+i[r+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,r=e[t+0],i=e[t+1],s=e[t+2],n=e[t+3],a=e[t+4],h=e[t+5],o=r*n-i*s;return new Float32Array([n/o,-i/o,-s/o,r/o,(s*h-n*a)/o,(i*a-r*h)/o])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,r=this.typedArray;r[e+0]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}}class n extends i{constructor(t,e,r,i){super(t,Uint16Array,t.ELEMENT_ARRAY_BUFFER),this.setMaxSize(e*i);for(let t=0;t<i;t++)this.addObject(t*r);this.bindBuffer(),this.bufferData()}addObject(t){}}class a{constructor(t,e,r,i){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,r,i){this.r=t,this.g=e,this.b=r,this.a=i,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),i=parseInt(t.slice(4,6),16);let s=255;return t.length>=8&&(s=parseInt(t.slice(6,8),16)),new a(e,r,i,s)}add(t){return new a(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new a(Math.max(this.r-t.r,0),Math.max(this.g-t.g,0),Math.max(this.b-t.b,0),Math.max(this.a-t.a,0))}}class h{constructor(e,r,i,s){this.attributeLoc={},this.uniformLoc={};const n=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let r="";for(let t=0;t<e;t++)r+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,r+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",r)}return t}(i,e.maxTextureUnits);this.program=((e,r,i)=>{var s=e.createProgram(),n=t(e,r,35633),a=t(e,i,35632);if(!s)throw new Error("Unable to create program shader");return e.attachShader(s,n),e.attachShader(s,a),e.linkProgram(s),s})(e.gl,r,n),this.gl=e.gl,this.attribute=s,this.parseShader(r),this.parseShader(n)}setUniforms(t){const e=this.gl;for(const r in t){const i=t[r],s=this.getUniform(r);if("number"==typeof i)e.uniform1f(s,i);else if(Array.isArray(i))switch(i.length){case 1:Number.isInteger(i[0])?e.uniform1i(s,i[0]):e.uniform1f(s,i[0]);break;case 2:Number.isInteger(i[0])?e.uniform2iv(s,i):e.uniform2fv(s,i);break;case 3:Number.isInteger(i[0])?e.uniform3iv(s,i):e.uniform3fv(s,i);break;case 4:Number.isInteger(i[0])?e.uniform4iv(s,i):e.uniform4fv(s,i);break;case 9:e.uniformMatrix3fv(s,!1,i);break;case 16:e.uniformMatrix4fv(s,!1,i);break;default:console.error(`Unsupported uniform array length for ${r}:`,i.length)}else"boolean"==typeof i?e.uniform1i(s,i?1:0):console.error(`Unsupported uniform type for ${r}:`,typeof i)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const t of r){const r=t.split(" ")[2],i=e.getAttribLocation(this.program,r);-1!=i&&(this.attributeLoc[r]=i)}const i=t.match(/uniform\s+\w+\s+(\w+)/g);if(i)for(const t of i){const r=t.split(" ")[2];this.uniformLoc[r]=e.getUniformLocation(this.program,r)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const r=this.gl;r.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),r.enableVertexAttribArray(e)}}}class o{constructor(t,e){this.usedTextures=[],this.needBind=new Set,this.attribute=e,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new i(t.gl,Float32Array,t.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:t.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...r){const[i,s]=this.rapid.transformPoint(t,e);this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s)}useTexture(t){let e=this.usedTextures.indexOf(t);return-1===e&&(this.usedTextures.length>=this.rapid.maxTextureUnits&&this.render(),this.usedTextures.push(t),e=this.usedTextures.length-1,this.needBind.add(e)),e}enterRegion(t){this.currentShader=null!=t?t:this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer();for(const t of this.attribute)this.currentShader.setAttribute(t);this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(t,e){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new h(this.rapid,t,e,this.attribute)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const t=this.gl;for(const e of this.needBind)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.needBind.clear()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class u extends o{constructor(t){super(t,c),this.vertex=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(t,e,r){this.webglArrayBuffer.resize(3),super.addVertex(t,e),this.webglArrayBuffer.pushUint(r),this.vertex+=1}drawCircle(t,e,r,i){const s=2*Math.PI/30;this.startRender(),this.addVertex(t,e,i);for(let n=0;n<=30;n++){const a=n*s,h=t+r*Math.cos(a),o=e+r*Math.sin(a);this.addVertex(h,o,i)}this.executeRender()}executeRender(){super.executeRender();const t=this.gl;t.drawArrays(t.TRIANGLE_FAN,0,this.vertex),this.vertex=0}}const c=[{name:"aPosition",size:2,type:e,stride:12},{name:"aColor",size:4,type:5121,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class d extends n{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.push(t),this.push(t+3),this.push(t+2),this.push(t),this.push(t+1),this.push(t+2)}}class l extends o{constructor(t){const e=t.gl;super(t,f),this.batchSprite=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}","precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}"),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new d(e,this.MAX_BATCH)}addVertex(t,e,r,i,s,n){super.addVertex(t,e),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s),this.webglArrayBuffer.pushUint(n)}renderSprite(t,e,r,i,s,n,a,h,o,u,c){var d;c&&(null===(d=this.currentShader)||void 0===d||d.setUniforms(c)),this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const l=this.useTexture(t),f=h+e,g=o+r,m=i+n,p=s+a;this.addVertex(h,o,i,s,l,u),this.addVertex(f,o,m,s,l,u),this.addVertex(f,g,m,p,l,u),this.addVertex(h,g,i,p,l,u)}executeRender(){super.executeRender();const t=this.gl;t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}}const f=[{name:"aPosition",size:2,type:e,stride:24},{name:"aRegion",size:2,type:e,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:e,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class g{constructor(t){this.cache=new Map,this.render=t}async textureFromUrl(t,e=!1){let r=this.cache.get(t);if(!r){const i=await this.loadImage(t);r=m.fromImageSource(this.render,i,e),this.cache.set(t,r)}return new p(r)}async loadImage(t){return new Promise((e=>{const r=new Image;r.onload=()=>{e(r)},r.src=t}))}}class m{constructor(t,e,r){this.texture=t,this.width=e,this.height=r}static fromImageSource(t,e,r=!1){return new m(function(t,e,r){const i=t.createTexture();if(t.bindTexture(t.TEXTURE_2D,i),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),!i)throw new Error("unable to create texture");return i}(t.gl,e,r),e.width,e.height)}}class p{constructor(t){this.base=t,this.setClipRegion(0,0,t.width,t.height)}setClipRegion(t,e,r,i){this.clipX=t/this.base.width,this.clipY=e/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+i/this.base.width,this.width=r,this.height=i}static fromImageSource(t,e,r=!1){return new p(m.fromImageSource(t,e,r))}static fromUrl(t,e){return t.textures.textureFromUrl(e)}}class x{constructor(t){this.projectionDirty=!0,this.matrixStack=new s,this.textures=new g(this),this.devicePixelRatio=window.devicePixelRatio||1,this.defaultColor=new a(255,255,255,255),this.regions=new Map;const e=(t=>{const e=t.getContext("webgl2")||t.getContext("webgl");if(!e)throw new Error("TODO");return e})(t.canvas);this.gl=e,this.canvas=t.canvas,this.maxTextureUnits=e.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=t.width||this.canvas.width,this.height=t.width||this.canvas.height,this.backgroundColor=t.backgroundColor||new a(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(e)}initWebgl(t){this.resize(this.width,this.height),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",l),this.registerRegion("graphic",u)}registerRegion(t,e){this.regions.set(t,new e(this))}setRegion(t,e){if(t!=this.currentRegionName||e&&e!==this.currentRegion.currentShader){const r=this.regions.get(t);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=t,r.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(t=!0){t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){var t;null===(t=this.currentRegion)||void 0===t||t.render(),this.projectionDirty=!1}renderSprite(t,e=0,r=0,i){if(i instanceof a)return this.renderSprite(t,e,r,{color:i});this.setRegion("sprite",null==i?void 0:i.shader),this.currentRegion.renderSprite(t.base.texture,t.width,t.height,t.clipX,t.clipY,t.clipW,t.clipH,e,r,((null==i?void 0:i.color)||this.defaultColor).uint32,null==i?void 0:i.uniforms)}startGraphicDraw(t){this.setRegion("graphic",t),this.currentRegion.startRender()}addGraphicVertex(t,e,r){this.currentRegion.addVertex(t,e,r.uint32)}endGraphicDraw(){this.currentRegion.render()}resize(t,e){this.width=t,this.height=e;const r=t*this.devicePixelRatio,i=e*this.devicePixelRatio;this.canvas.width=r,this.canvas.height=i,this.gl.viewport(0,0,r,i),this.projection=this.createOrthMatrix(0,t,e,0),this.projectionDirty=!0}clear(){const t=this.gl,e=this.backgroundColor;t.clearColor(e.r,e.g,e.b,e.a),t.clear(t.COLOR_BUFFER_BIT)}createOrthMatrix(t,e,r,i){return new Float32Array([2/(e-t),0,0,0,0,2/(i-r),0,0,0,0,-1,0,-(e+t)/(e-t),-(i+r)/(i-r),0,1])}transformPoint(t,e){return this.matrixStack.apply(t,e)}}export{m as BaseTexture,a as Color,r as DynamicArrayBuffer,h as GLShader,s as MatrixStack,x as Rapid,p as Texture,g as TextureCache,i as WebglBufferArray,n as WebglElementBufferArray,c as graphicAttributes,f as spriteAttributes};
1
+ const t=(t,e,r)=>{const i=t.createShader(r);if(!i)throw new Error("Unable to create webgl shader");t.shaderSource(i,e),t.compileShader(i);if(!t.getShaderParameter(i,t.COMPILE_STATUS)){const r=t.getShaderInfoLog(i);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+e)}return i};const e=5126;class r{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=t.BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new t(this.arraybuffer),t==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(e)}push(t){this.typedArray[this.usedElemNum++]=t}pushUint(t){this.uint32[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.typedArray.length}}class i extends r{constructor(t,e,r=t.ARRAY_BUFFER){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=r}push(t){super.push(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),t.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class s extends r{constructor(){super(Float32Array)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.push(e[t+0]),this.push(e[t+1]),this.push(e[t+2]),this.push(e[t+3]),this.push(e[t+4]),this.push(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(t,e){if(t instanceof a)return this.translate(t.x,t.y);const r=this.usedElemNum-6,i=this.typedArray;i[r+4]=i[r+0]*t+i[r+2]*e+i[r+4],i[r+5]=i[r+1]*t+i[r+3]*e+i[r+5]}rotate(t){const e=this.usedElemNum-6,r=this.typedArray,i=Math.cos(t),s=Math.sin(t),n=r[e+0],h=r[e+1],a=r[e+2],o=r[e+3];r[e+0]=n*i-h*s,r[e+1]=n*s+h*i,r[e+2]=a*i-o*s,r[e+3]=a*s+o*i}scale(t,e){if(t instanceof a)return this.scale(t.x,t.y);const r=this.usedElemNum-6,i=this.typedArray;i[r+0]=i[r+0]*t,i[r+1]=i[r+1]*t,i[r+2]=i[r+2]*e,i[r+3]=i[r+3]*e}apply(t,e){if(t instanceof a)return new a(...this.apply(t.x,t.y));const r=this.usedElemNum-6,i=this.typedArray;return[i[r+0]*t+i[r+2]*e+i[r+4],i[r+1]*t+i[r+3]*e+i[r+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,r=e[t+0],i=e[t+1],s=e[t+2],n=e[t+3],h=e[t+4],a=e[t+5],o=r*n-i*s;return new Float32Array([n/o,-i/o,-s/o,r/o,(s*a-n*h)/o,(i*h-r*a)/o])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,r=this.typedArray;r[e+0]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}}class n extends i{constructor(t,e,r,i){super(t,Uint16Array,t.ELEMENT_ARRAY_BUFFER),this.setMaxSize(e*i);for(let t=0;t<i;t++)this.addObject(t*r);this.bindBuffer(),this.bufferData()}addObject(t){}}class h{constructor(t,e,r,i){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,r,i){this.r=t,this.g=e,this.b=r,this.a=i,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),i=parseInt(t.slice(4,6),16);let s=255;return t.length>=8&&(s=parseInt(t.slice(6,8),16)),new h(e,r,i,s)}add(t){return new h(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new h(Math.max(this.r-t.r,0),Math.max(this.g-t.g,0),Math.max(this.b-t.b,0),Math.max(this.a-t.a,0))}}class a{constructor(t,e){this.x=void 0!==t?t:0,this.y=void 0!==e?e:0}scalarMult(t){return this.x*=t,this.y*=t,this}perpendicular(){const t=this.x;return this.x=-this.y,this.y=t,this}invert(){return this.x=-this.x,this.y=-this.y,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}normalize(){const t=this.length();return this.x/=t,this.y/=t,this}angle(){return this.y/this.x}static Angle(t,e){return Math.atan2(e.x-t.x,e.y-t.y)}static Add(t,e){return new a(t.x+e.x,t.y+e.y)}static Sub(t,e){return new a(t.x-e.x,t.y-e.y)}static Middle(t,e){return a.Add(t,e).scalarMult(.5)}}class o{constructor(t){this.cache=new Map,this.render=t}async textureFromUrl(t,e=!1){let r=this.cache.get(t);if(!r){const i=await this.loadImage(t);r=u.fromImageSource(this.render,i,e),this.cache.set(t,r)}return new l(r)}async loadImage(t){return new Promise((e=>{const r=new Image;r.onload=()=>{e(r)},r.src=t}))}createText(t){return new c(this.render,t)}}class u{constructor(t,e,r){this.texture=t,this.width=e,this.height=r}static fromImageSource(t,e,r=!1){return new u(function(t,e,r){const i=t.createTexture();if(t.bindTexture(t.TEXTURE_2D,i),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),!i)throw new Error("unable to create texture");return i}(t.gl,e,r),e.width,e.height)}}class l{constructor(t){this.scale=1,this.setBase(t)}setBase(t,e=1){t&&(this.base=t,this.setClipRegion(0,0,t.width*e,t.height*e))}setClipRegion(t,e,r,i){this.base&&(this.clipX=t/this.base.width,this.clipY=e/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+i/this.base.height,this.width=r*this.scale,this.height=i*this.scale)}static fromImageSource(t,e,r=!1){return new l(u.fromImageSource(t,e,r))}static fromUrl(t,e){return t.textures.textureFromUrl(e)}}const d=2;class c extends l{constructor(t,e){super(),this.scale=.5,this.rapid=t,this.options=e,this.text=e.text||"",this.updateTextImage()}updateTextImage(){const t=this.createTextCanvas();this.setBase(u.fromImageSource(this.rapid,t,!0))}createTextCanvas(){const t=document.createElement("canvas"),e=t.getContext("2d");if(!e)throw new Error("Failed to get canvas context");e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";const r=this.text.split("\n");let i=0,s=0;for(const t of r){const r=e.measureText(t);i=Math.max(i,r.width),s+=this.options.fontSize||16}t.width=2*i,t.height=2*s,e.scale(2,2),e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";let n=0;for(const t of r)e.fillText(t,0,n),n+=this.options.fontSize||16;return t}setText(t){this.text=t,this.updateTextImage()}}class p{constructor(e,r,i){this.attributeLoc={},this.uniformLoc={};const s=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let r="";for(let t=0;t<e;t++)r+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,r+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",r)}return t}(i,e.maxTextureUnits);this.program=((e,r,i)=>{var s=e.createProgram(),n=t(e,r,35633),h=t(e,i,35632);if(!s)throw new Error("Unable to create program shader");return e.attachShader(s,n),e.attachShader(s,h),e.linkProgram(s),s})(e.gl,r,s),this.gl=e.gl,this.parseShader(r),this.parseShader(s)}setUniforms(t,e){var r;const i=this.gl;for(const s in t){const n=t[s],h=this.getUniform(s);if(n instanceof l&&(null===(r=n.base)||void 0===r?void 0:r.texture))i.activeTexture(i.TEXTURE0+e),i.bindTexture(i.TEXTURE_2D,n.base.texture),i.uniform1i(h,e),e+=1;else if("number"==typeof n)i.uniform1f(h,n);else if(Array.isArray(n))switch(n.length){case 1:Number.isInteger(n[0])?i.uniform1i(h,n[0]):i.uniform1f(h,n[0]);break;case 2:Number.isInteger(n[0])?i.uniform2iv(h,n):i.uniform2fv(h,n);break;case 3:Number.isInteger(n[0])?i.uniform3iv(h,n):i.uniform3fv(h,n);break;case 4:Number.isInteger(n[0])?i.uniform4iv(h,n):i.uniform4fv(h,n);break;case 9:i.uniformMatrix3fv(h,!1,n);break;case 16:i.uniformMatrix4fv(h,!1,n);break;default:console.error(`Unsupported uniform array length for ${s}:`,n.length)}else"boolean"==typeof n?i.uniform1i(h,n?1:0):console.error(`Unsupported uniform type for ${s}:`,typeof n)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const t of r){const r=t.split(" ")[2],i=e.getAttribLocation(this.program,r);-1!=i&&(this.attributeLoc[r]=i)}const i=t.match(/uniform\s+\w+\s+(\w+)/g);if(i)for(const t of i){const r=t.split(" ")[2];this.uniformLoc[r]=e.getUniformLocation(this.program,r)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const r=this.gl;r.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),r.enableVertexAttribArray(e)}}}class f{constructor(t,e){this.usedTextures=[],this.needBind=new Set,this.attribute=e,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new i(t.gl,Float32Array,t.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:t.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...r){const[i,s]=this.rapid.transformPoint(t,e);this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s)}useTexture(t){let e=this.usedTextures.indexOf(t);return-1===e&&(this.usedTextures.length>=this.rapid.maxTextureUnits&&this.render(),this.usedTextures.push(t),e=this.usedTextures.length-1,this.needBind.add(e)),e}enterRegion(t){this.currentShader=null!=t?t:this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer();for(const t of this.attribute)this.currentShader.setAttribute(t);this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(t,e){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new p(this.rapid,t,e)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const t=this.gl;for(const e of this.needBind)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.needBind.clear()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class g extends f{constructor(t){super(t,m),this.vertex=0,this.drawType=t.gl.TRIANGLE_FAN,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(t,e,r){this.webglArrayBuffer.resize(3),super.addVertex(t,e),this.webglArrayBuffer.pushUint(r),this.vertex+=1}drawCircle(t,e,r,i){const s=2*Math.PI/30;this.startRender(),this.addVertex(t,e,i);for(let n=0;n<=30;n++){const h=n*s,a=t+r*Math.cos(h),o=e+r*Math.sin(h);this.addVertex(a,o,i)}this.executeRender()}executeRender(){super.executeRender();this.gl.drawArrays(this.drawType,0,this.vertex),this.drawType=this.rapid.gl.TRIANGLE_FAN,this.vertex=0}}const m=[{name:"aPosition",size:2,type:e,stride:12},{name:"aColor",size:4,type:5121,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class x extends n{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.push(t),this.push(t+3),this.push(t+2),this.push(t),this.push(t+1),this.push(t+2)}}class y extends f{constructor(t){const e=t.gl;super(t,E),this.batchSprite=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}","precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}"),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new x(e,this.MAX_BATCH)}addVertex(t,e,r,i,s,n){super.addVertex(t,e),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s),this.webglArrayBuffer.pushUint(n)}renderSprite(t,e,r,i,s,n,h,a,o,u,l){var d;l&&(null===(d=this.currentShader)||void 0===d||d.setUniforms(l,1)),this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const c=this.useTexture(t),p=a+e,f=o+r,g=i+n,m=s+h;this.addVertex(a,o,i,s,c,u),this.addVertex(p,o,g,s,c,u),this.addVertex(p,f,g,m,c,u),this.addVertex(a,f,i,m,c,u)}executeRender(){super.executeRender();const t=this.gl;t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}}const E=[{name:"aPosition",size:2,type:e,stride:24},{name:"aRegion",size:2,type:e,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:e,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];var b,A;!function(t){t[t.BEVEL=0]="BEVEL",t[t.ROUND=1]="ROUND",t[t.MITER=2]="MITER"}(b||(b={})),function(t){t[t.BUTT=0]="BUTT",t[t.ROUND=1]="ROUND",t[t.SQUARE=2]="SQUARE"}(A||(A={}));const T=1e-4,R=(t,e,r,i)=>{i.push(t),i.push(a.Add(t,r)),i.push(a.Add(e,r)),i.push(e),i.push(a.Add(e,r)),i.push(t)},S=(t,e,r,i,s)=>{const n=a.Sub(t,e).length();let h=Math.atan2(r.y-t.y,r.x-t.x),o=Math.atan2(e.y-t.y,e.x-t.x);const u=h;o>h?o-h>=Math.PI-T&&(o-=2*Math.PI):h-o>=Math.PI-T&&(h-=2*Math.PI);let l=o-h;if(Math.abs(l)>=Math.PI-T&&Math.abs(l)<=Math.PI+T){const e=a.Sub(t,i);0===e.x?e.y>0&&(l=-l):e.x>=-1e-4&&(l=-l)}const d=(Math.abs(l*n)/7>>0)+1,c=l/d;for(let e=0;e<d;e++)s.push(new a(t.x,t.y)),s.push(new a(t.x+n*Math.cos(u+c*e),t.y+n*Math.sin(u+c*e))),s.push(new a(t.x+n*Math.cos(u+c*(1+e)),t.y+n*Math.sin(u+c*(1+e))))},w=(t,e,r,i,s,n,h)=>{const o=a.Sub(e,t).perpendicular(),u=a.Sub(r,e).perpendicular();((t,e,r)=>(e.x-t.x)*(r.y-t.y)-(r.x-t.x)*(e.y-t.y))(t,e,r)>0&&(o.invert(),u.invert()),o.normalize().scalarMult(s),u.normalize().scalarMult(s);const l=((t,e,r,i)=>{const s=e.y-t.y,n=t.x-e.x,h=i.y-r.y,o=r.x-i.x,u=s*o-h*n;if(u>-1e-4&&u<T)return null;{const e=s*t.x+n*t.y,i=h*r.x+o*r.y;return new a((o*e-n*i)/u,(s*i-h*e)/u)}})(a.Add(o,t),a.Add(o,e),a.Add(u,r),a.Add(u,e));let d=null,c=Number.MAX_VALUE;l&&(d=a.Sub(l,e),c=d.length());const p=c/s|0,f=a.Sub(t,e).length(),g=a.Sub(e,r).length();if(c>f||c>g)i.push(a.Add(t,o)),i.push(a.Sub(t,o)),i.push(a.Add(e,o)),i.push(a.Sub(t,o)),i.push(a.Add(e,o)),i.push(a.Sub(e,o)),n===b.ROUND?S(e,a.Add(e,o),a.Add(e,u),r,i):n===b.BEVEL||n===b.MITER&&p>=h?(i.push(e),i.push(a.Add(e,o)),i.push(a.Add(e,u))):n===b.MITER&&p<h&&l&&(i.push(a.Add(e,o)),i.push(e),i.push(l),i.push(a.Add(e,u)),i.push(e),i.push(l)),i.push(a.Add(r,u)),i.push(a.Sub(e,u)),i.push(a.Add(e,u)),i.push(a.Add(r,u)),i.push(a.Sub(e,u)),i.push(a.Sub(r,u));else{if(i.push(a.Add(t,o)),i.push(a.Sub(t,o)),i.push(a.Sub(e,d)),i.push(a.Add(t,o)),i.push(a.Sub(e,d)),i.push(a.Add(e,o)),n===b.ROUND){const t=a.Add(e,o),r=a.Add(e,u),s=a.Sub(e,d),n=e;i.push(t),i.push(n),i.push(s),S(n,t,r,s,i),i.push(n),i.push(r),i.push(s)}else(n===b.BEVEL||n===b.MITER&&p>=h)&&(i.push(a.Add(e,o)),i.push(a.Add(e,u)),i.push(a.Sub(e,d))),n===b.MITER&&p<h&&(i.push(l),i.push(a.Add(e,o)),i.push(a.Add(e,u)));i.push(a.Add(r,u)),i.push(a.Sub(e,d)),i.push(a.Add(e,u)),i.push(a.Add(r,u)),i.push(a.Sub(e,d)),i.push(a.Sub(r,u))}};class v{constructor(t){this.projectionDirty=!0,this.matrixStack=new s,this.textures=new o(this),this.devicePixelRatio=window.devicePixelRatio||1,this.defaultColor=new h(255,255,255,255),this.defaultColorBlack=new h(0,0,0,255),this.regions=new Map;const e=(t=>{const e=t.getContext("webgl2")||t.getContext("webgl");if(!e)throw new Error("TODO");return e})(t.canvas);this.gl=e,this.canvas=t.canvas,this.maxTextureUnits=e.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=t.width||this.canvas.width,this.height=t.width||this.canvas.height,this.backgroundColor=t.backgroundColor||new h(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(e)}initWebgl(t){this.resize(this.width,this.height),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",y),this.registerRegion("graphic",g)}registerRegion(t,e){this.regions.set(t,new e(this))}setRegion(t,e){if(t!=this.currentRegionName||e&&e!==this.currentRegion.currentShader){const r=this.regions.get(t);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=t,r.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(t=!0){t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){var t;null===(t=this.currentRegion)||void 0===t||t.render(),this.projectionDirty=!1}renderSprite(t,e=0,r=0,i){if(t.base){if(i instanceof h)return this.renderSprite(t,e,r,{color:i});this.setRegion("sprite",null==i?void 0:i.shader),this.currentRegion.renderSprite(t.base.texture,t.width,t.height,t.clipX,t.clipY,t.clipW,t.clipH,e,r,((null==i?void 0:i.color)||this.defaultColor).uint32,null==i?void 0:i.uniforms)}}renderLine(t=0,e=0,r){const i=((t,e)=>{if(t.length<2)return[];let r=e.cap||A.BUTT,i=e.join||b.BEVEL,s=(e.width||1)/2,n=e.miterLimit||10,h=[],o=[];if(2===t.length)i=b.BEVEL,w(t[0],a.Middle(t[0],t[1]),t[1],h,s,i,n);else{for(let e=0;e<t.length-1;e++)0===e?o.push(t[0]):e===t.length-2?o.push(t[t.length-1]):o.push(a.Middle(t[e],t[e+1]));for(let e=1;e<o.length;e++)w(o[e-1],t[e],o[e],h,s,i,n)}if(r===A.ROUND){let e=h[0],r=h[1],i=t[1],s=h[h.length-1],n=h[h.length-3],a=t[t.length-2];S(t[0],e,r,i,h),S(t[t.length-1],s,n,a,h)}else if(r===A.SQUARE){let e=h[h.length-1],r=h[h.length-3];R(h[0],h[1],a.Sub(t[0],t[1]).normalize().scalarMult(a.Sub(t[0],h[0]).length()),h),R(e,r,a.Sub(t[t.length-1],t[t.length-2]).normalize().scalarMult(a.Sub(r,t[t.length-1]).length()),h)}return h})(r.points,r);this.renderGraphic(t,e,i,r.color,this.gl.TRIANGLES)}renderGraphic(t=0,e=0,r,i,s){this.startGraphicDraw(),s&&(this.currentRegion.drawType=s),r.forEach((r=>{this.addGraphicVertex(r.x+t,r.y+e,i||this.defaultColorBlack)})),this.endGraphicDraw()}startGraphicDraw(t){this.setRegion("graphic",t),this.currentRegion.startRender()}addGraphicVertex(t,e,r){if(t instanceof a)return this.addGraphicVertex(t.x,t.y,e);this.currentRegion.addVertex(t,e,r.uint32)}endGraphicDraw(){this.currentRegion.render()}resize(t,e){this.width=t,this.height=e;const r=t*this.devicePixelRatio,i=e*this.devicePixelRatio;this.canvas.width=r,this.canvas.height=i,this.gl.viewport(0,0,r,i),this.projection=this.createOrthMatrix(0,t,e,0),this.projectionDirty=!0}clear(){const t=this.gl,e=this.backgroundColor;t.clearColor(e.r,e.g,e.b,e.a),t.clear(t.COLOR_BUFFER_BIT)}createOrthMatrix(t,e,r,i){return new Float32Array([2/(e-t),0,0,0,0,2/(i-r),0,0,0,0,-1,0,-(e+t)/(e-t),-(i+r)/(i-r),0,1])}transformPoint(t,e){return this.matrixStack.apply(t,e)}}export{u as BaseTexture,A as CapTyps,h as Color,r as DynamicArrayBuffer,p as GLShader,b as JoinTyps,s as MatrixStack,v as Rapid,d as SCALEFACTOR,c as Text,l as Texture,o as TextureCache,a as Vec2,i as WebglBufferArray,n as WebglElementBufferArray,m as graphicAttributes,E as spriteAttributes};
@@ -1 +1 @@
1
- "use strict";const t=(t,e,r)=>{const i=t.createShader(r);if(!i)throw new Error("Unable to create webgl shader");t.shaderSource(i,e),t.compileShader(i);if(!t.getShaderParameter(i,t.COMPILE_STATUS)){const r=t.getShaderInfoLog(i);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+e)}return i};const e=5126;class r{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=t.BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new t(this.arraybuffer),t==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(e)}push(t){this.typedArray[this.usedElemNum++]=t}pushUint(t){this.uint32[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.typedArray.length}}class i extends r{constructor(t,e,r=t.ARRAY_BUFFER){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=r}push(t){super.push(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),t.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class s extends r{constructor(){super(Float32Array)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.push(e[t+0]),this.push(e[t+1]),this.push(e[t+2]),this.push(e[t+3]),this.push(e[t+4]),this.push(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(t,e){const r=this.usedElemNum-6,i=this.typedArray;i[r+4]=i[r+0]*t+i[r+2]*e+i[r+4],i[r+5]=i[r+1]*t+i[r+3]*e+i[r+5]}rotate(t){const e=this.usedElemNum-6,r=this.typedArray,i=Math.cos(t),s=Math.sin(t),a=r[e+0],n=r[e+1],h=r[e+2],o=r[e+3];r[e+0]=a*i-n*s,r[e+1]=a*s+n*i,r[e+2]=h*i-o*s,r[e+3]=h*s+o*i}scale(t,e=t){const r=this.usedElemNum-6,i=this.typedArray;i[r+0]=i[r+0]*t,i[r+1]=i[r+1]*t,i[r+2]=i[r+2]*e,i[r+3]=i[r+3]*e}apply(t,e){const r=this.usedElemNum-6,i=this.typedArray;return[i[r+0]*t+i[r+2]*e+i[r+4],i[r+1]*t+i[r+3]*e+i[r+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,r=e[t+0],i=e[t+1],s=e[t+2],a=e[t+3],n=e[t+4],h=e[t+5],o=r*a-i*s;return new Float32Array([a/o,-i/o,-s/o,r/o,(s*h-a*n)/o,(i*n-r*h)/o])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,r=this.typedArray;r[e+0]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}}class a extends i{constructor(t,e,r,i){super(t,Uint16Array,t.ELEMENT_ARRAY_BUFFER),this.setMaxSize(e*i);for(let t=0;t<i;t++)this.addObject(t*r);this.bindBuffer(),this.bufferData()}addObject(t){}}class n{constructor(t,e,r,i){this._r=t,this._g=e,this._b=r,this._a=i,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,r,i){this.r=t,this.g=e,this.b=r,this.a=i,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),i=parseInt(t.slice(4,6),16);let s=255;return t.length>=8&&(s=parseInt(t.slice(6,8),16)),new n(e,r,i,s)}add(t){return new n(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new n(Math.max(this.r-t.r,0),Math.max(this.g-t.g,0),Math.max(this.b-t.b,0),Math.max(this.a-t.a,0))}}class h{constructor(e,r,i,s){this.attributeLoc={},this.uniformLoc={};const a=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let r="";for(let t=0;t<e;t++)r+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,r+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",r)}return t}(i,e.maxTextureUnits);this.program=((e,r,i)=>{var s=e.createProgram(),a=t(e,r,35633),n=t(e,i,35632);if(!s)throw new Error("Unable to create program shader");return e.attachShader(s,a),e.attachShader(s,n),e.linkProgram(s),s})(e.gl,r,a),this.gl=e.gl,this.attribute=s,this.parseShader(r),this.parseShader(a)}setUniforms(t){const e=this.gl;for(const r in t){const i=t[r],s=this.getUniform(r);if("number"==typeof i)e.uniform1f(s,i);else if(Array.isArray(i))switch(i.length){case 1:Number.isInteger(i[0])?e.uniform1i(s,i[0]):e.uniform1f(s,i[0]);break;case 2:Number.isInteger(i[0])?e.uniform2iv(s,i):e.uniform2fv(s,i);break;case 3:Number.isInteger(i[0])?e.uniform3iv(s,i):e.uniform3fv(s,i);break;case 4:Number.isInteger(i[0])?e.uniform4iv(s,i):e.uniform4fv(s,i);break;case 9:e.uniformMatrix3fv(s,!1,i);break;case 16:e.uniformMatrix4fv(s,!1,i);break;default:console.error(`Unsupported uniform array length for ${r}:`,i.length)}else"boolean"==typeof i?e.uniform1i(s,i?1:0):console.error(`Unsupported uniform type for ${r}:`,typeof i)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const t of r){const r=t.split(" ")[2],i=e.getAttribLocation(this.program,r);-1!=i&&(this.attributeLoc[r]=i)}const i=t.match(/uniform\s+\w+\s+(\w+)/g);if(i)for(const t of i){const r=t.split(" ")[2];this.uniformLoc[r]=e.getUniformLocation(this.program,r)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const r=this.gl;r.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),r.enableVertexAttribArray(e)}}}class o{constructor(t,e){this.usedTextures=[],this.needBind=new Set,this.attribute=e,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new i(t.gl,Float32Array,t.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:t.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...r){const[i,s]=this.rapid.transformPoint(t,e);this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s)}useTexture(t){let e=this.usedTextures.indexOf(t);return-1===e&&(this.usedTextures.length>=this.rapid.maxTextureUnits&&this.render(),this.usedTextures.push(t),e=this.usedTextures.length-1,this.needBind.add(e)),e}enterRegion(t){this.currentShader=null!=t?t:this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer();for(const t of this.attribute)this.currentShader.setAttribute(t);this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(t,e){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new h(this.rapid,t,e,this.attribute)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const t=this.gl;for(const e of this.needBind)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.needBind.clear()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class u extends o{constructor(t){super(t,c),this.vertex=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(t,e,r){this.webglArrayBuffer.resize(3),super.addVertex(t,e),this.webglArrayBuffer.pushUint(r),this.vertex+=1}drawCircle(t,e,r,i){const s=2*Math.PI/30;this.startRender(),this.addVertex(t,e,i);for(let a=0;a<=30;a++){const n=a*s,h=t+r*Math.cos(n),o=e+r*Math.sin(n);this.addVertex(h,o,i)}this.executeRender()}executeRender(){super.executeRender();const t=this.gl;t.drawArrays(t.TRIANGLE_FAN,0,this.vertex),this.vertex=0}}const c=[{name:"aPosition",size:2,type:e,stride:12},{name:"aColor",size:4,type:5121,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class l extends a{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.push(t),this.push(t+3),this.push(t+2),this.push(t),this.push(t+1),this.push(t+2)}}class d extends o{constructor(t){const e=t.gl;super(t,f),this.batchSprite=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}","precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}"),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new l(e,this.MAX_BATCH)}addVertex(t,e,r,i,s,a){super.addVertex(t,e),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(i),this.webglArrayBuffer.push(s),this.webglArrayBuffer.pushUint(a)}renderSprite(t,e,r,i,s,a,n,h,o,u,c){var l;c&&(null===(l=this.currentShader)||void 0===l||l.setUniforms(c)),this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const d=this.useTexture(t),f=h+e,g=o+r,m=i+a,p=s+n;this.addVertex(h,o,i,s,d,u),this.addVertex(f,o,m,s,d,u),this.addVertex(f,g,m,p,d,u),this.addVertex(h,g,i,p,d,u)}executeRender(){super.executeRender();const t=this.gl;t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}}const f=[{name:"aPosition",size:2,type:e,stride:24},{name:"aRegion",size:2,type:e,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:e,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class g{constructor(t){this.cache=new Map,this.render=t}async textureFromUrl(t,e=!1){let r=this.cache.get(t);if(!r){const i=await this.loadImage(t);r=m.fromImageSource(this.render,i,e),this.cache.set(t,r)}return new p(r)}async loadImage(t){return new Promise((e=>{const r=new Image;r.onload=()=>{e(r)},r.src=t}))}}class m{constructor(t,e,r){this.texture=t,this.width=e,this.height=r}static fromImageSource(t,e,r=!1){return new m(function(t,e,r){const i=t.createTexture();if(t.bindTexture(t.TEXTURE_2D,i),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),!i)throw new Error("unable to create texture");return i}(t.gl,e,r),e.width,e.height)}}class p{constructor(t){this.base=t,this.setClipRegion(0,0,t.width,t.height)}setClipRegion(t,e,r,i){this.clipX=t/this.base.width,this.clipY=e/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+i/this.base.width,this.width=r,this.height=i}static fromImageSource(t,e,r=!1){return new p(m.fromImageSource(t,e,r))}static fromUrl(t,e){return t.textures.textureFromUrl(e)}}exports.BaseTexture=m,exports.Color=n,exports.DynamicArrayBuffer=r,exports.GLShader=h,exports.MatrixStack=s,exports.Rapid=class{constructor(t){this.projectionDirty=!0,this.matrixStack=new s,this.textures=new g(this),this.devicePixelRatio=window.devicePixelRatio||1,this.defaultColor=new n(255,255,255,255),this.regions=new Map;const e=(t=>{const e=t.getContext("webgl2")||t.getContext("webgl");if(!e)throw new Error("TODO");return e})(t.canvas);this.gl=e,this.canvas=t.canvas,this.maxTextureUnits=e.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=t.width||this.canvas.width,this.height=t.width||this.canvas.height,this.backgroundColor=t.backgroundColor||new n(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(e)}initWebgl(t){this.resize(this.width,this.height),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",d),this.registerRegion("graphic",u)}registerRegion(t,e){this.regions.set(t,new e(this))}setRegion(t,e){if(t!=this.currentRegionName||e&&e!==this.currentRegion.currentShader){const r=this.regions.get(t);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=t,r.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(t=!0){t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){var t;null===(t=this.currentRegion)||void 0===t||t.render(),this.projectionDirty=!1}renderSprite(t,e=0,r=0,i){if(i instanceof n)return this.renderSprite(t,e,r,{color:i});this.setRegion("sprite",null==i?void 0:i.shader),this.currentRegion.renderSprite(t.base.texture,t.width,t.height,t.clipX,t.clipY,t.clipW,t.clipH,e,r,((null==i?void 0:i.color)||this.defaultColor).uint32,null==i?void 0:i.uniforms)}startGraphicDraw(t){this.setRegion("graphic",t),this.currentRegion.startRender()}addGraphicVertex(t,e,r){this.currentRegion.addVertex(t,e,r.uint32)}endGraphicDraw(){this.currentRegion.render()}resize(t,e){this.width=t,this.height=e;const r=t*this.devicePixelRatio,i=e*this.devicePixelRatio;this.canvas.width=r,this.canvas.height=i,this.gl.viewport(0,0,r,i),this.projection=this.createOrthMatrix(0,t,e,0),this.projectionDirty=!0}clear(){const t=this.gl,e=this.backgroundColor;t.clearColor(e.r,e.g,e.b,e.a),t.clear(t.COLOR_BUFFER_BIT)}createOrthMatrix(t,e,r,i){return new Float32Array([2/(e-t),0,0,0,0,2/(i-r),0,0,0,0,-1,0,-(e+t)/(e-t),-(i+r)/(i-r),0,1])}transformPoint(t,e){return this.matrixStack.apply(t,e)}},exports.Texture=p,exports.TextureCache=g,exports.WebglBufferArray=i,exports.WebglElementBufferArray=a,exports.graphicAttributes=c,exports.spriteAttributes=f;
1
+ "use strict";const t=(t,e,r)=>{const s=t.createShader(r);if(!s)throw new Error("Unable to create webgl shader");t.shaderSource(s,e),t.compileShader(s);if(!t.getShaderParameter(s,t.COMPILE_STATUS)){const r=t.getShaderInfoLog(s);throw console.error("Shader compilation failed:",r),new Error("Unable to compile shader: "+r+e)}return s};const e=5126;class r{constructor(t){this.usedElemNum=0,this.maxElemNum=512,this.bytePerElem=t.BYTES_PER_ELEMENT,this.arrayType=t,this.arraybuffer=new ArrayBuffer(this.maxElemNum*this.bytePerElem),this.typedArray=new t(this.arraybuffer),t==Float32Array&&(this.uint32=new Uint32Array(this.arraybuffer))}clear(){this.usedElemNum=0}resize(t=0){if((t+=this.usedElemNum)>this.maxElemNum){for(;t>this.maxElemNum;)this.maxElemNum<<=1;this.setMaxSize(this.maxElemNum)}}setMaxSize(t=this.maxElemNum){const e=this.typedArray;this.maxElemNum=t,this.arraybuffer=new ArrayBuffer(t*this.bytePerElem),this.typedArray=new this.arrayType(this.arraybuffer),this.uint32&&(this.uint32=new Uint32Array(this.arraybuffer)),this.typedArray.set(e)}push(t){this.typedArray[this.usedElemNum++]=t}pushUint(t){this.uint32[this.usedElemNum++]=t}pop(t){this.usedElemNum-=t}getArray(t=0,e){return null==e?this.typedArray:this.typedArray.subarray(t,e)}get length(){return this.typedArray.length}}class s extends r{constructor(t,e,r=t.ARRAY_BUFFER){super(e),this.dirty=!0,this.webglBufferSize=0,this.gl=t,this.buffer=t.createBuffer(),this.type=r}push(t){super.push(t),this.dirty=!0}bindBuffer(){this.gl.bindBuffer(this.type,this.buffer)}bufferData(){if(this.dirty){const t=this.gl;this.maxElemNum>this.webglBufferSize?(t.bufferData(this.type,this.getArray(),t.STATIC_DRAW),this.webglBufferSize=this.maxElemNum):t.bufferSubData(this.type,0,this.getArray(0,this.usedElemNum)),this.dirty=!1}}}class i extends r{constructor(){super(Float32Array)}pushMat(){const t=this.usedElemNum-6,e=this.typedArray;this.resize(6),this.push(e[t+0]),this.push(e[t+1]),this.push(e[t+2]),this.push(e[t+3]),this.push(e[t+4]),this.push(e[t+5])}popMat(){this.pop(6)}pushIdentity(){this.resize(6),this.push(1),this.push(0),this.push(0),this.push(1),this.push(0),this.push(0)}translate(t,e){if(t instanceof a)return this.translate(t.x,t.y);const r=this.usedElemNum-6,s=this.typedArray;s[r+4]=s[r+0]*t+s[r+2]*e+s[r+4],s[r+5]=s[r+1]*t+s[r+3]*e+s[r+5]}rotate(t){const e=this.usedElemNum-6,r=this.typedArray,s=Math.cos(t),i=Math.sin(t),n=r[e+0],h=r[e+1],a=r[e+2],o=r[e+3];r[e+0]=n*s-h*i,r[e+1]=n*i+h*s,r[e+2]=a*s-o*i,r[e+3]=a*i+o*s}scale(t,e){if(t instanceof a)return this.scale(t.x,t.y);const r=this.usedElemNum-6,s=this.typedArray;s[r+0]=s[r+0]*t,s[r+1]=s[r+1]*t,s[r+2]=s[r+2]*e,s[r+3]=s[r+3]*e}apply(t,e){if(t instanceof a)return new a(...this.apply(t.x,t.y));const r=this.usedElemNum-6,s=this.typedArray;return[s[r+0]*t+s[r+2]*e+s[r+4],s[r+1]*t+s[r+3]*e+s[r+5]]}getInverse(){const t=this.usedElemNum-6,e=this.typedArray,r=e[t+0],s=e[t+1],i=e[t+2],n=e[t+3],h=e[t+4],a=e[t+5],o=r*n-s*i;return new Float32Array([n/o,-s/o,-i/o,r/o,(i*a-n*h)/o,(s*h-r*a)/o])}getTransform(){const t=this.usedElemNum-6,e=this.typedArray;return new Float32Array([e[t+0],e[t+1],e[t+2],e[t+3],e[t+4],e[t+5]])}setTransform(t){const e=this.usedElemNum-6,r=this.typedArray;r[e+0]=t[0],r[e+1]=t[1],r[e+2]=t[2],r[e+3]=t[3],r[e+4]=t[4],r[e+5]=t[5]}}class n extends s{constructor(t,e,r,s){super(t,Uint16Array,t.ELEMENT_ARRAY_BUFFER),this.setMaxSize(e*s);for(let t=0;t<s;t++)this.addObject(t*r);this.bindBuffer(),this.bufferData()}addObject(t){}}class h{constructor(t,e,r,s){this._r=t,this._g=e,this._b=r,this._a=s,this.updateUint()}get r(){return this._r}set r(t){this._r=t,this.updateUint()}get g(){return this._g}set g(t){this._g=t,this.updateUint()}get b(){return this._b}set b(t){this._b=t,this.updateUint()}get a(){return this._a}set a(t){this._a=t,this.updateUint()}updateUint(){this.uint32=(this._a<<24|this._b<<16|this._g<<8|this._r)>>>0}setRGBA(t,e,r,s){this.r=t,this.g=e,this.b=r,this.a=s,this.updateUint()}copy(t){this.setRGBA(t.r,t.g,t.b,t.a)}equals(t){return t.r===this.r&&t.g===this.g&&t.b===this.b&&t.a===this.a}static fromHex(t){t.startsWith("#")&&(t=t.slice(1));const e=parseInt(t.slice(0,2),16),r=parseInt(t.slice(2,4),16),s=parseInt(t.slice(4,6),16);let i=255;return t.length>=8&&(i=parseInt(t.slice(6,8),16)),new h(e,r,s,i)}add(t){return new h(Math.min(this.r+t.r,255),Math.min(this.g+t.g,255),Math.min(this.b+t.b,255),Math.min(this.a+t.a,255))}subtract(t){return new h(Math.max(this.r-t.r,0),Math.max(this.g-t.g,0),Math.max(this.b-t.b,0),Math.max(this.a-t.a,0))}}class a{constructor(t,e){this.x=void 0!==t?t:0,this.y=void 0!==e?e:0}scalarMult(t){return this.x*=t,this.y*=t,this}perpendicular(){const t=this.x;return this.x=-this.y,this.y=t,this}invert(){return this.x=-this.x,this.y=-this.y,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}normalize(){const t=this.length();return this.x/=t,this.y/=t,this}angle(){return this.y/this.x}static Angle(t,e){return Math.atan2(e.x-t.x,e.y-t.y)}static Add(t,e){return new a(t.x+e.x,t.y+e.y)}static Sub(t,e){return new a(t.x-e.x,t.y-e.y)}static Middle(t,e){return a.Add(t,e).scalarMult(.5)}}class o{constructor(t){this.cache=new Map,this.render=t}async textureFromUrl(t,e=!1){let r=this.cache.get(t);if(!r){const s=await this.loadImage(t);r=u.fromImageSource(this.render,s,e),this.cache.set(t,r)}return new l(r)}async loadImage(t){return new Promise((e=>{const r=new Image;r.onload=()=>{e(r)},r.src=t}))}createText(t){return new d(this.render,t)}}class u{constructor(t,e,r){this.texture=t,this.width=e,this.height=r}static fromImageSource(t,e,r=!1){return new u(function(t,e,r){const s=t.createTexture();if(t.bindTexture(t.TEXTURE_2D,s),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r?t.LINEAR:t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),!s)throw new Error("unable to create texture");return s}(t.gl,e,r),e.width,e.height)}}class l{constructor(t){this.scale=1,this.setBase(t)}setBase(t,e=1){t&&(this.base=t,this.setClipRegion(0,0,t.width*e,t.height*e))}setClipRegion(t,e,r,s){this.base&&(this.clipX=t/this.base.width,this.clipY=e/this.base.width,this.clipW=this.clipX+r/this.base.width,this.clipH=this.clipY+s/this.base.height,this.width=r*this.scale,this.height=s*this.scale)}static fromImageSource(t,e,r=!1){return new l(u.fromImageSource(t,e,r))}static fromUrl(t,e){return t.textures.textureFromUrl(e)}}class d extends l{constructor(t,e){super(),this.scale=.5,this.rapid=t,this.options=e,this.text=e.text||"",this.updateTextImage()}updateTextImage(){const t=this.createTextCanvas();this.setBase(u.fromImageSource(this.rapid,t,!0))}createTextCanvas(){const t=document.createElement("canvas"),e=t.getContext("2d");if(!e)throw new Error("Failed to get canvas context");e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";const r=this.text.split("\n");let s=0,i=0;for(const t of r){const r=e.measureText(t);s=Math.max(s,r.width),i+=this.options.fontSize||16}t.width=2*s,t.height=2*i,e.scale(2,2),e.font=`${this.options.fontSize||16}px ${this.options.fontFamily||"Arial"}`,e.fillStyle=this.options.color||"#000",e.textAlign=this.options.textAlign||"left",e.textBaseline=this.options.textBaseline||"top";let n=0;for(const t of r)e.fillText(t,0,n),n+=this.options.fontSize||16;return t}setText(t){this.text=t,this.updateTextImage()}}class c{constructor(e,r,s){this.attributeLoc={},this.uniformLoc={};const i=function(t,e){if(t.includes("%TEXTURE_NUM%")&&(t=t.replace("%TEXTURE_NUM%",e.toString())),t.includes("%GET_COLOR%")){let r="";for(let t=0;t<e;t++)r+=0==t?`if(vTextureId == ${t}.0)`:t==e-1?"else":`else if(vTextureId == ${t}.0)`,r+=`{color = texture2D(uTextures[${t}], vRegion);}`;t=t.replace("%GET_COLOR%",r)}return t}(s,e.maxTextureUnits);this.program=((e,r,s)=>{var i=e.createProgram(),n=t(e,r,35633),h=t(e,s,35632);if(!i)throw new Error("Unable to create program shader");return e.attachShader(i,n),e.attachShader(i,h),e.linkProgram(i),i})(e.gl,r,i),this.gl=e.gl,this.parseShader(r),this.parseShader(i)}setUniforms(t,e){var r;const s=this.gl;for(const i in t){const n=t[i],h=this.getUniform(i);if(n instanceof l&&(null===(r=n.base)||void 0===r?void 0:r.texture))s.activeTexture(s.TEXTURE0+e),s.bindTexture(s.TEXTURE_2D,n.base.texture),s.uniform1i(h,e),e+=1;else if("number"==typeof n)s.uniform1f(h,n);else if(Array.isArray(n))switch(n.length){case 1:Number.isInteger(n[0])?s.uniform1i(h,n[0]):s.uniform1f(h,n[0]);break;case 2:Number.isInteger(n[0])?s.uniform2iv(h,n):s.uniform2fv(h,n);break;case 3:Number.isInteger(n[0])?s.uniform3iv(h,n):s.uniform3fv(h,n);break;case 4:Number.isInteger(n[0])?s.uniform4iv(h,n):s.uniform4fv(h,n);break;case 9:s.uniformMatrix3fv(h,!1,n);break;case 16:s.uniformMatrix4fv(h,!1,n);break;default:console.error(`Unsupported uniform array length for ${i}:`,n.length)}else"boolean"==typeof n?s.uniform1i(h,n?1:0):console.error(`Unsupported uniform type for ${i}:`,typeof n)}}getUniform(t){return this.uniformLoc[t]}use(){this.gl.useProgram(this.program)}parseShader(t){const e=this.gl,r=t.match(/attribute\s+\w+\s+(\w+)/g);if(r)for(const t of r){const r=t.split(" ")[2],s=e.getAttribLocation(this.program,r);-1!=s&&(this.attributeLoc[r]=s)}const s=t.match(/uniform\s+\w+\s+(\w+)/g);if(s)for(const t of s){const r=t.split(" ")[2];this.uniformLoc[r]=e.getUniformLocation(this.program,r)}}setAttribute(t){const e=this.attributeLoc[t.name];if(void 0!==e){const r=this.gl;r.vertexAttribPointer(e,t.size,t.type,t.normalized||!1,t.stride,t.offset||0),r.enableVertexAttribArray(e)}}}class p{constructor(t,e){this.usedTextures=[],this.needBind=new Set,this.attribute=e,this.rapid=t,this.gl=t.gl,this.webglArrayBuffer=new s(t.gl,Float32Array,t.gl.ARRAY_BUFFER),this.TEXTURE_UNITS_ARRAY=Array.from({length:t.maxTextureUnits},((t,e)=>e))}addVertex(t,e,...r){const[s,i]=this.rapid.transformPoint(t,e);this.webglArrayBuffer.push(s),this.webglArrayBuffer.push(i)}useTexture(t){let e=this.usedTextures.indexOf(t);return-1===e&&(this.usedTextures.length>=this.rapid.maxTextureUnits&&this.render(),this.usedTextures.push(t),e=this.usedTextures.length-1,this.needBind.add(e)),e}enterRegion(t){this.currentShader=null!=t?t:this.defaultShader,this.currentShader.use(),this.initializeForNextRender(),this.webglArrayBuffer.bindBuffer();for(const t of this.attribute)this.currentShader.setAttribute(t);this.gl.uniformMatrix4fv(this.currentShader.uniformLoc.uProjectionMatrix,!1,this.rapid.projection)}exitRegion(){}initDefaultShader(t,e){this.webglArrayBuffer.bindBuffer(),this.defaultShader=new c(this.rapid,t,e)}render(){this.executeRender(),this.initializeForNextRender()}executeRender(){this.webglArrayBuffer.bufferData();const t=this.gl;for(const e of this.needBind)t.activeTexture(t.TEXTURE0+e),t.bindTexture(t.TEXTURE_2D,this.usedTextures[e]);this.needBind.clear()}initializeForNextRender(){this.webglArrayBuffer.clear(),this.usedTextures=[]}}class f extends p{constructor(t){super(t,x),this.vertex=0,this.drawType=t.gl.TRIANGLE_FAN,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec4 aColor;\r\nvarying vec4 vColor;\r\nuniform mat4 uProjectionMatrix;\r\nuniform vec4 uColor;\r\n\r\nvoid main(void) {\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n vColor = aColor;\r\n}\r\n","precision mediump float;\r\n\r\nvarying vec4 vColor;\r\nvoid main(void) {\r\n gl_FragColor = vColor;//vColor;\r\n}\r\n")}startRender(){this.vertex=0,this.webglArrayBuffer.clear()}addVertex(t,e,r){this.webglArrayBuffer.resize(3),super.addVertex(t,e),this.webglArrayBuffer.pushUint(r),this.vertex+=1}drawCircle(t,e,r,s){const i=2*Math.PI/30;this.startRender(),this.addVertex(t,e,s);for(let n=0;n<=30;n++){const h=n*i,a=t+r*Math.cos(h),o=e+r*Math.sin(h);this.addVertex(a,o,s)}this.executeRender()}executeRender(){super.executeRender();this.gl.drawArrays(this.drawType,0,this.vertex),this.drawType=this.rapid.gl.TRIANGLE_FAN,this.vertex=0}}const x=[{name:"aPosition",size:2,type:e,stride:12},{name:"aColor",size:4,type:5121,stride:12,offset:2*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];class g extends n{constructor(t,e){super(t,6,4,e)}addObject(t){super.addObject(),this.push(t),this.push(t+3),this.push(t+2),this.push(t),this.push(t+1),this.push(t+2)}}class m extends p{constructor(t){const e=t.gl;super(t,y),this.batchSprite=0,this.initDefaultShader("precision mediump float;\r\n\r\nattribute vec2 aPosition;\r\nattribute vec2 aRegion;\r\nattribute float aTextureId;\r\nattribute vec4 aColor;\r\n\r\nuniform mat4 uProjectionMatrix;\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vRegion = aRegion;\r\n vTextureId = aTextureId;\r\n vColor = aColor;\r\n gl_Position = uProjectionMatrix * vec4(aPosition, 0.0, 1.0);\r\n}","precision mediump float;\r\nuniform sampler2D uTextures[%TEXTURE_NUM%];\r\n\r\nvarying vec2 vRegion;\r\nvarying float vTextureId;\r\nvarying vec4 vColor;\r\n\r\nvoid main(void) {\r\n vec4 color;\r\n %GET_COLOR%\r\n\r\n gl_FragColor = color*vColor;\r\n}"),this.MAX_BATCH=Math.floor(16384),this.indexBuffer=new g(e,this.MAX_BATCH)}addVertex(t,e,r,s,i,n){super.addVertex(t,e),this.webglArrayBuffer.push(r),this.webglArrayBuffer.push(s),this.webglArrayBuffer.push(i),this.webglArrayBuffer.pushUint(n)}renderSprite(t,e,r,s,i,n,h,a,o,u,l){var d;l&&(null===(d=this.currentShader)||void 0===d||d.setUniforms(l,1)),this.batchSprite>=this.MAX_BATCH&&this.render(),this.batchSprite++,this.webglArrayBuffer.resize(24);const c=this.useTexture(t),p=a+e,f=o+r,x=s+n,g=i+h;this.addVertex(a,o,s,i,c,u),this.addVertex(p,o,x,i,c,u),this.addVertex(p,f,x,g,c,u),this.addVertex(a,f,s,g,c,u)}executeRender(){super.executeRender();const t=this.gl;t.drawElements(t.TRIANGLES,6*this.batchSprite,t.UNSIGNED_SHORT,0)}enterRegion(t){super.enterRegion(t),this.indexBuffer.bindBuffer(),this.gl.uniform1iv(this.currentShader.uniformLoc.uTextures,this.TEXTURE_UNITS_ARRAY)}initializeForNextRender(){super.initializeForNextRender(),this.batchSprite=0}}const y=[{name:"aPosition",size:2,type:e,stride:24},{name:"aRegion",size:2,type:e,stride:24,offset:2*Float32Array.BYTES_PER_ELEMENT},{name:"aTextureId",size:1,type:e,stride:24,offset:4*Float32Array.BYTES_PER_ELEMENT},{name:"aColor",size:4,type:5121,stride:24,offset:5*Float32Array.BYTES_PER_ELEMENT,normalized:!0}];var T,E;exports.JoinTyps=void 0,(T=exports.JoinTyps||(exports.JoinTyps={}))[T.BEVEL=0]="BEVEL",T[T.ROUND=1]="ROUND",T[T.MITER=2]="MITER",exports.CapTyps=void 0,(E=exports.CapTyps||(exports.CapTyps={}))[E.BUTT=0]="BUTT",E[E.ROUND=1]="ROUND",E[E.SQUARE=2]="SQUARE";const b=1e-4,A=(t,e,r,s)=>{s.push(t),s.push(a.Add(t,r)),s.push(a.Add(e,r)),s.push(e),s.push(a.Add(e,r)),s.push(t)},R=(t,e,r,s,i)=>{const n=a.Sub(t,e).length();let h=Math.atan2(r.y-t.y,r.x-t.x),o=Math.atan2(e.y-t.y,e.x-t.x);const u=h;o>h?o-h>=Math.PI-b&&(o-=2*Math.PI):h-o>=Math.PI-b&&(h-=2*Math.PI);let l=o-h;if(Math.abs(l)>=Math.PI-b&&Math.abs(l)<=Math.PI+b){const e=a.Sub(t,s);0===e.x?e.y>0&&(l=-l):e.x>=-1e-4&&(l=-l)}const d=(Math.abs(l*n)/7>>0)+1,c=l/d;for(let e=0;e<d;e++)i.push(new a(t.x,t.y)),i.push(new a(t.x+n*Math.cos(u+c*e),t.y+n*Math.sin(u+c*e))),i.push(new a(t.x+n*Math.cos(u+c*(1+e)),t.y+n*Math.sin(u+c*(1+e))))},S=(t,e,r,s,i,n,h)=>{const o=a.Sub(e,t).perpendicular(),u=a.Sub(r,e).perpendicular();((t,e,r)=>(e.x-t.x)*(r.y-t.y)-(r.x-t.x)*(e.y-t.y))(t,e,r)>0&&(o.invert(),u.invert()),o.normalize().scalarMult(i),u.normalize().scalarMult(i);const l=((t,e,r,s)=>{const i=e.y-t.y,n=t.x-e.x,h=s.y-r.y,o=r.x-s.x,u=i*o-h*n;if(u>-1e-4&&u<b)return null;{const e=i*t.x+n*t.y,s=h*r.x+o*r.y;return new a((o*e-n*s)/u,(i*s-h*e)/u)}})(a.Add(o,t),a.Add(o,e),a.Add(u,r),a.Add(u,e));let d=null,c=Number.MAX_VALUE;l&&(d=a.Sub(l,e),c=d.length());const p=c/i|0,f=a.Sub(t,e).length(),x=a.Sub(e,r).length();if(c>f||c>x)s.push(a.Add(t,o)),s.push(a.Sub(t,o)),s.push(a.Add(e,o)),s.push(a.Sub(t,o)),s.push(a.Add(e,o)),s.push(a.Sub(e,o)),n===exports.JoinTyps.ROUND?R(e,a.Add(e,o),a.Add(e,u),r,s):n===exports.JoinTyps.BEVEL||n===exports.JoinTyps.MITER&&p>=h?(s.push(e),s.push(a.Add(e,o)),s.push(a.Add(e,u))):n===exports.JoinTyps.MITER&&p<h&&l&&(s.push(a.Add(e,o)),s.push(e),s.push(l),s.push(a.Add(e,u)),s.push(e),s.push(l)),s.push(a.Add(r,u)),s.push(a.Sub(e,u)),s.push(a.Add(e,u)),s.push(a.Add(r,u)),s.push(a.Sub(e,u)),s.push(a.Sub(r,u));else{if(s.push(a.Add(t,o)),s.push(a.Sub(t,o)),s.push(a.Sub(e,d)),s.push(a.Add(t,o)),s.push(a.Sub(e,d)),s.push(a.Add(e,o)),n===exports.JoinTyps.ROUND){const t=a.Add(e,o),r=a.Add(e,u),i=a.Sub(e,d),n=e;s.push(t),s.push(n),s.push(i),R(n,t,r,i,s),s.push(n),s.push(r),s.push(i)}else(n===exports.JoinTyps.BEVEL||n===exports.JoinTyps.MITER&&p>=h)&&(s.push(a.Add(e,o)),s.push(a.Add(e,u)),s.push(a.Sub(e,d))),n===exports.JoinTyps.MITER&&p<h&&(s.push(l),s.push(a.Add(e,o)),s.push(a.Add(e,u)));s.push(a.Add(r,u)),s.push(a.Sub(e,d)),s.push(a.Add(e,u)),s.push(a.Add(r,u)),s.push(a.Sub(e,d)),s.push(a.Sub(r,u))}};exports.BaseTexture=u,exports.Color=h,exports.DynamicArrayBuffer=r,exports.GLShader=c,exports.MatrixStack=i,exports.Rapid=class{constructor(t){this.projectionDirty=!0,this.matrixStack=new i,this.textures=new o(this),this.devicePixelRatio=window.devicePixelRatio||1,this.defaultColor=new h(255,255,255,255),this.defaultColorBlack=new h(0,0,0,255),this.regions=new Map;const e=(t=>{const e=t.getContext("webgl2")||t.getContext("webgl");if(!e)throw new Error("TODO");return e})(t.canvas);this.gl=e,this.canvas=t.canvas,this.maxTextureUnits=e.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS),this.width=t.width||this.canvas.width,this.height=t.width||this.canvas.height,this.backgroundColor=t.backgroundColor||new h(255,255,255,255),this.registerBuildInRegion(),this.initWebgl(e)}initWebgl(t){this.resize(this.width,this.height),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA)}registerBuildInRegion(){this.registerRegion("sprite",m),this.registerRegion("graphic",f)}registerRegion(t,e){this.regions.set(t,new e(this))}setRegion(t,e){if(t!=this.currentRegionName||e&&e!==this.currentRegion.currentShader){const r=this.regions.get(t);this.currentRegion&&(this.currentRegion.render(),this.currentRegion.exitRegion()),this.currentRegion=r,this.currentRegionName=t,r.enterRegion(e)}}save(){this.matrixStack.pushMat()}restore(){this.matrixStack.popMat()}startRender(t=!0){t&&this.matrixStack.clear(),this.matrixStack.pushIdentity(),this.currentRegion=void 0,this.currentRegionName=void 0}endRender(){var t;null===(t=this.currentRegion)||void 0===t||t.render(),this.projectionDirty=!1}renderSprite(t,e=0,r=0,s){if(t.base){if(s instanceof h)return this.renderSprite(t,e,r,{color:s});this.setRegion("sprite",null==s?void 0:s.shader),this.currentRegion.renderSprite(t.base.texture,t.width,t.height,t.clipX,t.clipY,t.clipW,t.clipH,e,r,((null==s?void 0:s.color)||this.defaultColor).uint32,null==s?void 0:s.uniforms)}}renderLine(t=0,e=0,r){const s=((t,e)=>{if(t.length<2)return[];let r=e.cap||exports.CapTyps.BUTT,s=e.join||exports.JoinTyps.BEVEL,i=(e.width||1)/2,n=e.miterLimit||10,h=[],o=[];if(2===t.length)s=exports.JoinTyps.BEVEL,S(t[0],a.Middle(t[0],t[1]),t[1],h,i,s,n);else{for(let e=0;e<t.length-1;e++)0===e?o.push(t[0]):e===t.length-2?o.push(t[t.length-1]):o.push(a.Middle(t[e],t[e+1]));for(let e=1;e<o.length;e++)S(o[e-1],t[e],o[e],h,i,s,n)}if(r===exports.CapTyps.ROUND){let e=h[0],r=h[1],s=t[1],i=h[h.length-1],n=h[h.length-3],a=t[t.length-2];R(t[0],e,r,s,h),R(t[t.length-1],i,n,a,h)}else if(r===exports.CapTyps.SQUARE){let e=h[h.length-1],r=h[h.length-3];A(h[0],h[1],a.Sub(t[0],t[1]).normalize().scalarMult(a.Sub(t[0],h[0]).length()),h),A(e,r,a.Sub(t[t.length-1],t[t.length-2]).normalize().scalarMult(a.Sub(r,t[t.length-1]).length()),h)}return h})(r.points,r);this.renderGraphic(t,e,s,r.color,this.gl.TRIANGLES)}renderGraphic(t=0,e=0,r,s,i){this.startGraphicDraw(),i&&(this.currentRegion.drawType=i),r.forEach((r=>{this.addGraphicVertex(r.x+t,r.y+e,s||this.defaultColorBlack)})),this.endGraphicDraw()}startGraphicDraw(t){this.setRegion("graphic",t),this.currentRegion.startRender()}addGraphicVertex(t,e,r){if(t instanceof a)return this.addGraphicVertex(t.x,t.y,e);this.currentRegion.addVertex(t,e,r.uint32)}endGraphicDraw(){this.currentRegion.render()}resize(t,e){this.width=t,this.height=e;const r=t*this.devicePixelRatio,s=e*this.devicePixelRatio;this.canvas.width=r,this.canvas.height=s,this.gl.viewport(0,0,r,s),this.projection=this.createOrthMatrix(0,t,e,0),this.projectionDirty=!0}clear(){const t=this.gl,e=this.backgroundColor;t.clearColor(e.r,e.g,e.b,e.a),t.clear(t.COLOR_BUFFER_BIT)}createOrthMatrix(t,e,r,s){return new Float32Array([2/(e-t),0,0,0,0,2/(s-r),0,0,0,0,-1,0,-(e+t)/(e-t),-(s+r)/(s-r),0,1])}transformPoint(t,e){return this.matrixStack.apply(t,e)}},exports.SCALEFACTOR=2,exports.Text=d,exports.Texture=l,exports.TextureCache=o,exports.Vec2=a,exports.WebglBufferArray=s,exports.WebglElementBufferArray=n,exports.graphicAttributes=x,exports.spriteAttributes=y;
@@ -2,6 +2,7 @@ import { Rapid } from "..";
2
2
  import RenderRegion from "./region";
3
3
  declare class GraphicRegion extends RenderRegion {
4
4
  private vertex;
5
+ drawType: number;
5
6
  constructor(rapid: Rapid);
6
7
  startRender(): void;
7
8
  addVertex(x: number, y: number, color: number): void;
package/dist/render.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { IRapiadOptions, IRenderSpriteOptions, WebGLContext } from "./interface";
2
- import { Color, MatrixStack } from "./math";
1
+ import { IRapiadOptions, IRenderLineOptions, IRenderSpriteOptions, WebGLContext } from "./interface";
2
+ import { Color, MatrixStack, Vec2 } from "./math";
3
3
  import RenderRegion from "./regions/region";
4
4
  import { Texture, TextureCache } from "./texture";
5
5
  import GLShader from "./webgl/glshader";
@@ -19,6 +19,7 @@ declare class Rapid {
19
19
  readonly devicePixelRatio: number;
20
20
  readonly maxTextureUnits: number;
21
21
  private readonly defaultColor;
22
+ private readonly defaultColorBlack;
22
23
  private currentRegion?;
23
24
  private currentRegionName?;
24
25
  private regions;
@@ -73,6 +74,8 @@ declare class Rapid {
73
74
  * @param options - Rendering options including color and custom shader.
74
75
  */
75
76
  renderSprite(texture: Texture, offsetX?: number, offsetY?: number, options?: IRenderSpriteOptions | Color): void;
77
+ renderLine(offsetX: number | undefined, offsetY: number | undefined, options: IRenderLineOptions): void;
78
+ renderGraphic(offsetX: number | undefined, offsetY: number | undefined, vertexs: Vec2[], color?: Color, drawType?: number): void;
76
79
  /**
77
80
  * Starts a graphic drawing process with an optional custom shader.
78
81
  * @param customShader - An optional custom shader to use.
@@ -84,7 +87,7 @@ declare class Rapid {
84
87
  * @param y - The Y position of the vertex.
85
88
  * @param color - The color of the vertex.
86
89
  */
87
- addGraphicVertex(x: number, y: number, color: Color): void;
90
+ addGraphicVertex(x: number | Vec2, y?: number | Color, color?: Color): void;
88
91
  /**
89
92
  * Ends the graphic drawing process by rendering the current graphic region.
90
93
  */
@@ -114,6 +117,6 @@ declare class Rapid {
114
117
  * @param y - The Y coordinate of the point.
115
118
  * @returns The transformed point as an array `[newX, newY]`.
116
119
  */
117
- transformPoint(x: number, y: number): number[];
120
+ transformPoint(x: number, y: number): number[] | Vec2;
118
121
  }
119
122
  export default Rapid;
package/dist/texture.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Rapid from "./render";
2
- import { Images } from "./interface";
2
+ import { Images, ITextOptions } from "./interface";
3
3
  /**
4
4
  * texture manager
5
5
  */
@@ -16,6 +16,7 @@ declare class TextureCache {
16
16
  */
17
17
  textureFromUrl(url: string, antialias?: boolean): Promise<Texture>;
18
18
  loadImage(url: string): Promise<HTMLImageElement>;
19
+ createText(options: ITextOptions): Text;
19
20
  }
20
21
  /**
21
22
  * Each {@link Texture} references a baseTexture, and different textures may have the same baseTexture
@@ -31,7 +32,7 @@ declare class Texture {
31
32
  /**
32
33
  * Reference to the {@link BaseTexture} used by this texture.
33
34
  */
34
- base: BaseTexture;
35
+ base?: BaseTexture;
35
36
  /**
36
37
  * The x-coordinate of the top-left corner of the clipped region.
37
38
  */
@@ -56,11 +57,13 @@ declare class Texture {
56
57
  * The height of the texture.
57
58
  */
58
59
  height: number;
60
+ scale: number;
59
61
  /**
60
62
  * Creates a new `Texture` instance with the specified base texture reference.
61
63
  * @param base - The {@link BaseTexture} to be used by the texture.
62
64
  */
63
- constructor(base: BaseTexture);
65
+ constructor(base?: BaseTexture);
66
+ setBase(base?: BaseTexture, scale?: number): void;
64
67
  /**
65
68
  * Sets the region of the texture to be used for rendering.
66
69
  * @param x - The x-coordinate of the top-left corner of the region.
@@ -85,4 +88,23 @@ declare class Texture {
85
88
  */
86
89
  static fromUrl(rapid: Rapid, url: string): Promise<Texture>;
87
90
  }
88
- export { Texture, BaseTexture, TextureCache };
91
+ export declare const SCALEFACTOR = 2;
92
+ declare class Text extends Texture {
93
+ private options;
94
+ private rapid;
95
+ scale: number;
96
+ text: string;
97
+ /**
98
+ * Creates a new `Text` instance.
99
+ * @param options - The options for rendering the text, such as font, size, color, etc.
100
+ */
101
+ constructor(rapid: Rapid, options: ITextOptions);
102
+ private updateTextImage;
103
+ /**
104
+ * Creates a canvas with the text rendered on it.
105
+ * @returns A `Canvas` element with the rendered text.
106
+ */
107
+ private createTextCanvas;
108
+ setText(text: string): void;
109
+ }
110
+ export { Text, Texture, BaseTexture, TextureCache };
@@ -4,10 +4,9 @@ declare class GLShader {
4
4
  attributeLoc: Record<string, number>;
5
5
  uniformLoc: Record<string, WebGLUniformLocation>;
6
6
  program: WebGLProgram;
7
- attribute: IAttribute[];
8
7
  private gl;
9
- constructor(rapid: Rapid, vs: string, fs: string, attribute: IAttribute[]);
10
- setUniforms(uniforms: UniformType): void;
8
+ constructor(rapid: Rapid, vs: string, fs: string);
9
+ setUniforms(uniforms: UniformType, usedTextureUnit: number): void;
11
10
  private getUniform;
12
11
  use(): void;
13
12
  parseShader(shader: string): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rapid-render",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"