@acamposuribe/brush
Version:
Unlock custom brushes, natural fill effects and intuitive hatching in vanilla js
3 lines (2 loc) • 38.2 kB
JavaScript
var t,e;t=this,e=function(t){const e=Math.sqrt(3),i=.5*(e-1),r=(3-e)/6,n=t=>0|Math.floor(t),o=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 e=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),s=new Float64Array(e).map((t=>o[t%12*2])),a=new Float64Array(e).map((t=>o[t%12*2+1]));return function(t,o){let c=0,l=0,h=0;const u=(t+o)*i,f=n(t+u),g=n(o+u),m=(f+g)*r,x=t-(f-m),d=o-(g-m);let p,y;x>d?(p=1,y=0):(p=0,y=1);const v=x-p+r,_=d-y+r,b=x-1+2*r,E=d-1+2*r,w=255&f,R=255&g;let A=.5-x*x-d*d;if(A>=0){const t=w+e[R];A*=A,c=A*A*(s[t]*x+a[t]*d)}let S=.5-v*v-_*_;if(S>=0){const t=w+p+e[R+y];S*=S,l=S*S*(s[t]*v+a[t]*_)}let P=.5-b*b-E*E;if(P>=0){const t=w+1+e[R+1];P*=P,h=P*P*(s[t]*b+a[t]*E)}return 70*(c+l+h)}}function a(t,e){let i=new c(t),r=()=>i.next();return r.double=()=>r()+11102230246251565e-32*(2097152*r()|0),r.int32=()=>4294967296*i.next()|0,r.quick=r,r}class c{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 l=a(Math.random());t.noise=s(a(Math.random()));const h=(t=0,e=1)=>t+l()*(e-t),u=t=>t[~~(l()*t.length)],f=(t,e)=>~~h(t,e),g=(t=0,e=1)=>{const i=1-l(),r=l();return Math.sqrt(-2*Math.log(i))*E(360*r)*e+t},m=t=>{let e=0;const i=[];for(const r in t)e+=t[r],i.push({key:r,cumulative:e});const r=l()*e;for(const{key:t,cumulative:e}of i)if(r<e)return isNaN(t)?t:parseInt(t)},x=(t,e,i,r,n,o=!1)=>{let s=r+(t-e)/(i-e)*(n-r);return o?r<n?d(s,r,n):d(s,n,r):s},d=(t,e,i)=>Math.max(Math.min(t,i),e),p=t=>(t%=360)<0?t+360:t,y=1440,v=2*Math.PI/y,_=new Float32Array(y).fill(NaN),b=new Float32Array(y).fill(NaN),E=t=>{const e=~~(4*p(t));let i=_[e];return isNaN(i)&&(i=Math.cos(e*v),_[e]=i),i},w=t=>{const e=~~(4*p(t));let i=b[e];return isNaN(i)&&(i=Math.sin(e*v),b[e]=i),i},R=t=>{let e=180*t/Math.PI%360;return e<0?e+360:e},A=(t,e,i,r,n)=>{let o=E(n),s=w(n);return{x:o*(i-t)+s*(r-e)+t,y:o*(r-e)-s*(i-t)+e}},S=(t,e,i,r)=>Math.hypot(i-t,r-e),P=(t,e,i,r)=>R(Math.atan2(-(r-e),i-t)),I=(t,e,i,r,n=!1)=>{let o=t.x,s=t.y,a=e.x,c=e.y,l=i.x,h=i.y,u=r.x,f=r.y;if(o===a&&s===c||l===u&&h===f)return!1;let g=a-o,m=c-s,x=u-l,d=f-h,p=d*g-x*m;if(0===p)return!1;let y=(x*(s-h)-d*(o-l))/p,v=(g*(s-h)-m*(o-l))/p;return!(!n&&(v<0||v>1))&&{x:o+y*g,y:s+y*m}},T=()=>{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 o(t,i){e.activeTexture(t),e.bindTexture(e.TEXTURE_2D,i)}function s(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(s){t=s,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),o(e.TEXTURE0,i.source.texture),o(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),s(i.target.fbo,i.source.fbo),t.isLast&&!t.sp&&s(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 L={};let C,k,M;const N=(t,e)=>{C=t,L[C]||(L[C]={canvas:e}),k=e.width,M=e.height,O=!0,z.load()};let O=!1;const F={},B=document.createElement("canvas").getContext("2d");class X{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=d(t,0,255),this.g=d(e||t,0,255),this.b=d(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=>(B.fillStyle=t,B.fillStyle)}const D=()=>{z.loaded||((()=>{if(!O)throw new Error("Call `load()` first")})(),z.load())},z={loaded:!1,isBlending:!1,load(){const t=L[C];t.worker||(t.mask=new OffscreenCanvas(k,M),t.glMask=new OffscreenCanvas(k,M),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(T),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(D(),!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 U=new X("white");const Y={x:0,y:0};let G=!1;function W(){G||(D(),Z=.01*k,V=-.5*k,j=-.5*M,q=Math.round(2*k/Z),$=Math.round(2*M/Z),tt("hand",(function(e,i){const r=h(.2,.8),n=f(5,10);for(let o=0;o<q;o++){const s=o;for(let a=0;a<$;a++){const c=f(15,25),l=.5*n*w(r*a*o+c),h=t.noise(s,a);i[o][a]=.2*l*E(e)+h*n*.7}}return i})),G=!0)}class H{constructor(t,e){W(),this.update(t,e),this.plotted=0}update(t,e){this.x=t,this.y=e,this.colIdx=H.getColIndex(t),this.rowIdx=H.getRowIndex(e)}reset(){this.plotted=0}isIn(){return F.field.isActive?H.isIn(this.colIdx,this.rowIdx):this.isInCanvas(this.x,this.y)}isInCanvas(){const t=k,e=M,i=this.x+Y.x,r=this.y+Y.y;return i>=-.3*t&&i<=1.3*t&&r>=-.3*e&&r<=1.3*e}angle(){return this.isIn()&&F.field.isActive?K.get(F.field.current).field[this.colIdx][this.rowIdx]*F.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 o=0;o<e/i;o++){const e=this.angle()-(r?t.angle(this.plotted):t);this.update(this.x+i*E(e),this.y+i*w(e)),this.plotted+=i/n}else this.plotted+=i/n}static getRowIndex(t,e=1){const i=t+Y.y-j;return Math.round(i/Z/e)}static getColIndex(t,e=1){const i=t+Y.x-V;return Math.round(i/Z/e)}static isIn(t,e){return t>=0&&e>=0&&t<q&&e<$}}F.field={isActive:!1,current:null,wiggle:1};let Z,V,j,q,$,K=new Map;function J(){return new Array(q).fill(null).map((()=>new Float32Array($)))}function Q(t){if(F.field.wiggle||(F.field.wiggle=1),W(),!K.has(t))throw new Error(`Field "${name}" does not exist.`);F.field.isActive=!0,F.field.current=t}function tt(t,e){K.set(t,{gen:e}),K.get(t).field=K.get(t).gen(0,J())}let et={};function it(t){z.ctx.beginPath(),t.forEach(((t,e)=>{0===e?z.ctx.moveTo(t.x,t.y):z.ctx.lineTo(t.x,t.y)})),z.ctx.closePath()}function rt(t,e,i){const r=2*Math.PI,n=i/2;z.ctx.moveTo(t+n,e),z.ctx.arc(t,e,n,0,r)}const nt={isActive:!1,c:null,a:255};function ot(t){z.blend(nt.c),z.isErase=!0,z.ctx.save(),z.ctx.fillStyle="rgb(255 0 0 / "+nt.a+"%)",it(t),z.ctx.fill(),z.ctx.restore()}class st{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=I(t.point1,t.point2,e,r);n&&i.push(n)}return this._intersectionCache[e]=i,i}erase(){ot(this.vertices)}show(){nt.isActive?this.erase():(F.draw&&this.draw(),F.hatch&&this.hatch(),F.fill&&this.fill())}}class at{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:R(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:R(t),this.angles[this.angles.length-1]=t,this.pres.push(e)}rotate(t){this.dir=R(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)),x(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){W();const n=.5,o=[],s=Math.round(this.length/n),a=new H(t,e);let c=0,l=0;for(let t=0;t<s;t++){a.plotTo(this,n,n);const t=this.calcIndex(a.plotted);c+=n,(c>=Math.max(this.segments[t]*r*h(.7,1.3),10)||t>=l)&&a.x&&(o.push([a.x,a.y]),c=0,t>=l&&l++)}return new st(o)}erase(t,e,i){this.origin&&([t,e,i]=[...this.origin,1]),this.pol=this.genPol(t,e,i,.15),ot(this.pol.vertices)}show(t,e,i=1){nt.isActive?this.erase():(F.stroke&&this.draw(t,e,i),F.hatch&&this.hatch(t,e,i),F.fill&&this.fill(t,e,i))}}let ct,lt,ht,ut,ft;class gt{constructor(){this.isClosed=!1,this.curvature=ht,this.vert=[]}vertex(t,e,i){this.vert.push([t,e,i])}show(){vt(this.vert,this.curvature,this.isClosed).show()}}function mt(t=0){ht=d(t,0,1),ct=[]}function xt(t,e,i=1){lt=new gt,ct.push(lt),lt.vertex(t,e,i)}function dt(t,e,i=1){lt.vertex(t,e,i)}function pt(){lt.vertex(...lt.vert[0]),lt.isClosed=!0}function yt(){for(let t of ct)t.show();ct=!1}function vt(t,e=.5,i=!1){const r=new at(0===e?"segments":"curve"),n=2*Math.PI;if(i&&0!==e&&t.push(t[1]),t&&t.length>0){let o,s,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=S(h[0],h[1],u[0],u[1]),m=S(u[0],u[1],f[0],f[1]),x=P(h[0],h[1],u[0],u[1]),d=P(u[0],u[1],f[0],f[1]),p=e*Math.min(g,m,.5*Math.min(g,m)),y=Math.max(g,m),v=g-p,_=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&&(o=g,a=p,s=t[1],c=0)}else{const e={x:u[0]-p*E(-x),y:u[1]-p*w(-x)},f={x:e.x+y*E(90-x),y:e.y+y*w(90-x)},g={x:u[0]+p*E(-d),y:u[1]+p*w(-d)},m={x:g.x+y*E(90-d),y:g.y+y*w(90-d)},b=I(e,f,g,m,!0),R=S(e.x,e.y,b.x,b.y),A=S(e.x,e.y,g.x,g.y)/2,P=n*R*(2*Math.asin(A/R)*(180/Math.PI))/360,T=i&&0===l?0:v-c,L=l===t.length-3?i?o-p:_:0;r.addSegment(x,T,h[2],!0),r.addSegment(x,isNaN(P)?0:P,h[2],!0),r.addSegment(d,L,u[2],!0),c=p,0===l&&(o=v,a=p,s=[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=S(e[0],e[1],i[0],i[1]),o=P(e[0],e[1],i[0],i[1]);r.addSegment(o,n,i[2],!0),l===t.length-2&&r.endPlot(o,1,!0)}r.origin=i&&0!==e?s:t[0]}return r}let _t,bt=0,Et=!1,wt=30;t.frameCount=0;let Rt=t=>(t&&(wt=t),wt);function At(e){Et&&(e>bt+1e3/Rt()||0===e)&&(bt=e,t.frameCount++,_t&&_t(),St()),requestAnimationFrame(At)}function St(){z.blend(!1,!0)}let Pt,It,Tt=!1;const Lt={},Ct={},kt=[];function Mt(){if(!Tt){D(),Pt=z.gl,It=new Float32Array([2/k,0,0,0,0,-2/M,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})(Pt);Pt.useProgram(t),Pt.enable(Pt.BLEND),Pt.blendFunc(Pt.ONE_MINUS_DST_ALPHA,Pt.ONE),["a_position","a_radius","a_alpha"].forEach((e=>Lt[e]=Pt.getAttribLocation(t,e))),["u_matrix"].forEach((e=>Ct[e]=Pt.getUniformLocation(t,e))),Tt=!0}}function Nt(t,e,i,r){Mt(),kt.push({x:t+Y.x,y:e+Y.y,radius:i/2,alpha:r/100})}function Ot(){if(0===kt.length)return;const t=new Float32Array(4*kt.length);kt.forEach(((e,i)=>{const r=4*i;t.set([e.x,e.y,e.radius,e.alpha],r)})),kt.length=0;const e=Pt.createVertexArray();Pt.bindVertexArray(e);const i=Pt.createBuffer();Pt.bindBuffer(Pt.ARRAY_BUFFER,i),Pt.bufferData(Pt.ARRAY_BUFFER,t,Pt.STATIC_DRAW),Pt.enableVertexAttribArray(Lt.a_position),Pt.vertexAttribPointer(Lt.a_position,2,Pt.FLOAT,!1,16,0),Pt.enableVertexAttribArray(Lt.a_radius),Pt.vertexAttribPointer(Lt.a_radius,1,Pt.FLOAT,!1,16,8),Pt.enableVertexAttribArray(Lt.a_alpha),Pt.vertexAttribPointer(Lt.a_alpha,1,Pt.FLOAT,!1,16,12),Pt.uniformMatrix4fv(Ct.u_matrix,!1,It),Pt.drawArrays(Pt.POINTS,0,t.length/4),Pt.bindVertexArray(null),Pt.deleteBuffer(i),Pt.deleteVertexArray(e)}const Ft=2*Math.PI;F.stroke={color:new X("black"),weight:1,clipWindow:null,type:"HB",isActive:!1,opacity:1};let Bt,Xt,Dt,zt,Ut=new Map;function Yt(){return{...F.stroke}}function Gt(t){F.stroke={...t}}function Wt(t,e){e.type=["marker","custom","image","spray"].includes(e.type)?e.type:"default",Ut.set(t,{param:e,colors:[],buffers:[]})}function Ht(t){Ut.has(t)&&(F.stroke.type=t)}function Zt(t,e,i){F.stroke.color=new X(...arguments),F.stroke.isActive=!0}function Vt(t){F.stroke.weight=t}function jt(t,e,i=1){Ht(t),Zt(e),Vt(i)}const qt={};function $t(t,e,i,r=!1){Bt=new H(t,e),Xt=i,Dt=r,Dt&&Dt.calcIndex(0)}const Kt=[];function Jt(t,e){e||(zt=t),function(){qt.seed=99999*h();const{param:t}=Ut.get(F.stroke.type)??{};if(!t)return;qt.p=t;const{pressure:e}=t;qt.a="custom"!==e.type?h(-1,1):0,qt.b="custom"!==e.type?h(1,1.5):0,qt.cp="custom"!==e.type?h(3,3.5):h(-.2,.2),[qt.min,qt.max]=e.min_max,Mt(),ne()&&z.blend(F.stroke.color),z.isBrush=!0,qt.alpha=re(),se()}();const i=function(){const{param:t}=Ut.get(F.stroke.type)??{};return t?t.spacing:1}(),r=Math.round(Xt*(e?t:1)/i);for(let n=0;n<r;n++)Kt.length<2*r&&Kt.push(g()),Qt(),e?Bt.plotTo(Dt,i,i,t,n<10):Bt.moveTo(t,i,i);Ot(F.stroke.color),se()}function Qt(t=!1){if(!ne())return;let e=t||te();switch(qt.p.type){case"spray":!function(t){const e=F.stroke.weight*qt.p.vibration*t+F.stroke.weight*u(Kt)*qt.p.vibration/3,i=qt.p.weight*h(.9,1.1),r=Math.ceil(qt.p.quality/t);for(let t=0;t<r;t++){const t=h(.9,1.1),r=t*e*h(-1,1),n=h(-1,1),o=Math.sqrt((t*e)**2-r**2);Nt(Bt.x+r,Bt.y+n*o,i,qt.alpha)}}(e);break;case"marker":oe(e);break;case"custom":case"image":!function(t,e,i=!0){z.ctx.save();const r=i?F.stroke.weight*qt.p.vibration:0,n=i?r*h(-1,1):0,o=i?r*h(-1,1):0;z.ctx.translate(Bt.x+n,Bt.y+o),function(t){z.ctx.scale(t,t);let e=0;"random"===qt.p.rotate?e=f(0,Ft):"natural"===qt.p.rotate&&(e=(Dt?-Dt.angle(Bt.plotted):-zt)+Bt.angle(),e=e*Math.PI/180),z.ctx.rotate(e)}(F.stroke.weight*t),qt.p.tip(z.ctx),z.ctx.restore()}(e);break;default:!function(t,e=1){const i=(e=x(e,0,1,.9,1.05))*F.stroke.weight*qt.p.vibration*(qt.p.definition+(1-qt.p.definition)*u(Kt)*ie(.5,.9,5,.2,1.2)/t);h(0,qt.p.quality*t)>.4&&Nt(Bt.x+.7*i*h(-1,1),Bt.y+i*h(-1,1),t*qt.p.weight*h(.85,1.15)*F.stroke.weight,qt.alpha)}(e)}}function te(){return Dt?ee()*Dt.pressure(Bt.plotted):ee()}function ee(){return"custom"===qt.p.pressure.type?x(qt.p.pressure.curve(Bt.plotted/Xt)+qt.cp,0,1,qt.min,qt.max,!0):ie()}function ie(t=.5+qt.p.pressure.curve[0]*qt.a,e=1-qt.p.pressure.curve[1]*qt.b,i=qt.cp,r=qt.min,n=qt.max){return x(1/(1+Math.pow(Math.abs((Bt.plotted-t*Xt)/(e*Xt/2)),2*i)),0,1,r,n)}function re(){return["default","spray"].includes(qt.p.type)?qt.p.opacity*F.stroke.opacity:qt.p.opacity/F.stroke.weight*F.stroke.opacity}function ne(){if(F.stroke.clipWindow)return Bt.x>=F.stroke.clipWindow[0]&&Bt.x<=F.stroke.clipWindow[2]&&Bt.y>=F.stroke.clipWindow[1]&&Bt.y<=F.stroke.clipWindow[3];{let t=k,e=M,i=.05*k,r=Bt.x+Y.x,n=Bt.y+Y.y;return r>=-i&&r<=t+i&&n>=-i&&n<=e+i}}function oe(t,e=!0,i=qt.alpha){const r=e?F.stroke.weight*qt.p.vibration:0,n=e?r*h(-1,1):0,o=e?r*h(-1,1):0;Nt(Bt.x+n,Bt.y+o,F.stroke.weight*qt.p.weight*t,i)}function se(){if(ne()){let t=te(),e=re();if("marker"===qt.p.type){for(let i=1;i<10;i++)oe(t*i/10,!1,5*e);Ot(F.stroke.color)}else if("custom"===qt.p.type||"image"===qt.p.type)for(let i=1;i<5;i++)z.ctx.beginPath(),qt.drawCustomOrImage(t*i/5,e,!1),z.ctx.fill()}}function ae(t,e,i,r){W();let n=S(t,e,i,r);0!=n&&($t(t,e,n),Jt(P(t,e,i,r),!1))}const ce=["weight","vibration","definition","quality","opacity","spacing","pressure","type","tip","rotate"],le=[["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 le){let e={};for(let i=0;i<t[1].length;i++)e[ce[i]]=t[1][i];Wt(t[0],e)}function he(){return{...F.hatch}}function ue(t=5,e=45,i={rand:!1,continuous:!1,gradient:!1}){let r=F.hatch;r.isActive=!0,r.dist=t,r.angle=e,r.options=i}function fe(t){let e=F.hatch.dist,i=R(F.hatch.angle)%180,r=F.hatch.options,n=Yt();F.hatch.hBrush&&jt(...Object.values(F.hatch.hBrush)),Array.isArray(t)||(t=[t]);const o=function(t){let e={minX:Infinity,minY:Infinity,maxX:-Infinity,maxY:-Infinity};for(let i of t){const t=ge(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 s=new st([[o.minX,o.minY],[o.maxX,o.minY],[o.maxX,o.maxY],[o.minX,o.maxY]]),a=i<=90&&i>=0?o.minY:o.maxY,c=r.gradient?x(r.gradient,0,1,1,1.1,!0):1,l=[],u=0,f=e,g=t=>({point1:{x:o.minX+f*t*E(90-i),y:a+f*t*w(90-i)},point2:{x:o.minX+f*t*E(90-i)+E(-i),y:a+f*t*w(90-i)+w(-i)}});for(;s.intersect(g(u)).length>0;){let e=[];for(let i of t)e.push(i.intersect(g(u)));l[u]=e.flat().sort(((t,e)=>t.x===e.x?t.y-e.y:t.x-e.x)),f*=c,u++}let m=l.filter((t=>void 0!==t[0])),d=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!==d&&(i[r].x+=d*e*h(-10,10),i[r].y+=d*e*h(-10,10),i[r+1].x+=d*e*h(-10,10),i[r+1].y+=d*e*h(-10,10)),ae(i[r].x,i[r].y,i[r+1].x,i[r+1].y),n&&ae(m[t-1][1].x,m[t-1][1].y,i[r].x,i[r].y)}Gt(n)}function ge(t){if(t._boundingBox)return t._boundingBox;let e=Infinity,i=Infinity,r=-Infinity,n=-Infinity;for(let o=0;o<t.a.length;o++){const[s,a]=t.a[o];s<e&&(e=s),s>r&&(r=s),a<i&&(i=a),a>n&&(n=a)}return t._boundingBox={minX:e,minY:i,maxX:r,maxY:n},t._boundingBox}st.prototype.draw=function(t=!1,e,i){let r=Yt();if(t&&jt(t,e,i),r.isActive)for(let t of this.sides)ae(t[0].x,t[0].y,t[1].x,t[1].y);Gt(r)},at.prototype.draw=function(t,e,i){Yt().isActive&&(this.origin&&(t=this.origin[0],e=this.origin[1],i=1),function(t,e,i,r){W(),$t(e,i,t.length,t),Jt(r,!0)}(this,t,e,i))},F.hatch={isActive:!1,dist:5,angle:45,options:{},hBrush:!1},st.prototype.hatch=function(t=!1,e,i){let r=he();t&&ue(t,e,i),r.isActive&&fe(this),function(t){F.hatch={...t}}(r)},at.prototype.hatch=function(t,e,i){he().isActive&&(this.origin&&(t=this.origin[0],e=this.origin[1],i=1),this.pol=this.genPol(t,e,i,.25),this.pol.hatch())},F.fill={color:new X("#002185"),opacity:60,bleed_strength:.07,texture_strength:.8,border_strength:.5,direction:"out",isActive:!1};const me=()=>({...F.fill});function xe(t,e,i,r){F.fill.opacity=(arguments.length<4?e:r)||60,F.fill.color=arguments.length<3?new X(t):new X(t,e,i),F.fill.isActive=!0}function de(t,e="out"){F.fill.bleed_strength=d(t,0,1),F.fill.direction=e}function pe(t=.4,e=.4){F.fill.texture_strength=d(t,0,1),F.fill.border_strength=d(e,0,1)}let ye;const ve=[[],[]];class _e{constructor(t,e,i,r=[],n=!1,o,s){if(this.v=t,this.m=e,this.dir=r,this.midP=i,n){let e=0,r=0;const n=[];for(let o=0;o<t.length;o++){const s=Math.abs(i.x-t[o].x),a=Math.abs(i.y-t[o].y);e=Math.max(e,s),r=Math.max(r,a);const c=t[o],l=t[(o+1)%t.length],h={x:l.x-c.x,y:l.y-c.y},u=A(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 ye.intersect(t.ray))r=t.v1,o=e,((n=t.v2).x-r.x)*(o.y-r.y)-(n.y-r.y)*(o.x-r.x)>.01&&i++;var r,n,o;this.dir[e]=i%2==0}));const o=h(-.6,.6)*e,s=h(-.6,.6)*r;this.midP={x:i.x+o,y:i.y+s}}else this.sizeX=o,this.sizeY=s}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],o=[...this.dir];return r.splice(i,e),n.splice(i,e),o.splice(i,e),{v:r,m:n,dir:o}}grow(t=1){const{v:e,m:i,dir:r}=this.trim(t),n=e.length,o=[],s=[],a=[],c="out"===F.fill.direction?-90:90;let l=0,f=999===t?h(.6,.8):F.fill.bleed_strength;for(let m=0;m<n;m++){ve[0].length<1.5*n&&(ve[0].push(g(.5,.2)),ve[1].push(g(0,.02)));const x=e[m],d=m+1<n?e[m+1]:e[0];t<997&&(f=i[m]);const p=(r[m]?c:-c)+5*h(-1,1),y=d.x-x.x,v=d.y-x.y,{x:_,y:b}=A(0,0,y,v,p),E=.5,w=u(ve[0])*h(.65,1.35)*f;o[l]=x,s[l]=i[m],a[l++]=r[m],o[l]={x:x.x+y*E+_*w,y:x.y+v*E+b*w},s[l]=i[m]+u(ve[1]),a[l++]=r[m]}return new _e(o,s,this.midP,a,!1,this.sizeX,this.sizeY)}fill(t,e,i){const r=3*i,n=2*e*(1+i/2);z.blend(t),z.ctx.save(),z.ctx.strokeStyle=`rgb(255 0 0 / ${.01*F.fill.border_strength})`,z.ctx.lineCap="round";const o=Math.max(this.sizeX,this.sizeY),s=h(.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,o,n);i%2==0&&c.grow(s).grow(999).layer(i,o,2*n),i%5!=0&&19!==i||(0!==r&&c.erase(3*r,e),z.blend(t,!0,!1,!0))}z.ctx.restore()}layer(t,e,i){z.ctx.lineWidth=x(t,0,24,e/25,e/30,!0),z.ctx.fillStyle=`rgb(255 0 0 / ${i}%)`,it(this.v),z.ctx.fill(),z.ctx.stroke()}erase(t,e){z.ctx.save();const i=~~(h(80,110)*x(t,0,1,2,3.5)),r=this.sizeX/1.3,n=this.sizeY/1.3,o=Math.min(this.sizeX,this.sizeY)*(1.4-F.fill.bleed_strength),s=.05*o,a=.4*o,{x:c,y:l}=this.midP;z.ctx.globalCompositeOperation="destination-out";const u=(5-x(e,80,100,.3,.7,!0))*t/255;z.ctx.fillStyle=`rgb(255 0 0 / ${u})`,z.ctx.lineWidth=0;for(let t=0;t<i;t++){const e=c+g(0,r),i=l+g(0,n),o=h(s,a);z.ctx.beginPath(),rt(e,i,o),t%5!=0&&z.ctx.fill()}z.ctx.globalCompositeOperation="source-over",z.ctx.restore()}}st.prototype.fill=function(t=!1,e,i,r,n,o){let s=me();t&&(xe(t,e),de(i,o),pe(r,n)),s.isActive&&(W(),function(t){ye=t;const e=[...t.vertices],i=~~(.25*e.length*m({1:5,2:10,3:60})),r=F.fill.bleed_strength,n=e.map(((t,e)=>(e>i?1:.3)*h(.85,1.2)*r)),o=f(0,e.length),s=[...e.slice(o),...e.slice(0,o)],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 o=e[t].x*e[t+1].y-e[t+1].x*e[t].y;i+=o,r+=(e[t].x+e[t+1].x)*o,n+=(e[t].y+e[t+1].y)*o}return i*=.5,i?{x:r/(6*i),y:n/(6*i)}:{x:e[0].x,y:e[0].y}}(s);new _e(s,n,a,[],!0).fill(F.fill.color,x(F.fill.opacity,0,100,0,1,!0),F.fill.texture_strength)}(this)),(t=>{F.fill={...t}})(s)},at.prototype.fill=function(t,e,i){me().isActive&&(this.origin&&(t=this.origin[0],e=this.origin[1],i=1),this.pol=this.genPol(t,e,i,x(F.fill.bleed_strength,0,.6,.3,.45,!0)),this.pol.fill())},t.Color=X,t.Plot=at,t.Polygon=st,t.Position=H,t.add=Wt,t.addField=tt,t.arc=function(t,e,i,r,n){const o=new at("curve"),s=270-R(r),a=270-R(n),c=R(n-r),l=Math.PI*i*c/180;o.addSegment(s,l,1,!0),o.endPlot(a,1,!0);const h=t+i*E(-s-90),u=e+i*w(-s-90);o.draw(h,u,1)},t.background=(...t)=>{D(),U=new X(...t),z.worker.postMessage({color:U.gl,isBG:!0})},t.beginPath=mt,t.beginStroke=function(t,e,i){ft=[e,i],ut=new at(t)},t.box=function(){return[...Ut.keys()]},t.circle=function(t,e,i,r=!1){const n=new at("curve"),o=Math.PI*i,s=h(0,360),a=r?()=>1+.2*h():()=>1;for(let t=0;t<4;t++){const e=-90*t+s;n.addSegment(e*a(),o/2*a(),1,!0)}if(r){const t=f(-5,5);n.addSegment(s,Math.abs(t)*(Math.PI/180)*i,1,!0),n.endPlot(t+s,1,!0)}else n.endPlot(s,1,!0);const c=t-i*w(s),l=e-i*E(-s);n.show(c,l,1)},t.clip=function(t){F.stroke.clipWindow=t},t.closePath=pt,t.createCanvas=function(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",N(i.id,i)},t.draw=St,t.drawImage=(t,...e)=>{D(),z.ctx.drawImage(t,...e),t=z.mask.transferToImageBitmap(),z.blend(!1,!1,t)},t.endPath=yt,t.endStroke=function(t,e){ut.endPlot(t,e),ut.draw(ft[0],ft[1],1),ut=!1},t.erase=function(t=_bg_Color,e=255){nt.isActive=!0,nt.c=new X(t),nt.a=e},t.field=Q,t.fillBleed=de,t.fillStyle=xe,t.fillTexture=pe,t.frameRate=Rt,t.hatch=ue,t.hatchArray=fe,t.hatchStyle=function(t,e="black",i=1){F.hatch.hBrush={brush:t,color:e,weight:i}},t.line=ae,t.lineTo=dt,t.lineWidth=Vt,t.listFields=function(){return W(),Array.from(K.keys())},t.load=N,t.loop=function(t=!1){t&&(_t=t),Et=!0,setTimeout((()=>{requestAnimationFrame(At)}),"200")},t.move=function(t,e,i){ut.addSegment(t,e,i)},t.moveTo=xt,t.noClip=function(){F.stroke.clipWindow=null},t.noErase=function(){nt.isActive=!1},t.noField=function(){W(),F.field.isActive=!1},t.noFill=function(){F.fill.isActive=!1},t.noHatch=function(){F.hatch.isActive=!1,F.hatch.hBrush=!1},t.noLoop=function(){Et=!1},t.noStroke=function(){F.stroke.isActive=!1},t.noiseSeed=e=>{t.noise=s(a(e))},t.pick=Ht,t.polygon=function(t){new st(t).show()},t.random=function(t=0,e=1){return Array.isArray(t)?u(t):1===arguments.length?l()*t:h(t,e)},t.rect=function(t,e,i,r,n="corner"){"center"===n&&(t-=i/2,e-=r/2),mt(0),xt(t,e),dt(t+i,e),dt(t+i,e+r),dt(t,e+r),pt(),yt()},t.refreshField=function(t=0){const e=K.get(F.field.current);e.field=e.gen(t,J())},t.restore=function(){z.ctx.restore();let t=z.ctx.getTransform();Y.x=t.e,Y.y=t.f,F.stroke={...et.stroke},F.field={...et.field},F.hatch={...et.hatch},F.fill={...et.fill}},t.save=function(){W(),z.ctx.save(),et.fill={...F.fill},et.stroke={...F.stroke},et.hatch={...F.hatch},et.field={...F.field}},t.scaleBrushes=function(t){for(const{param:e}of Ut.values())e&&(e.weight*=t,e.vibration*=t,e.spacing*=t)},t.seed=t=>{l=a(t)},t.set=jt,t.spline=function(t,e=.5){vt(t,e).draw()},t.stroke=function(t,e,i,r){W(),$t(t,e,i),Jt(R(r),!1)},t.strokeStyle=Zt,t.translate=function(t,e){W(),z.ctx.translate(t,e);let i=z.ctx.getTransform();Y.x=i.e,Y.y=i.f},t.wRand=m,t.wiggle=function(t=1){Q("hand"),F.field.wiggle=t}},"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).brush={});
//# sourceMappingURL=brush.js.map