rapid-render 0.0.6 → 0.0.8

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