rapid-render 0.0.9 → 0.1.0

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
@@ -2,27 +2,25 @@
2
2
 
3
3
  A highly efficient and lightweight WebGL renderer capable of rendering 10k sprites at 60fps.
4
4
 
5
- * `Intel(r) UHD graphic 620` can handle 30k sprites at a stable 60fps (integrated graphics)
6
- * `NVIDIA GeForce GTX 1050 with Max-Q Design` can handle 60k sprites at a stable 60fps (discrete graphics)
7
-
8
- (32 * 32 texture sprites bouncing)
5
+ ## [API Docs](https://nightre.github.io/Rapid.js/docs/)
9
6
 
10
7
  [demo](https://nightre.github.io/Rapid.js/demo/) ( [source code](./demo/index.js) )
11
8
 
12
- [matrix stack demo](https://nightre.github.io/Rapid.js/demo/matrix_stack.html) ( [source code](./demo/matrix_stack.js) )
9
+ [render demo](https://nightre.github.io/Rapid.js/demo/matrix_stack.html) ( [source code](./demo/matrix_stack.js) )
13
10
 
14
11
  [custom shader demo](https://nightre.github.io/Rapid.js/demo/custom-shader.html) ( [source code](./demo/custom-shader.js) )
15
12
 
16
13
 
17
14
 
18
- # Features:
19
- * Fast rendering ( capable of rendering 10,000 sprites at 60fps )
20
- * Multi-texture support ( Batch rendering based on the GPU's maximum texture units )
21
- * Graphic
22
- * Matrix stack
23
- * Text
24
- * Line
25
- * custom Shader
15
+ # Features
16
+ * **Fast Rendering**: Render 10,000 sprites at 60fps
17
+ * **Multi-Texture Support**: Batch rendering using GPU's maximum texture units
18
+ * **Graphics Drawing**
19
+ * **Matrix Stack**
20
+ * **Text Rendering**
21
+ * **Line Drawing**
22
+ * **Custom Shaders**
23
+ * **Texture Clipping**
26
24
 
27
25
  # Install
28
26
 
@@ -48,51 +46,51 @@ import { Rapid } from "rapid-render"
48
46
  let rapid = new Rapid({
49
47
  canvas: document.getElementById("game"),
50
48
  backgroundColor: Color.fromHex("FFFFFF")
51
- })
49
+ });
52
50
 
53
- // Creating textures
54
- const cat = await rapid.textures.textureFromUrl("./cat.png")
55
- const plane = await rapid.textures.textureFromUrl("./plane.png")
56
- // or
57
- // Texture.fromImageSource(img)
58
- // Texture.fromUrl(url)
59
- // set clip
60
- cat.setClipRegion(
61
- 10,10 // top-left corner of the clipped region.
62
- 50,50 // size
63
- )
51
+ // Create texture
52
+ const cat = await rapid.textures.textureFromUrl("./cat.png");
64
53
  // R G B A
65
- const color = new Color(255,255,255,255)
66
- // or Color.fromHex
67
- // Called before starting rendering
68
- rapid.startRender()
54
+ const color = new Color(255, 255, 255, 255); // Or use Color.fromHex
69
55
 
56
+ // Call before rendering
57
+ rapid.startRender();
58
+
59
+ // Render here...
60
+
61
+ // Call after rendering
62
+ rapid.endRender();
63
+
64
+ // Set canvas size
65
+ rapid.resize(100, 100);
66
+ ```
67
+
68
+ # Render
69
+
70
+ ```js
71
+ const text = rapid.textures.createText({ text: "Hello!", fontSize: 30 })
70
72
 
71
73
  rapid.save() // Save state
72
74
  rapid.matrixStack.translate(0,0)
73
75
  rapid.matrixStack.scale(1)
74
76
  rapid.matrixStack.rotate(0)
75
77
 
76
- // texture offset color
77
- rapid.renderSprite(cat, 0, 0, color) // draw Sprite
78
- // or rapid.renderSprite(cat, 0, 0, { color })
79
- rapid.restore() // back to the previous saved state
80
- // draw graphic
81
- // vertices can have different colors
82
- const path = Vec2.FormArray([[0, 0], [100, 0], [100, 100]]) //[new Vec2(0, 0), new Vec2(100, 0), new Vec2(100, 100)]
78
+ // Render Sprit
79
+ rapid.renderSprite(cat, 0, 0, color) // or rapid.renderSprite(cat, 0, 0, { color })
80
+
81
+ // Rendr Graphic
82
+ const path = Vec2.FormArray([[0, 0], [100, 0], [100, 100]])
83
83
  rapid.renderGraphic(0,0,{points:path, color:green})
84
84
  // or
85
85
  // rapid.startGraphicDraw()
86
86
  // rapid.addGraphicVertex(0, 0, color)
87
- // rapid.addGraphicVertex(100, 0, color)
88
- // rapid.addGraphicVertex(100, 100, color)
89
87
  // rapid.endGraphicDraw()
90
88
 
91
- // Called after rendering
92
- rapid.endRender()
89
+ // Render Text
90
+ rapid.renderSprite(text, 200, 0)
91
+ text.setText("time:" + Math.round(time))
93
92
 
94
- // set the size
95
- rapid.resize(100,100)
93
+ rapid.restore() // back to the previous saved state
96
94
  ```
97
95
 
98
96
  # Custom Shader
package/dist/math.d.ts CHANGED
@@ -92,9 +92,25 @@ export declare class MatrixStack extends DynamicArrayBuffer {
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
94
  scale(x: number | Vec2, y?: number): void;
95
+ /**
96
+ * Transforms a point by applying the current matrix stack.
97
+ * @returns The transformed point as an array `[newX, newY]`.
98
+ */
95
99
  apply(x: number | Vec2, y: number): Vec2 | number[];
100
+ /**
101
+ * Obtain the inverse matrix of the current matrix
102
+ * @returns inverse matrix
103
+ */
96
104
  getInverse(): Float32Array;
105
+ /**
106
+ * Get a copy of the current transformation matrix
107
+ * @returns matrix
108
+ */
97
109
  getTransform(): Float32Array;
110
+ /**
111
+ * Set the current transformation matrix
112
+ * @param array
113
+ */
98
114
  setTransform(array: Float32Array | number[]): void;
99
115
  }
100
116
  export declare class WebglElementBufferArray extends WebglBufferArray {
@@ -197,20 +213,82 @@ export declare class Color {
197
213
  */
198
214
  subtract(color: Color): Color;
199
215
  }
216
+ /**
217
+ * Represents a 2D vector with x and y components.
218
+ */
200
219
  export declare class Vec2 {
201
220
  x: number;
202
221
  y: number;
222
+ /**
223
+ * Creates an instance of Vec2.
224
+ * @param x - The x coordinate (default is 0).
225
+ * @param y - The y coordinate (default is 0).
226
+ */
203
227
  constructor(x?: number, y?: number);
228
+ /**
229
+ * Multiplies the vector by a scalar.
230
+ * @param f - The scalar value to multiply by.
231
+ * @returns The current instance with updated values.
232
+ */
204
233
  scalarMult(f: number): this;
234
+ /**
235
+ * Rotates the vector 90 degrees counterclockwise.
236
+ * @returns The current instance with updated values.
237
+ */
205
238
  perpendicular(): this;
239
+ /**
240
+ * Inverts the direction of the vector.
241
+ * @returns The current instance with updated values.
242
+ */
206
243
  invert(): this;
244
+ /**
245
+ * Calculates the length of the vector.
246
+ * @returns The length of the vector.
247
+ */
207
248
  length(): number;
249
+ /**
250
+ * Normalizes the vector to have a length of 1.
251
+ * @returns The current instance with updated values.
252
+ */
208
253
  normalize(): this;
254
+ /**
255
+ * Calculates the angle of the vector relative to the x-axis.
256
+ * @returns The angle of the vector.
257
+ */
209
258
  angle(): number;
259
+ /**
260
+ * Computes the angle between two vectors.
261
+ * @param p0 - The starting vector.
262
+ * @param p1 - The ending vector.
263
+ * @returns The angle between the two vectors in radians.
264
+ */
210
265
  static Angle(p0: Vec2, p1: Vec2): number;
266
+ /**
267
+ * Adds two vectors together.
268
+ * @param p0 - The first vector.
269
+ * @param p1 - The second vector.
270
+ * @returns A new vector representing the sum of p0 and p1.
271
+ */
211
272
  static Add(p0: Vec2, p1: Vec2): Vec2;
273
+ /**
274
+ * Subtracts one vector from another.
275
+ * @param p1 - The vector to subtract from.
276
+ * @param p0 - The vector to subtract.
277
+ * @returns A new vector representing the difference between p1 and p0.
278
+ */
212
279
  static Sub(p1: Vec2, p0: Vec2): Vec2;
280
+ /**
281
+ * Finds the midpoint between two vectors.
282
+ * @param p0 - The first vector.
283
+ * @param p1 - The second vector.
284
+ * @returns A new vector representing the midpoint between p0 and p1.
285
+ */
213
286
  static Middle(p0: Vec2, p1: Vec2): Vec2;
287
+ /**
288
+ * Converts an array of coordinate pairs into an array of Vec2 instances.
289
+ * @param array - An array of [x, y] coordinate pairs.
290
+ * @returns An array of Vec2 instances.
291
+ */
214
292
  static FormArray(array: number[][]): Vec2[];
215
293
  }
216
294
  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 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);e||(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){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)}static FormArray(t){return t.map((t=>new o(t[0],t[1])))}}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))))},w=(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,w(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++)w(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,{color:i.color,drawType:this.gl.TRIANGLES,points:s})}renderGraphic(t=0,e=0,r){if(r instanceof Array)return this.renderGraphic(t,e,{points:r});this.startGraphicDraw(),r.drawType&&(this.currentRegion.drawType=r.drawType),r.points.forEach((i=>{this.addGraphicVertex(i.x+t,i.y+e,r.color||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}({});
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);e||(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){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.y-t.y,e.x-t.x)}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)}static FormArray(t){return t.map((t=>new o(t[0],t[1])))}}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.setBaseTextur(t)}setBaseTextur(t){t&&(this.base=t,this.setClipRegion(0,0,t.width,t.height))}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.setBaseTextur(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))))},w=(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,w(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++)w(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,{color:i.color,drawType:this.gl.TRIANGLES,points:s})}renderGraphic(t=0,e=0,r){if(r instanceof Array)return this.renderGraphic(t,e,{points:r});this.startGraphicDraw(),r.drawType&&(this.currentRegion.drawType=r.drawType),r.points.forEach((i=>{this.addGraphicVertex(i.x+t,i.y+e,r.color||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){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);e||(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){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)}static FormArray(t){return t.map((t=>new a(t[0],t[1])))}}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)},w=(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))))},S=(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?w(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),w(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,S(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++)S(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];w(t[0],e,r,i,h),w(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,{color:r.color,drawType:this.gl.TRIANGLES,points:i})}renderGraphic(t=0,e=0,r){if(r instanceof Array)return this.renderGraphic(t,e,{points:r});this.startGraphicDraw(),r.drawType&&(this.currentRegion.drawType=r.drawType),r.points.forEach((i=>{this.addGraphicVertex(i.x+t,i.y+e,r.color||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
+ 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);e||(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){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.y-t.y,e.x-t.x)}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)}static FormArray(t){return t.map((t=>new a(t[0],t[1])))}}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.setBaseTextur(t)}setBaseTextur(t){t&&(this.base=t,this.setClipRegion(0,0,t.width,t.height))}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.setBaseTextur(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)},w=(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))))},S=(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?w(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),w(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,S(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++)S(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];w(t[0],e,r,i,h),w(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,{color:r.color,drawType:this.gl.TRIANGLES,points:i})}renderGraphic(t=0,e=0,r){if(r instanceof Array)return this.renderGraphic(t,e,{points:r});this.startGraphicDraw(),r.drawType&&(this.currentRegion.drawType=r.drawType),r.points.forEach((i=>{this.addGraphicVertex(i.x+t,i.y+e,r.color||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 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);e||(e=t);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)}static FormArray(t){return t.map((t=>new a(t[0],t[1])))}}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,{color:r.color,drawType:this.gl.TRIANGLES,points:s})}renderGraphic(t=0,e=0,r){if(r instanceof Array)return this.renderGraphic(t,e,{points:r});this.startGraphicDraw(),r.drawType&&(this.currentRegion.drawType=r.drawType),r.points.forEach((s=>{this.addGraphicVertex(s.x+t,s.y+e,r.color||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;
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);e||(e=t);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.y-t.y,e.x-t.x)}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)}static FormArray(t){return t.map((t=>new a(t[0],t[1])))}}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.setBaseTextur(t)}setBaseTextur(t){t&&(this.base=t,this.setClipRegion(0,0,t.width,t.height))}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.setBaseTextur(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,{color:r.color,drawType:this.gl.TRIANGLES,points:s})}renderGraphic(t=0,e=0,r){if(r instanceof Array)return this.renderGraphic(t,e,{points:r});this.startGraphicDraw(),r.drawType&&(this.currentRegion.drawType=r.drawType),r.points.forEach((s=>{this.addGraphicVertex(s.x+t,s.y+e,r.color||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;
package/dist/render.d.ts CHANGED
@@ -74,7 +74,25 @@ declare class Rapid {
74
74
  * @param options - Rendering options including color and custom shader.
75
75
  */
76
76
  renderSprite(texture: Texture, offsetX?: number, offsetY?: number, options?: IRenderSpriteOptions | Color): void;
77
+ /**
78
+ * Renders a line with the specified options.
79
+ *
80
+ * @param offsetX - The X offset to apply when rendering the line. Defaults to 0.
81
+ * @param offsetY - The Y offset to apply when rendering the line. Defaults to 0.
82
+ * @param options - The options for rendering the line, including points and color.
83
+ */
77
84
  renderLine(offsetX: number | undefined, offsetY: number | undefined, options: IRenderLineOptions): void;
85
+ /**
86
+ * Renders graphics based on the provided options or array of Vec2 points.
87
+ *
88
+ * @param offsetX - The X offset to apply when rendering the graphics. Defaults to 0.
89
+ * @param offsetY - The Y offset to apply when rendering the graphics. Defaults to 0.
90
+ * @param options - Either an object containing graphic options or an array of Vec2 points.
91
+ *
92
+ * @remarks
93
+ * If `options` is an array of `Vec2`, it will be converted to an object with `points` property.
94
+ * If `options` is an object, it should contain `points` (array of `Vec2`) and optionally `color` and `drawType`.
95
+ */
78
96
  renderGraphic(offsetX: number | undefined, offsetY: number | undefined, options: IGraphicOptions | Vec2[]): void;
79
97
  /**
80
98
  * Starts a graphic drawing process with an optional custom shader.
package/dist/texture.d.ts CHANGED
@@ -57,13 +57,21 @@ declare class Texture {
57
57
  * The height of the texture.
58
58
  */
59
59
  height: number;
60
- scale: number;
60
+ /**
61
+ * Image scaling factor
62
+ */
63
+ protected scale: number;
61
64
  /**
62
65
  * Creates a new `Texture` instance with the specified base texture reference.
63
66
  * @param base - The {@link BaseTexture} to be used by the texture.
64
67
  */
65
68
  constructor(base?: BaseTexture);
66
- setBase(base?: BaseTexture, scale?: number): void;
69
+ /**
70
+ * Set or change BaseTexture
71
+ * @param base
72
+ * @param scale
73
+ */
74
+ setBaseTextur(base?: BaseTexture): void;
67
75
  /**
68
76
  * Sets the region of the texture to be used for rendering.
69
77
  * @param x - The x-coordinate of the top-left corner of the region.
@@ -92,7 +100,7 @@ export declare const SCALEFACTOR = 2;
92
100
  declare class Text extends Texture {
93
101
  private options;
94
102
  private rapid;
95
- scale: number;
103
+ protected scale: number;
96
104
  text: string;
97
105
  /**
98
106
  * Creates a new `Text` instance.
@@ -100,11 +108,11 @@ declare class Text extends Texture {
100
108
  */
101
109
  constructor(rapid: Rapid, options: ITextOptions);
102
110
  private updateTextImage;
111
+ private createTextCanvas;
103
112
  /**
104
- * Creates a canvas with the text rendered on it.
105
- * @returns A `Canvas` element with the rendered text.
113
+ * Update the displayed text
114
+ * @param text
106
115
  */
107
- private createTextCanvas;
108
116
  setText(text: string): void;
109
117
  }
110
118
  export { Text, Texture, BaseTexture, TextureCache };
@@ -6,10 +6,22 @@ declare class GLShader {
6
6
  program: WebGLProgram;
7
7
  private gl;
8
8
  constructor(rapid: Rapid, vs: string, fs: string);
9
+ /**
10
+ * Set the uniform of this shader
11
+ * @param uniforms
12
+ * @param usedTextureUnit How many texture units have been used
13
+ */
9
14
  setUniforms(uniforms: UniformType, usedTextureUnit: number): void;
10
15
  private getUniform;
16
+ /**
17
+ * use this shader
18
+ */
11
19
  use(): void;
12
- parseShader(shader: string): void;
20
+ private parseShader;
21
+ /**
22
+ * Set vertex attributes in glsl shader
23
+ * @param element
24
+ */
13
25
  setAttribute(element: IAttribute): void;
14
26
  }
15
27
  export default GLShader;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rapid-render",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -15,7 +15,8 @@
15
15
  },
16
16
  "scripts": {
17
17
  "dev": "rollup -c rollup.config.dev.js -w",
18
- "build": "rollup -c rollup.config.prod.js && tsc"
18
+ "build": "rollup -c rollup.config.prod.js && tsc",
19
+ "docs": "typedoc"
19
20
  },
20
21
  "devDependencies": {
21
22
  "rollup": "^4.12.0",
@@ -25,6 +26,10 @@
25
26
  "rollup-plugin-terser": "^7.0.2",
26
27
  "rollup-plugin-typescript2": "^0.36.0",
27
28
  "tslib": "^2.6.2",
29
+ "typedoc": "^0.26.6",
28
30
  "typescript": "^5.3.3"
31
+ },
32
+ "dependencies": {
33
+ "typedoc-theme-category-nav": "^0.0.3"
29
34
  }
30
35
  }