UNPKG

@acamposuribe/brush

Version:

Unlock custom brushes, natural fill effects and intuitive hatching in vanilla js

3 lines (2 loc) 38.3 kB
const t=Math.sqrt(3),e=.5*(t-1),i=(3-t)/6,r=t=>0|Math.floor(t),n=new Float64Array([1,1,-1,1,1,-1,-1,-1,1,0,-1,0,1,0,-1,0,0,1,0,-1,0,1,0,-1]);function s(t=Math.random){const s=function(t){const e=new Uint8Array(512);for(let t=0;t<256;t++)e[t]=t;for(let i=0;i<255;i++){const r=i+~~(t()*(256-i)),n=e[i];e[i]=e[r],e[r]=n}for(let t=256;t<512;t++)e[t]=e[t-256];return e}(t),o=new Float64Array(s).map((t=>n[t%12*2])),a=new Float64Array(s).map((t=>n[t%12*2+1]));return function(t,n){let c=0,l=0,h=0;const u=(t+n)*e,f=r(t+u),g=r(n+u),m=(f+g)*i,x=t-(f-m),d=n-(g-m);let p,y;x>d?(p=1,y=0):(p=0,y=1);const _=x-p+i,v=d-y+i,b=x-1+2*i,E=d-1+2*i,R=255&f,w=255&g;let A=.5-x*x-d*d;if(A>=0){const t=R+s[w];A*=A,c=A*A*(o[t]*x+a[t]*d)}let S=.5-_*_-v*v;if(S>=0){const t=R+p+s[w+y];S*=S,l=S*S*(o[t]*_+a[t]*v)}let P=.5-b*b-E*E;if(P>=0){const t=R+1+s[w+1];P*=P,h=P*P*(o[t]*b+a[t]*E)}return 70*(c+l+h)}}function o(t,e){let i=new a(t),r=()=>i.next();return r.double=()=>r()+11102230246251565e-32*(2097152*r()|0),r.int32=()=>4294967296*i.next()|0,r.quick=r,r}class a{constructor(t){null==t&&(t=+new Date);let e=4022871197;function i(t){t=String(t);for(let i=0;i<t.length;i++){e+=t.charCodeAt(i);let r=.02519603282416938*e;e=r>>>0,r-=e,r*=e,e=r>>>0,r-=e,e+=4294967296*r}return 2.3283064365386963e-10*(e>>>0)}this.c=1,this.s0=i(" "),this.s1=i(" "),this.s2=i(" "),this.s0-=i(t),this.s0<0&&(this.s0+=1),this.s1-=i(t),this.s1<0&&(this.s1+=1),this.s2-=i(t),this.s2<0&&(this.s2+=1)}next(){let{c:t,s0:e,s1:i,s2:r}=this,n=2091639*e+2.3283064365386963e-10*t;return this.s0=i,this.s1=r,this.s2=n-(this.c=0|n)}copy(t,e){return e.c=t.c,e.s0=t.s0,e.s1=t.s1,e.s2=t.s2,e}}let c=o(Math.random());const l=t=>{c=o(t)};let h=s(o(Math.random()));const u=t=>{h=s(o(t))},f=(t=0,e=1)=>t+c()*(e-t),g=t=>t[~~(c()*t.length)];function m(t=0,e=1){return Array.isArray(t)?g(t):1===arguments.length?c()*t:f(t,e)}const x=(t,e)=>~~f(t,e),d=(t=0,e=1)=>{const i=1-c(),r=c();return Math.sqrt(-2*Math.log(i))*A(360*r)*e+t},p=t=>{let e=0;const i=[];for(const r in t)e+=t[r],i.push({key:r,cumulative:e});const r=c()*e;for(const{key:t,cumulative:e}of i)if(r<e)return isNaN(t)?t:parseInt(t)},y=(t,e,i,r,n,s=!1)=>{let o=r+(t-e)/(i-e)*(n-r);return s?r<n?_(o,r,n):_(o,n,r):o},_=(t,e,i)=>Math.max(Math.min(t,i),e),v=t=>(t%=360)<0?t+360:t,b=1440,E=2*Math.PI/b,R=new Float32Array(b).fill(NaN),w=new Float32Array(b).fill(NaN),A=t=>{const e=~~(4*v(t));let i=R[e];return isNaN(i)&&(i=Math.cos(e*E),R[e]=i),i},S=t=>{const e=~~(4*v(t));let i=w[e];return isNaN(i)&&(i=Math.sin(e*E),w[e]=i),i},P=t=>{let e=180*t/Math.PI%360;return e<0?e+360:e},I=(t,e,i,r,n)=>{let s=A(n),o=S(n);return{x:s*(i-t)+o*(r-e)+t,y:s*(r-e)-o*(i-t)+e}},T=(t,e,i,r)=>Math.hypot(i-t,r-e),L=(t,e,i,r)=>P(Math.atan2(-(r-e),i-t)),C=(t,e,i,r,n=!1)=>{let s=t.x,o=t.y,a=e.x,c=e.y,l=i.x,h=i.y,u=r.x,f=r.y;if(s===a&&o===c||l===u&&h===f)return!1;let g=a-s,m=c-o,x=u-l,d=f-h,p=d*g-x*m;if(0===p)return!1;let y=(x*(o-h)-d*(s-l))/p,_=(g*(o-h)-m*(s-l))/p;return!(!n&&(_<0||_>1))&&{x:s+y*g,y:o+y*m}},k=()=>{let t,e,i={};function r(){const i=e.createTexture();return e.bindTexture(e.TEXTURE_2D,i),e.texStorage2D(e.TEXTURE_2D,1,e.RGBA8,t.width,t.height),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),i}function n(){let t=r();const i=e.createFramebuffer();return e.bindFramebuffer(e.FRAMEBUFFER,i),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),{texture:t,fbo:i}}function s(t,i){e.activeTexture(t),e.bindTexture(e.TEXTURE_2D,i)}function o(i,r){e.bindFramebuffer(e.READ_FRAMEBUFFER,i),e.bindFramebuffer(e.DRAW_FRAMEBUFFER,r),e.blitFramebuffer(0,0,t.width,t.height,0,0,t.width,t.height,e.COLOR_BUFFER_BIT,e.NEAREST)}function a(t){e.bindFramebuffer(e.DRAW_FRAMEBUFFER,i.source.fbo),e.clearColor(...t),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}onmessage=async c=>{const l=c.data;l.canvas?function(o){t=o,e=t.getContext("webgl2",{antialias:!1});const c=(t=>{const e=t.createProgram();for(let[i,r]of[[t.VERTEX_SHADER,"#version 300 es\n#define GLSLIFY 1\nout vec2 p;void main(){vec3 v=vec3(-1);v[gl_VertexID]=3.;gl_Position=vec4(p=v.xy,0,1);}"],[t.FRAGMENT_SHADER,"#version 300 es\nprecision highp float;\n#define GLSLIFY 1\nuniform vec4 u_addColor;uniform bool u_isErase;uniform bool u_isImage;uniform bool u_isBrush;uniform sampler2D u_source;uniform sampler2D u_mask;in vec2 p;out vec4 outColor;const int SPECTRAL_SIZE=38;const float SPECTRAL_GAMMA=2.4;const float SPECTRAL_EPSILON=0.0001;float compand(float x,bool inverse){if(inverse){return(x<0.04045)? x/12.92 : pow((x+0.055)/1.055,SPECTRAL_GAMMA);}else{return(x<0.0031308)? x*12.92 : 1.055*pow(x,1.0/SPECTRAL_GAMMA)-0.055;}}vec3 spectral_srgb_to_linear(vec3 srgb){return vec3(compand(srgb.r,true),compand(srgb.g,true),compand(srgb.b,true));}vec3 spectral_linear_to_srgb(vec3 lrgb){return clamp(vec3(compand(lrgb.r,false),compand(lrgb.g,false),compand(lrgb.b,false)),0.0,1.0);}void spectral_upsampling(vec3 lrgb,out float w,out float c,out float m,out float y,out float r,out float g,out float b){w=min(lrgb.r,min(lrgb.g,lrgb.b));lrgb-=w;c=min(lrgb.g,lrgb.b);m=min(lrgb.r,lrgb.b);y=min(lrgb.r,lrgb.g);r=min(max(0.,lrgb.r-lrgb.b),max(0.,lrgb.r-lrgb.g));g=min(max(0.,lrgb.g-lrgb.b),max(0.,lrgb.g-lrgb.r));b=min(max(0.,lrgb.b-lrgb.g),max(0.,lrgb.b-lrgb.r));}void spectral_linear_to_reflectance(vec3 lrgb,inout float R[SPECTRAL_SIZE]){float w,c,m,y,r,g,b;spectral_upsampling(lrgb,w,c,m,y,r,g,b);R[0]=max(SPECTRAL_EPSILON,w+c*0.96853629+m*0.51567122+y*0.02055257+r*0.03147571+g*0.49108579+b*0.97901834);R[1]=max(SPECTRAL_EPSILON,w+c*0.96855103+m*0.54015520+y*0.02059936+r*0.03146636+g*0.46944057+b*0.97901649);R[2]=max(SPECTRAL_EPSILON,w+c*0.96859338+m*0.62645502+y*0.02062723+r*0.03140624+g*0.40165780+b*0.97901118);R[3]=max(SPECTRAL_EPSILON,w+c*0.96877345+m*0.75595012+y*0.02073387+r*0.03119611+g*0.24490420+b*0.97892146);R[4]=max(SPECTRAL_EPSILON,w+c*0.96942204+m*0.92826996+y*0.02114202+r*0.03053888+g*0.06826880+b*0.97858555);R[5]=max(SPECTRAL_EPSILON,w+c*0.97143709+m*0.97223624+y*0.02233154+r*0.02856855+g*0.02732883+b*0.97743705);R[6]=max(SPECTRAL_EPSILON,w+c*0.97541862+m*0.98616174+y*0.02556857+r*0.02459485+g*0.01360600+b*0.97428075);R[7]=max(SPECTRAL_EPSILON,w+c*0.98074186+m*0.98955255+y*0.03330189+r*0.01929520+g*0.01000187+b*0.96663223);R[8]=max(SPECTRAL_EPSILON,w+c*0.98580992+m*0.98676237+y*0.05185294+r*0.01423112+g*0.01284127+b*0.94822893);R[9]=max(SPECTRAL_EPSILON,w+c*0.98971194+m*0.97312575+y*0.10087639+r*0.01033111+g*0.02636635+b*0.89937713);R[10]=max(SPECTRAL_EPSILON,w+c*0.99238027+m*0.91944277+y*0.24000413+r*0.00765876+g*0.07058713+b*0.76070164);R[11]=max(SPECTRAL_EPSILON,w+c*0.99409844+m*0.32564851+y*0.53589066+r*0.00593693+g*0.70421692+b*0.46420440);R[12]=max(SPECTRAL_EPSILON,w+c*0.99517200+m*0.13820628+y*0.79874659+r*0.00485616+g*0.85473994+b*0.20123039);R[13]=max(SPECTRAL_EPSILON,w+c*0.99576545+m*0.05015143+y*0.91186529+r*0.00426186+g*0.95081565+b*0.08808402);R[14]=max(SPECTRAL_EPSILON,w+c*0.99593552+m*0.02912336+y*0.95399623+r*0.00409039+g*0.97170370+b*0.04592894);R[15]=max(SPECTRAL_EPSILON,w+c*0.99564041+m*0.02421691+y*0.97137099+r*0.00438375+g*0.97651888+b*0.02860373);R[16]=max(SPECTRAL_EPSILON,w+c*0.99464769+m*0.02660696+y*0.97939505+r*0.00537525+g*0.97429245+b*0.02060067);R[17]=max(SPECTRAL_EPSILON,w+c*0.99229579+m*0.03407586+y*0.98345207+r*0.00772962+g*0.97012917+b*0.01656701);R[18]=max(SPECTRAL_EPSILON,w+c*0.98638762+m*0.04835936+y*0.98553736+r*0.01366120+g*0.94258630+b*0.01451549);R[19]=max(SPECTRAL_EPSILON,w+c*0.96829712+m*0.00011720+y*0.98648905+r*0.03181352+g*0.99989207+b*0.01357964);R[20]=max(SPECTRAL_EPSILON,w+c*0.89228016+m*0.00008554+y*0.98674535+r*0.10791525+g*0.99989891+b*0.01331243);R[21]=max(SPECTRAL_EPSILON,w+c*0.53740239+m*0.85267882+y*0.98657555+r*0.46249516+g*0.13823139+b*0.01347661);R[22]=max(SPECTRAL_EPSILON,w+c*0.15360445+m*0.93188793+y*0.98611877+r*0.84604333+g*0.06968113+b*0.01387181);R[23]=max(SPECTRAL_EPSILON,w+c*0.05705719+m*0.94810268+y*0.98559942+r*0.94275572+g*0.05628787+b*0.01435472);R[24]=max(SPECTRAL_EPSILON,w+c*0.03126539+m*0.94200977+y*0.98507063+r*0.96860996+g*0.06111561+b*0.01479836);R[25]=max(SPECTRAL_EPSILON,w+c*0.02205445+m*0.91478045+y*0.98460039+r*0.97783966+g*0.08987709+b*0.01515250);R[26]=max(SPECTRAL_EPSILON,w+c*0.01802271+m*0.87065445+y*0.98425301+r*0.98187757+g*0.13656016+b*0.01540513);R[27]=max(SPECTRAL_EPSILON,w+c*0.01613460+m*0.78827548+y*0.98403909+r*0.98377315+g*0.22169624+b*0.01557233);R[28]=max(SPECTRAL_EPSILON,w+c*0.01520947+m*0.65738359+y*0.98388535+r*0.98470202+g*0.32176956+b*0.01565710);R[29]=max(SPECTRAL_EPSILON,w+c*0.01475977+m*0.59909403+y*0.98376116+r*0.98515481+g*0.36157329+b*0.01571025);R[30]=max(SPECTRAL_EPSILON,w+c*0.01454263+m*0.56817268+y*0.98368246+r*0.98537114+g*0.48361920+b*0.01571916);R[31]=max(SPECTRAL_EPSILON,w+c*0.01444459+m*0.54031997+y*0.98365023+r*0.98546685+g*0.46488579+b*0.01572133);R[32]=max(SPECTRAL_EPSILON,w+c*0.01439897+m*0.52110241+y*0.98361309+r*0.98550011+g*0.47440306+b*0.01572502);R[33]=max(SPECTRAL_EPSILON,w+c*0.01437620+m*0.51041094+y*0.98357259+r*0.98551031+g*0.48576990+b*0.01571717);R[34]=max(SPECTRAL_EPSILON,w+c*0.01436343+m*0.50526577+y*0.98353856+r*0.98550741+g*0.49267971+b*0.01571905);R[35]=max(SPECTRAL_EPSILON,w+c*0.01435687+m*0.50255080+y*0.98351247+r*0.98551323+g*0.49625685+b*0.01571059);R[36]=max(SPECTRAL_EPSILON,w+c*0.01435370+m*0.50126452+y*0.98350101+r*0.98551563+g*0.49807754+b*0.01569728);R[37]=max(SPECTRAL_EPSILON,w+c*0.01435408+m*0.50083021+y*0.98350852+r*0.98551547+g*0.49889859+b*0.01570020);}const vec3 XYZ_DATA[SPECTRAL_SIZE]=vec3[](vec3(0.00006469,0.00000184,0.00030502),vec3(0.00021941,0.00000621,0.00103681),vec3(0.00112057,0.00003101,0.00531314),vec3(0.00376661,0.00010475,0.01795439),vec3(0.01188055,0.00035364,0.05707758),vec3(0.02328644,0.00095147,0.11365162),vec3(0.03455942,0.00228226,0.17335873),vec3(0.03722379,0.00420733,0.19620658),vec3(0.03241838,0.00668880,0.18608237),vec3(0.02123321,0.00988840,0.13995048),vec3(0.01049099,0.01524945,0.08917453),vec3(0.00329584,0.02141831,0.04789621),vec3(0.00050704,0.03342293,0.02814563),vec3(0.00094867,0.05131001,0.01613766),vec3(0.00627372,0.07040208,0.00775910),vec3(0.01686462,0.08783871,0.00429615),vec3(0.02868965,0.09424905,0.00200551),vec3(0.04267481,0.09795667,0.00086147),vec3(0.05625475,0.09415219,0.00036904),vec3(0.06947040,0.08678102,0.00019143),vec3(0.08305315,0.07885653,0.00014956),vec3(0.08612610,0.06352670,0.00009231),vec3(0.09046614,0.05374142,0.00006813),vec3(0.08500387,0.04264606,0.00002883),vec3(0.07090667,0.03161735,0.00001577),vec3(0.05062889,0.02088521,0.00000394),vec3(0.03547396,0.01386011,0.00000158),vec3(0.02146821,0.00810264,0.00000000),vec3(0.01251646,0.00463010,0.00000000),vec3(0.00680458,0.00249138,0.00000000),vec3(0.00346457,0.00125930,0.00000000),vec3(0.00149761,0.00054165,0.00000000),vec3(0.00076970,0.00027795,0.00000000),vec3(0.00040737,0.00014711,0.00000000),vec3(0.00016901,0.00006103,0.00000000),vec3(0.00009522,0.00003439,0.00000000),vec3(0.00004903,0.00001771,0.00000000),vec3(0.00002000,0.00000722,0.00000000));vec3 spectral_reflectance_to_xyz(float R[SPECTRAL_SIZE]){vec3 xyz=vec3(0.0);for(int i=0;i<SPECTRAL_SIZE;i++){xyz+=R[i]*XYZ_DATA[i];}return xyz;}float calculate_ks(float r){return pow(1.0-r,2.0)/(2.0*r);}const mat3 XYZ_RGB=mat3(vec3(3.24306333,-1.53837619,-0.49893282),vec3(-0.96896309,1.87542451,0.04154303),vec3(0.05568392,-0.20417438,1.05799454));vec3 spectral_xyz_to_srgb(vec3 xyz){vec3 lrgb=vec3(dot(XYZ_RGB[0],xyz),dot(XYZ_RGB[1],xyz),dot(XYZ_RGB[2],xyz));return spectral_linear_to_srgb(lrgb);}vec3 srgb_to_xyz(vec3 color){vec3 lrgb=spectral_srgb_to_linear(color);float R[SPECTRAL_SIZE];spectral_linear_to_reflectance(lrgb,R);return spectral_reflectance_to_xyz(R);}vec3 spectral_mix(vec3 color1,vec3 color2,float t){vec3 lrgb1=spectral_srgb_to_linear(color1);vec3 lrgb2=spectral_srgb_to_linear(color2);float R1[SPECTRAL_SIZE];float R2[SPECTRAL_SIZE];float R[SPECTRAL_SIZE];spectral_linear_to_reflectance(lrgb1,R1);spectral_linear_to_reflectance(lrgb2,R2);float l1=spectral_reflectance_to_xyz(R1)[1];float l2=spectral_reflectance_to_xyz(R2)[1];float t1=l1*pow(1.0-t,2.0);float t2=l2*pow(t,2.0);t=t2/(t1+t2);for(int i=0;i<SPECTRAL_SIZE;i++){float ks1=calculate_ks(R1[i]);float ks2=calculate_ks(R2[i]);float ks=(1.0-t)*ks1+t*ks2;R[i]=1.0+ks-sqrt(ks*ks+2.0*ks);}return spectral_xyz_to_srgb(spectral_reflectance_to_xyz(R));}const float GAMMA=2.4,EPSILON=0.0001;const float DARKEN_THRESHOLD=0.7;const float EDGE_MIN=0.05,EDGE_MAX=0.35;void main(void){vec2 uv=0.5*p+0.5;vec2 uv1=vec2(uv.x,1.0-uv.y);vec4 source=texture(u_source,uv);vec4 maskColor=texture(u_mask,uv1);if(u_isImage){outColor=maskColor;return;}if(maskColor.r<=0.0){outColor=source;return;}vec4 pigment=vec4(u_addColor.xyz,1.0);if(maskColor.a>DARKEN_THRESHOLD&&!u_isErase){float blacken=0.5*(maskColor.a-DARKEN_THRESHOLD);pigment=pigment*(1.0-blacken)-vec4(0.5)*blacken;}float mixIntensity=maskColor.a;if(!u_isBrush){vec2 texelSize=1.0/vec2(textureSize(u_mask,0));float scaledAlpha=maskColor.a*15.0;float blurEdge=0.0;for(int i=-2;i<=2;i+=2){for(int j=-2;j<=2;j+=2){vec2 sampleUV=uv1+vec2(float(i),float(j))*texelSize;float neighborAlpha=texture(u_mask,sampleUV).a*15.0;blurEdge+=smoothstep(EDGE_MIN,EDGE_MAX,length(vec2(dFdx(neighborAlpha),dFdy(neighborAlpha))));}}blurEdge/=9.0;mixIntensity=clamp(maskColor.a+blurEdge*0.1,0.0,1.0);}outColor=vec4(spectral_mix(source.rgb,pigment.rgb,mixIntensity),1.0);}"]]){const n=t.createShader(i);t.shaderSource(n,r),t.compileShader(n),t.attachShader(e,n)}return t.linkProgram(e),e})(e);e.useProgram(c),["u_addColor","u_isErase","u_isImage","u_isBrush","u_source","u_mask"].forEach((t=>{i[t]=e.getUniformLocation(c,t)})),i.mask=r(),i.source=n(),i.target=n(),e.uniform1i(i.u_source,0),e.uniform1i(i.u_mask,1),s(e.TEXTURE0,i.source.texture),s(e.TEXTURE1,i.mask),a([1,1,1,0])}(l.canvas):l.isBG?a(l.color):l.mask&&function(t){(function(t){let i=t.mask;if(self.navigator&&/Safari/.test(self.navigator.userAgent)&&!/Chrome/.test(self.navigator.userAgent)){const t=new OffscreenCanvas(i.width,i.height);t.getContext("2d").drawImage(i,0,0),i=t.getContext("2d").getImageData(0,0,i.width,i.height)}e.texSubImage2D(e.TEXTURE_2D,0,0,0,e.RGBA,e.UNSIGNED_BYTE,i),t.mask.close()})(t),e.bindFramebuffer(e.FRAMEBUFFER,i.target.fbo),e.uniform1i(i.u_isImage,t.isImage?1:0),e.uniform1i(i.u_isBrush,t.isBrush?1:0),t.isImage||(e.uniform1i(i.u_isImage,!1),e.uniform4f(i.u_addColor,...t.addColor),e.uniform1i(i.u_isErase,!!t.isErase)),e.drawArrays(e.TRIANGLES,0,3),o(i.target.fbo,i.source.fbo),t.isLast&&!t.sp&&o(i.target.fbo,null)}(l)}};Worker.createURL=function(t){const e="function"==typeof t?t.toString():t,i=new Blob(["'use strict';\nself.onmessage="+e],{type:"text/javascript"});return window.URL.createObjectURL(i)},Worker.create=function(t){return new Worker(Worker.createURL(t))};const M={};let N,O,B;const F=(t,e)=>{N=t,M[N]||(M[N]={canvas:e}),O=e.width,B=e.height,X=!0,G.load()};let X=!1;const D={},z=document.createElement("canvas").getContext("2d");class U{constructor(t,e,i){if(isNaN(t)){this.hex=this.standardize(t);let e=this.hexToRgb(this.hex);this.r=e.r,this.g=e.g,this.b=e.b}else this.r=_(t,0,255),this.g=_(e||t,0,255),this.b=_(i||t,0,255),this.hex=this.rgbToHex(this.r,this.g,this.b);this.gl=[this.r/255,this.g/255,this.b/255,1]}rgbToHex=(t,e,i)=>"#"+(1<<24|t<<16|e<<8|i).toString(16).slice(1);hexToRgb(t){t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,((t,e,i,r)=>e+e+i+i+r+r));const e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null}standardize=t=>(z.fillStyle=t,z.fillStyle)}const Y=()=>{G.loaded||((()=>{if(!X)throw new Error("Call `load()` first")})(),G.load())},G={loaded:!1,isBlending:!1,load(){const t=M[N];t.worker||(t.mask=new OffscreenCanvas(O,B),t.glMask=new OffscreenCanvas(O,B),t.ctx=t.mask.getContext("2d"),t.gl=t.glMask.getContext("webgl2"),t.ctx.lineWidth=0,t.offscreen=t.canvas.transferControlToOffscreen(),t.worker=Worker.create(k),t.worker.postMessage(0),t.worker.postMessage({canvas:t.offscreen},[t.offscreen])),Object.assign(this,t)},blend(t=!1,e=!1,i=!1,r=!1){if(Y(),!this.isBlending&&t&&(this.currentColor=t.gl,this.isBlending=!0),e||i||t.gl.toString()!==this.currentColor.toString()){const n=i||this.isBrush?this.glMask.transferToImageBitmap():this.mask.transferToImageBitmap();this.worker.postMessage({addColor:this.currentColor,mask:n,isLast:e,isErase:this.isErase,isImage:Boolean(i),sp:r,isBrush:this.isBrush},[n]),this.isErase=this.isBrush=!1,e&&!r?this.isBlending=!1:this.currentColor=t.gl}}};let W=new U("white");const H=(...t)=>{Y(),W=new U(...t),G.worker.postMessage({color:W.gl,isBG:!0})},Z=(t,...e)=>{Y(),G.ctx.drawImage(t,...e),t=G.mask.transferToImageBitmap(),G.blend(!1,!1,t)},V={x:0,y:0};function q(t,e){j(),G.ctx.translate(t,e);let i=G.ctx.getTransform();V.x=i.e,V.y=i.f}let $=!1;function j(){$||(Y(),J=.01*O,Q=-.5*O,tt=-.5*B,et=Math.round(2*O/J),it=Math.round(2*B/J),ct("hand",(function(t,e){const i=f(.2,.8),r=x(5,10);for(let n=0;n<et;n++){const s=n;for(let o=0;o<it;o++){const a=x(15,25),c=.5*r*S(i*o*n+a),l=h(s,o);e[n][o]=.2*c*A(t)+l*r*.7}}return e})),$=!0)}class K{constructor(t,e){j(),this.update(t,e),this.plotted=0}update(t,e){this.x=t,this.y=e,this.colIdx=K.getColIndex(t),this.rowIdx=K.getRowIndex(e)}reset(){this.plotted=0}isIn(){return D.field.isActive?K.isIn(this.colIdx,this.rowIdx):this.isInCanvas(this.x,this.y)}isInCanvas(){const t=O,e=B,i=this.x+V.x,r=this.y+V.y;return i>=-.3*t&&i<=1.3*t&&r>=-.3*e&&r<=1.3*e}angle(){return this.isIn()&&D.field.isActive?rt.get(D.field.current).field[this.colIdx][this.rowIdx]*D.field.wiggle:0}moveTo(t,e,i=1){this.movePos(t,e,i)}plotTo(t,e,i,r=1){this.movePos(t,e,i,r)}movePos(t,e,i,r=!1){const n=r||1;if(this.isIn())for(let s=0;s<e/i;s++){const e=this.angle()-(r?t.angle(this.plotted):t);this.update(this.x+i*A(e),this.y+i*S(e)),this.plotted+=i/n}else this.plotted+=i/n}static getRowIndex(t,e=1){const i=t+V.y-tt;return Math.round(i/J/e)}static getColIndex(t,e=1){const i=t+V.x-Q;return Math.round(i/J/e)}static isIn(t,e){return t>=0&&e>=0&&t<et&&e<it}}D.field={isActive:!1,current:null,wiggle:1};let J,Q,tt,et,it,rt=new Map;function nt(t=0){const e=rt.get(D.field.current);e.field=e.gen(t,st())}function st(){return new Array(et).fill(null).map((()=>new Float32Array(it)))}function ot(t){if(D.field.wiggle||(D.field.wiggle=1),j(),!rt.has(t))throw new Error(`Field "${name}" does not exist.`);D.field.isActive=!0,D.field.current=t}function at(){j(),D.field.isActive=!1}function ct(t,e){rt.set(t,{gen:e}),rt.get(t).field=rt.get(t).gen(0,st())}function lt(){return j(),Array.from(rt.keys())}function ht(t=1){ot("hand"),D.field.wiggle=t}let ut={};function ft(){j(),G.ctx.save(),ut.fill={...D.fill},ut.stroke={...D.stroke},ut.hatch={...D.hatch},ut.field={...D.field}}function gt(){G.ctx.restore();let t=G.ctx.getTransform();V.x=t.e,V.y=t.f,D.stroke={...ut.stroke},D.field={...ut.field},D.hatch={...ut.hatch},D.fill={...ut.fill}}function mt(t){G.ctx.beginPath(),t.forEach(((t,e)=>{0===e?G.ctx.moveTo(t.x,t.y):G.ctx.lineTo(t.x,t.y)})),G.ctx.closePath()}function xt(t,e,i){const r=2*Math.PI,n=i/2;G.ctx.moveTo(t+n,e),G.ctx.arc(t,e,n,0,r)}const dt={isActive:!1,c:null,a:255};function pt(t=_bg_Color,e=255){dt.isActive=!0,dt.c=new U(t),dt.a=e}function yt(){dt.isActive=!1}function _t(t){G.blend(dt.c),G.isErase=!0,G.ctx.save(),G.ctx.fillStyle="rgb(255 0 0 / "+dt.a+"%)",mt(t),G.ctx.fill(),G.ctx.restore()}class vt{constructor(t,e=!1){this.a=t,this.vertices=e?t:t.map((([t,e])=>({x:t,y:e}))),this.sides=this.vertices.map(((t,e,i)=>[t,i[(e+1)%i.length]])),this._intersectionCache={}}intersect(t){const e=`${t.point1.x},${t.point1.y}-${t.point2.x},${t.point2.y}`;if(this._intersectionCache[e])return this._intersectionCache[e];const i=[];for(const[e,r]of this.sides){const n=C(t.point1,t.point2,e,r);n&&i.push(n)}return this._intersectionCache[e]=i,i}erase(){_t(this.vertices)}show(){dt.isActive?this.erase():(D.draw&&this.draw(),D.hatch&&this.hatch(),D.fill&&this.fill())}}class bt{constructor(t){this.segments=[],this.angles=[],this.pres=[],this.type=t,this.dir=0,this.calcIndex(0),this.pol=!1}addSegment(t=0,e=0,i=1,r=!1){this.angles.length>0&&this.angles.pop(),t=r?(t%360+360)%360:P(t),this.angles.push(t,t),this.pres.push(i),this.segments.push(e),this.length=this.segments.reduce(((t,e)=>t+e),0)}endPlot(t=0,e=1,i=!1){t=i?(t%360+360)%360:P(t),this.angles[this.angles.length-1]=t,this.pres.push(e)}rotate(t){this.dir=P(t)}pressure(t){return t>this.length?this.pres[this.pres.length-1]:this.curving(this.pres,t)}angle(t){return t>this.length?this.angles[this.angles.length-1]:(this.calcIndex(t),"curve"===this.type?this.curving(this.angles,t)+this.dir:this.angles[this.index]+this.dir)}curving(t,e){let i=t[this.index],r=t[this.index+1]??i;return Math.abs(r-i)>180&&(r>i?r=-(360-r):i=-(360-i)),y(e-this.suma,0,this.segments[this.index],i,r,!0)}calcIndex(t){this.index=-1,this.suma=0;let e=0;for(;e<=t;)this.suma=e,e+=this.segments[this.index+1],this.index++;return this.index}genPol(t,e,i=1,r){j();const n=.5,s=[],o=Math.round(this.length/n),a=new K(t,e);let c=0,l=0;for(let t=0;t<o;t++){a.plotTo(this,n,n);const t=this.calcIndex(a.plotted);c+=n,(c>=Math.max(this.segments[t]*r*f(.7,1.3),10)||t>=l)&&a.x&&(s.push([a.x,a.y]),c=0,t>=l&&l++)}return new vt(s)}erase(t,e,i){this.origin&&([t,e,i]=[...this.origin,1]),this.pol=this.genPol(t,e,i,.15),_t(this.pol.vertices)}show(t,e,i=1){dt.isActive?this.erase():(D.stroke&&this.draw(t,e,i),D.hatch&&this.hatch(t,e,i),D.fill&&this.fill(t,e,i))}}function Et(t){new vt(t).show()}function Rt(t,e,i,r,n="corner"){"center"===n&&(t-=i/2,e-=r/2),kt(0),Mt(t,e),Nt(t+i,e),Nt(t+i,e+r),Nt(t,e+r),Ot(),Bt()}function wt(t,e,i,r=!1){const n=new bt("curve"),s=Math.PI*i,o=f(0,360),a=r?()=>1+.2*f():()=>1;for(let t=0;t<4;t++){const e=-90*t+o;n.addSegment(e*a(),s/2*a(),1,!0)}if(r){const t=x(-5,5);n.addSegment(o,Math.abs(t)*(Math.PI/180)*i,1,!0),n.endPlot(t+o,1,!0)}else n.endPlot(o,1,!0);const c=t-i*S(o),l=e-i*A(-o);n.show(c,l,1)}function At(t,e,i,r,n){const s=new bt("curve"),o=270-P(r),a=270-P(n),c=P(n-r),l=Math.PI*i*c/180;s.addSegment(o,l,1,!0),s.endPlot(a,1,!0);const h=t+i*A(-o-90),u=e+i*S(-o-90);s.draw(h,u,1)}let St,Pt,It,Tt,Lt;class Ct{constructor(){this.isClosed=!1,this.curvature=It,this.vert=[]}vertex(t,e,i){this.vert.push([t,e,i])}show(){Ut(this.vert,this.curvature,this.isClosed).show()}}function kt(t=0){It=_(t,0,1),St=[]}function Mt(t,e,i=1){Pt=new Ct,St.push(Pt),Pt.vertex(t,e,i)}function Nt(t,e,i=1){Pt.vertex(t,e,i)}function Ot(){Pt.vertex(...Pt.vert[0]),Pt.isClosed=!0}function Bt(){for(let t of St)t.show();St=!1}function Ft(t,e,i){Lt=[e,i],Tt=new bt(t)}function Xt(t,e,i){Tt.addSegment(t,e,i)}function Dt(t,e){Tt.endPlot(t,e),Tt.draw(Lt[0],Lt[1],1),Tt=!1}function zt(t,e=.5){Ut(t,e).draw()}function Ut(t,e=.5,i=!1){const r=new bt(0===e?"segments":"curve"),n=2*Math.PI;if(i&&0!==e&&t.push(t[1]),t&&t.length>0){let s,o,a,c=0;for(let l=0;l<t.length-1;l++)if(e>0&&l<t.length-2){const h=t[l],u=t[l+1],f=t[l+2],g=T(h[0],h[1],u[0],u[1]),m=T(u[0],u[1],f[0],f[1]),x=L(h[0],h[1],u[0],u[1]),d=L(u[0],u[1],f[0],f[1]),p=e*Math.min(g,m,.5*Math.min(g,m)),y=Math.max(g,m),_=g-p,v=m-p;if(Math.floor(x)===Math.floor(d)){const e=i&&0===l?0:g-c,n=i?0===l?0:m-a:m;r.addSegment(x,e,h[2],!0),l===t.length-3&&r.addSegment(d,n,u[2],!0),c=0,0===l&&(s=g,a=p,o=t[1],c=0)}else{const e={x:u[0]-p*A(-x),y:u[1]-p*S(-x)},f={x:e.x+y*A(90-x),y:e.y+y*S(90-x)},g={x:u[0]+p*A(-d),y:u[1]+p*S(-d)},m={x:g.x+y*A(90-d),y:g.y+y*S(90-d)},b=C(e,f,g,m,!0),E=T(e.x,e.y,b.x,b.y),R=T(e.x,e.y,g.x,g.y)/2,w=n*E*(2*Math.asin(R/E)*(180/Math.PI))/360,P=i&&0===l?0:_-c,I=l===t.length-3?i?s-p:v:0;r.addSegment(x,P,h[2],!0),r.addSegment(x,isNaN(w)?0:w,h[2],!0),r.addSegment(d,I,u[2],!0),c=p,0===l&&(s=_,a=p,o=[e.x,e.y])}l===t.length-3&&r.endPlot(d,u[2],!0)}else if(0===e){const e=t[l],i=t[l+1],n=T(e[0],e[1],i[0],i[1]),s=L(e[0],e[1],i[0],i[1]);r.addSegment(s,n,i[2],!0),l===t.length-2&&r.endPlot(s,1,!0)}r.origin=i&&0!==e?o:t[0]}return r}let Yt,Gt=0,Wt=!1,Ht=30,Zt=0;function Vt(t=!1){t&&(Yt=t),Wt=!0,setTimeout((()=>{requestAnimationFrame(jt)}),"200")}function qt(){Wt=!1}let $t=t=>(t&&(Ht=t),Ht);function jt(t){Wt&&(t>Gt+1e3/$t()||0===t)&&(Gt=t,Zt++,Yt&&Yt(),Kt()),requestAnimationFrame(jt)}function Kt(){G.blend(!1,!0)}let Jt,Qt,te=!1;const ee={},ie={},re=[];function ne(){if(!te){Y(),Jt=G.gl,Qt=new Float32Array([2/O,0,0,0,0,-2/B,0,0,0,0,1,0,-1,1,0,1]);const t=(t=>{const e=t.createProgram();for(let[i,r]of[[t.VERTEX_SHADER,"#version 300 es\nin vec2 a_position;in float a_radius,a_alpha;uniform mat4 u_matrix;out float v_alpha;void main(){gl_Position=u_matrix*vec4(a_position,0,1);v_alpha=a_alpha;gl_PointSize=a_radius*2.;}"],[t.FRAGMENT_SHADER,"#version 300 es\nprecision highp float;in float v_alpha;out vec4 outColor;void main(){vec2 v=gl_PointCoord-vec2(.5);float f=length(v),a=fwidth(f);f=1.-smoothstep(.5-a,.5+a,f);if(f<.01)discard;outColor=vec4(vec3(1,0,0)*v_alpha,v_alpha*f);}\n"]]){const n=t.createShader(i);t.shaderSource(n,r),t.compileShader(n),t.attachShader(e,n)}return t.linkProgram(e),e})(Jt);Jt.useProgram(t),Jt.enable(Jt.BLEND),Jt.blendFunc(Jt.ONE_MINUS_DST_ALPHA,Jt.ONE),["a_position","a_radius","a_alpha"].forEach((e=>ee[e]=Jt.getAttribLocation(t,e))),["u_matrix"].forEach((e=>ie[e]=Jt.getUniformLocation(t,e))),te=!0}}function se(t,e,i,r){ne(),re.push({x:t+V.x,y:e+V.y,radius:i/2,alpha:r/100})}function oe(){if(0===re.length)return;const t=new Float32Array(4*re.length);re.forEach(((e,i)=>{const r=4*i;t.set([e.x,e.y,e.radius,e.alpha],r)})),re.length=0;const e=Jt.createVertexArray();Jt.bindVertexArray(e);const i=Jt.createBuffer();Jt.bindBuffer(Jt.ARRAY_BUFFER,i),Jt.bufferData(Jt.ARRAY_BUFFER,t,Jt.STATIC_DRAW),Jt.enableVertexAttribArray(ee.a_position),Jt.vertexAttribPointer(ee.a_position,2,Jt.FLOAT,!1,16,0),Jt.enableVertexAttribArray(ee.a_radius),Jt.vertexAttribPointer(ee.a_radius,1,Jt.FLOAT,!1,16,8),Jt.enableVertexAttribArray(ee.a_alpha),Jt.vertexAttribPointer(ee.a_alpha,1,Jt.FLOAT,!1,16,12),Jt.uniformMatrix4fv(ie.u_matrix,!1,Qt),Jt.drawArrays(Jt.POINTS,0,t.length/4),Jt.bindVertexArray(null),Jt.deleteBuffer(i),Jt.deleteVertexArray(e)}const ae=2*Math.PI;D.stroke={color:new U("black"),weight:1,clipWindow:null,type:"HB",isActive:!1,opacity:1};let ce,le,he,ue,fe=new Map;function ge(){return{...D.stroke}}function me(t){D.stroke={...t}}function xe(t,e){e.type=["marker","custom","image","spray"].includes(e.type)?e.type:"default",fe.set(t,{param:e,colors:[],buffers:[]})}function de(){return[...fe.keys()]}function pe(t){for(const{param:e}of fe.values())e&&(e.weight*=t,e.vibration*=t,e.spacing*=t)}function ye(t){fe.has(t)&&(D.stroke.type=t)}function _e(t,e,i){D.stroke.color=new U(...arguments),D.stroke.isActive=!0}function ve(t){D.stroke.weight=t}function be(t,e,i=1){ye(t),_e(e),ve(i)}function Ee(){D.stroke.isActive=!1}function Re(t){D.stroke.clipWindow=t}function we(){D.stroke.clipWindow=null}const Ae={};function Se(t,e,i,r=!1){ce=new K(t,e),le=i,he=r,he&&he.calcIndex(0)}const Pe=[];function Ie(t,e){e||(ue=t),function(){Ae.seed=99999*f();const{param:t}=fe.get(D.stroke.type)??{};if(!t)return;Ae.p=t;const{pressure:e}=t;Ae.a="custom"!==e.type?f(-1,1):0,Ae.b="custom"!==e.type?f(1,1.5):0,Ae.cp="custom"!==e.type?f(3,3.5):f(-.2,.2),[Ae.min,Ae.max]=e.min_max,ne(),Ne()&&G.blend(D.stroke.color),G.isBrush=!0,Ae.alpha=Me(),Be()}();const i=function(){const{param:t}=fe.get(D.stroke.type)??{};return t?t.spacing:1}(),r=Math.round(le*(e?t:1)/i);for(let n=0;n<r;n++)Pe.length<2*r&&Pe.push(d()),Te(),e?ce.plotTo(he,i,i,t,n<10):ce.moveTo(t,i,i);oe(D.stroke.color),Be()}function Te(t=!1){if(!Ne())return;let e=t||Le();switch(Ae.p.type){case"spray":!function(t){const e=D.stroke.weight*Ae.p.vibration*t+D.stroke.weight*g(Pe)*Ae.p.vibration/3,i=Ae.p.weight*f(.9,1.1),r=Math.ceil(Ae.p.quality/t);for(let t=0;t<r;t++){const t=f(.9,1.1),r=t*e*f(-1,1),n=f(-1,1),s=Math.sqrt((t*e)**2-r**2);se(ce.x+r,ce.y+n*s,i,Ae.alpha)}}(e);break;case"marker":Oe(e);break;case"custom":case"image":!function(t,e,i=!0){G.ctx.save();const r=i?D.stroke.weight*Ae.p.vibration:0,n=i?r*f(-1,1):0,s=i?r*f(-1,1):0;G.ctx.translate(ce.x+n,ce.y+s),function(t){G.ctx.scale(t,t);let e=0;"random"===Ae.p.rotate?e=x(0,ae):"natural"===Ae.p.rotate&&(e=(he?-he.angle(ce.plotted):-ue)+ce.angle(),e=e*Math.PI/180),G.ctx.rotate(e)}(D.stroke.weight*t),Ae.p.tip(G.ctx),G.ctx.restore()}(e);break;default:!function(t,e=1){const i=(e=y(e,0,1,.9,1.05))*D.stroke.weight*Ae.p.vibration*(Ae.p.definition+(1-Ae.p.definition)*g(Pe)*ke(.5,.9,5,.2,1.2)/t);f(0,Ae.p.quality*t)>.4&&se(ce.x+.7*i*f(-1,1),ce.y+i*f(-1,1),t*Ae.p.weight*f(.85,1.15)*D.stroke.weight,Ae.alpha)}(e)}}function Le(){return he?Ce()*he.pressure(ce.plotted):Ce()}function Ce(){return"custom"===Ae.p.pressure.type?y(Ae.p.pressure.curve(ce.plotted/le)+Ae.cp,0,1,Ae.min,Ae.max,!0):ke()}function ke(t=.5+Ae.p.pressure.curve[0]*Ae.a,e=1-Ae.p.pressure.curve[1]*Ae.b,i=Ae.cp,r=Ae.min,n=Ae.max){return y(1/(1+Math.pow(Math.abs((ce.plotted-t*le)/(e*le/2)),2*i)),0,1,r,n)}function Me(){return["default","spray"].includes(Ae.p.type)?Ae.p.opacity*D.stroke.opacity:Ae.p.opacity/D.stroke.weight*D.stroke.opacity}function Ne(){if(D.stroke.clipWindow)return ce.x>=D.stroke.clipWindow[0]&&ce.x<=D.stroke.clipWindow[2]&&ce.y>=D.stroke.clipWindow[1]&&ce.y<=D.stroke.clipWindow[3];{let t=O,e=B,i=.05*O,r=ce.x+V.x,n=ce.y+V.y;return r>=-i&&r<=t+i&&n>=-i&&n<=e+i}}function Oe(t,e=!0,i=Ae.alpha){const r=e?D.stroke.weight*Ae.p.vibration:0,n=e?r*f(-1,1):0,s=e?r*f(-1,1):0;se(ce.x+n,ce.y+s,D.stroke.weight*Ae.p.weight*t,i)}function Be(){if(Ne()){let t=Le(),e=Me();if("marker"===Ae.p.type){for(let i=1;i<10;i++)Oe(t*i/10,!1,5*e);oe(D.stroke.color)}else if("custom"===Ae.p.type||"image"===Ae.p.type)for(let i=1;i<5;i++)G.ctx.beginPath(),Ae.drawCustomOrImage(t*i/5,e,!1),G.ctx.fill()}}function Fe(t,e,i,r){j();let n=T(t,e,i,r);0!=n&&(Se(t,e,n),Ie(L(t,e,i,r),!1))}function Xe(t,e,i,r){j(),Se(t,e,i),Ie(P(r),!1)}const De=["weight","vibration","definition","quality","opacity","spacing","pressure","type","tip","rotate"],ze=[["pen",[.35,.12,.5,8,88,.3,{curve:[.15,.2],min_max:[1.4,.9]}]],["rotring",[.2,.05,.5,30,115,.15,{curve:[.35,.2],min_max:[1.3,.9]}]],["2B",[.25,.7,.45,28,140,.1,{curve:[.15,.2],min_max:[1.3,1]}]],["HB",[.3,.5,.4,4,130,.2,{curve:[.15,.2],min_max:[1.2,.9]}]],["2H",[.2,.4,.3,2,60,.2,{curve:[.15,.2],min_max:[1.2,.9]}]],["cpencil",[.3,.55,.8,7,40,.1,{curve:[.15,.2],min_max:[.95,1.2]}]],["charcoal",[.3,1.3,.8,500,80,.03,{curve:[.15,.2],min_max:[1.5,.9]}]],["spray",[.15,6,15,40,85,.65,{curve:[0,.1],min_max:[.5,1]},"spray"]],["marker",[2.5,.12,null,null,.4,.04,{curve:[.35,.25],min_max:[1.5,1]},"marker"]]];for(let t of ze){let e={};for(let i=0;i<t[1].length;i++)e[De[i]]=t[1][i];xe(t[0],e)}function Ue(){return{...D.hatch}}function Ye(t=5,e=45,i={rand:!1,continuous:!1,gradient:!1}){let r=D.hatch;r.isActive=!0,r.dist=t,r.angle=e,r.options=i}function Ge(t,e="black",i=1){D.hatch.hBrush={brush:t,color:e,weight:i}}function We(){D.hatch.isActive=!1,D.hatch.hBrush=!1}function He(t){let e=D.hatch.dist,i=P(D.hatch.angle)%180,r=D.hatch.options,n=ge();D.hatch.hBrush&&be(...Object.values(D.hatch.hBrush)),Array.isArray(t)||(t=[t]);const s=function(t){let e={minX:Infinity,minY:Infinity,maxX:-Infinity,maxY:-Infinity};for(let i of t){const t=Ze(i);e.minX=Math.min(e.minX,t.minX),e.minY=Math.min(e.minY,t.minY),e.maxX=Math.max(e.maxX,t.maxX),e.maxY=Math.max(e.maxY,t.maxY)}return e}(t);let o=new vt([[s.minX,s.minY],[s.maxX,s.minY],[s.maxX,s.maxY],[s.minX,s.maxY]]),a=i<=90&&i>=0?s.minY:s.maxY,c=r.gradient?y(r.gradient,0,1,1,1.1,!0):1,l=[],h=0,u=e,g=t=>({point1:{x:s.minX+u*t*A(90-i),y:a+u*t*S(90-i)},point2:{x:s.minX+u*t*A(90-i)+A(-i),y:a+u*t*S(90-i)+S(-i)}});for(;o.intersect(g(h)).length>0;){let e=[];for(let i of t)e.push(i.intersect(g(h)));l[h]=e.flat().sort(((t,e)=>t.x===e.x?t.y-e.y:t.x-e.x)),u*=c,h++}let m=l.filter((t=>void 0!==t[0])),x=r.rand||0;for(let t=0;t<m.length;t++){let i=m[t],n=t>0&&r.continuous;for(let r=0;r<i.length-1;r+=2)0!==x&&(i[r].x+=x*e*f(-10,10),i[r].y+=x*e*f(-10,10),i[r+1].x+=x*e*f(-10,10),i[r+1].y+=x*e*f(-10,10)),Fe(i[r].x,i[r].y,i[r+1].x,i[r+1].y),n&&Fe(m[t-1][1].x,m[t-1][1].y,i[r].x,i[r].y)}me(n)}function Ze(t){if(t._boundingBox)return t._boundingBox;let e=Infinity,i=Infinity,r=-Infinity,n=-Infinity;for(let s=0;s<t.a.length;s++){const[o,a]=t.a[s];o<e&&(e=o),o>r&&(r=o),a<i&&(i=a),a>n&&(n=a)}return t._boundingBox={minX:e,minY:i,maxX:r,maxY:n},t._boundingBox}vt.prototype.draw=function(t=!1,e,i){let r=ge();if(t&&be(t,e,i),r.isActive)for(let t of this.sides)Fe(t[0].x,t[0].y,t[1].x,t[1].y);me(r)},bt.prototype.draw=function(t,e,i){ge().isActive&&(this.origin&&(t=this.origin[0],e=this.origin[1],i=1),function(t,e,i,r){j(),Se(e,i,t.length,t),Ie(r,!0)}(this,t,e,i))},D.hatch={isActive:!1,dist:5,angle:45,options:{},hBrush:!1},vt.prototype.hatch=function(t=!1,e,i){let r=Ue();t&&Ye(t,e,i),r.isActive&&He(this),function(t){D.hatch={...t}}(r)},bt.prototype.hatch=function(t,e,i){Ue().isActive&&(this.origin&&(t=this.origin[0],e=this.origin[1],i=1),this.pol=this.genPol(t,e,i,.25),this.pol.hatch())},D.fill={color:new U("#002185"),opacity:60,bleed_strength:.07,texture_strength:.8,border_strength:.5,direction:"out",isActive:!1};const Ve=()=>({...D.fill});function qe(t,e,i,r){D.fill.opacity=(arguments.length<4?e:r)||60,D.fill.color=arguments.length<3?new U(t):new U(t,e,i),D.fill.isActive=!0}function $e(t,e="out"){D.fill.bleed_strength=_(t,0,1),D.fill.direction=e}function je(t=.4,e=.4){D.fill.texture_strength=_(t,0,1),D.fill.border_strength=_(e,0,1)}function Ke(){D.fill.isActive=!1}let Je;const Qe=[[],[]];class ti{constructor(t,e,i,r=[],n=!1,s,o){if(this.v=t,this.m=e,this.dir=r,this.midP=i,n){let e=0,r=0;const n=[];for(let s=0;s<t.length;s++){const o=Math.abs(i.x-t[s].x),a=Math.abs(i.y-t[s].y);e=Math.max(e,o),r=Math.max(r,a);const c=t[s],l=t[(s+1)%t.length],h={x:l.x-c.x,y:l.y-c.y},u=I(0,0,h.x,h.y,90),f={x:c.x+h.x/2,y:c.y+h.y/2};n.push({v1:c,v2:l,ray:{point1:f,point2:{x:f.x+u.x,y:f.y+u.y}}})}this.sizeX=e,this.sizeY=r,this.dir=Array(t.length),n.forEach(((t,e)=>{let i=0;for(const e of Je.intersect(t.ray))r=t.v1,s=e,((n=t.v2).x-r.x)*(s.y-r.y)-(n.y-r.y)*(s.x-r.x)>.01&&i++;var r,n,s;this.dir[e]=i%2==0}));const s=f(-.6,.6)*e,o=f(-.6,.6)*r;this.midP={x:i.x+s,y:i.y+o}}else this.sizeX=s,this.sizeY=o}trim(t=1){if(t>=1||t<0||this.v.length<=8)return{v:[...this.v],m:[...this.m],dir:[...this.dir]};const e=~~((1-t)*this.v.length),i=~~(this.v.length/2-e/2),r=[...this.v],n=[...this.m],s=[...this.dir];return r.splice(i,e),n.splice(i,e),s.splice(i,e),{v:r,m:n,dir:s}}grow(t=1){const{v:e,m:i,dir:r}=this.trim(t),n=e.length,s=[],o=[],a=[],c="out"===D.fill.direction?-90:90;let l=0,h=999===t?f(.6,.8):D.fill.bleed_strength;for(let u=0;u<n;u++){Qe[0].length<1.5*n&&(Qe[0].push(d(.5,.2)),Qe[1].push(d(0,.02)));const m=e[u],x=u+1<n?e[u+1]:e[0];t<997&&(h=i[u]);const p=(r[u]?c:-c)+5*f(-1,1),y=x.x-m.x,_=x.y-m.y,{x:v,y:b}=I(0,0,y,_,p),E=.5,R=g(Qe[0])*f(.65,1.35)*h;s[l]=m,o[l]=i[u],a[l++]=r[u],s[l]={x:m.x+y*E+v*R,y:m.y+_*E+b*R},o[l]=i[u]+g(Qe[1]),a[l++]=r[u]}return new ti(s,o,this.midP,a,!1,this.sizeX,this.sizeY)}fill(t,e,i){const r=3*i,n=2*e*(1+i/2);G.blend(t),G.ctx.save(),G.ctx.strokeStyle=`rgb(255 0 0 / ${.01*D.fill.border_strength})`,G.ctx.lineCap="round";const s=Math.max(this.sizeX,this.sizeY),o=f(.15,.7);let a,c=this.grow();for(let i=0;i<20;i++){i%4==0&&(c=c.grow()),i%2==0&&(a=[c.grow(1-.0125*i),c.grow(.7-.0125*i),c.grow(.4-.0125*i)]);for(const t of a)t.grow(999).grow(997).layer(i,s,n);i%2==0&&c.grow(o).grow(999).layer(i,s,2*n),i%5!=0&&19!==i||(0!==r&&c.erase(3*r,e),G.blend(t,!0,!1,!0))}G.ctx.restore()}layer(t,e,i){G.ctx.lineWidth=y(t,0,24,e/25,e/30,!0),G.ctx.fillStyle=`rgb(255 0 0 / ${i}%)`,mt(this.v),G.ctx.fill(),G.ctx.stroke()}erase(t,e){G.ctx.save();const i=~~(f(80,110)*y(t,0,1,2,3.5)),r=this.sizeX/1.3,n=this.sizeY/1.3,s=Math.min(this.sizeX,this.sizeY)*(1.4-D.fill.bleed_strength),o=.05*s,a=.4*s,{x:c,y:l}=this.midP;G.ctx.globalCompositeOperation="destination-out";const h=(5-y(e,80,100,.3,.7,!0))*t/255;G.ctx.fillStyle=`rgb(255 0 0 / ${h})`,G.ctx.lineWidth=0;for(let t=0;t<i;t++){const e=c+d(0,r),i=l+d(0,n),s=f(o,a);G.ctx.beginPath(),xt(e,i,s),t%5!=0&&G.ctx.fill()}G.ctx.globalCompositeOperation="source-over",G.ctx.restore()}}function ei(t,e){const i=document.createElement("canvas");i.width=t,i.height=e,document.getElementsByTagName("body")[0].appendChild(i),i.style.maxWidth="100%",i.style.maxHeight="100%",i.style.width="auto",i.style.height="auto",i.style.objectFit="contain",F(i.id,i)}vt.prototype.fill=function(t=!1,e,i,r,n,s){let o=Ve();t&&(qe(t,e),$e(i,s),je(r,n)),o.isActive&&(j(),function(t){Je=t;const e=[...t.vertices],i=~~(.25*e.length*p({1:5,2:10,3:60})),r=D.fill.bleed_strength,n=e.map(((t,e)=>(e>i?1:.3)*f(.85,1.2)*r)),s=x(0,e.length),o=[...e.slice(s),...e.slice(0,s)],a=function(t){if(t.length<8)return t.reduce(((t,e)=>({x:t.x+e.x,y:t.y+e.y})),{x:0,y:0}).map((e=>e/t.length));const e=[...t];e[0].x===e[e.length-1].x&&e[0].y===e[e.length-1].y||e.push(e[0]);let i=0,r=0,n=0;for(let t=0;t<e.length-1;t++){const s=e[t].x*e[t+1].y-e[t+1].x*e[t].y;i+=s,r+=(e[t].x+e[t+1].x)*s,n+=(e[t].y+e[t+1].y)*s}return i*=.5,i?{x:r/(6*i),y:n/(6*i)}:{x:e[0].x,y:e[0].y}}(o);new ti(o,n,a,[],!0).fill(D.fill.color,y(D.fill.opacity,0,100,0,1,!0),D.fill.texture_strength)}(this)),(t=>{D.fill={...t}})(o)},bt.prototype.fill=function(t,e,i){Ve().isActive&&(this.origin&&(t=this.origin[0],e=this.origin[1],i=1),this.pol=this.genPol(t,e,i,y(D.fill.bleed_strength,0,.6,.3,.45,!0)),this.pol.fill())};export{U as Color,bt as Plot,vt as Polygon,K as Position,xe as add,ct as addField,At as arc,H as background,kt as beginPath,Ft as beginStroke,de as box,wt as circle,Re as clip,Ot as closePath,ei as createCanvas,Kt as draw,Z as drawImage,Bt as endPath,Dt as endStroke,pt as erase,ot as field,$e as fillBleed,qe as fillStyle,je as fillTexture,Zt as frameCount,$t as frameRate,Ye as hatch,He as hatchArray,Ge as hatchStyle,Fe as line,Nt as lineTo,ve as lineWidth,lt as listFields,F as load,Vt as loop,Xt as move,Mt as moveTo,we as noClip,yt as noErase,at as noField,Ke as noFill,We as noHatch,qt as noLoop,Ee as noStroke,h as noise,u as noiseSeed,ye as pick,Et as polygon,m as random,Rt as rect,nt as refreshField,gt as restore,ft as save,pe as scaleBrushes,l as seed,be as set,zt as spline,Xe as stroke,_e as strokeStyle,q as translate,p as wRand,ht as wiggle}; //# sourceMappingURL=brush.esm.js.map