function checkers(){const t=R.random(120,220)*initialThreadSize,o=t/2;return(e,r,a)=>((r%t<o&&a%t<o||r%t>o&&a%t>o)&&(e=lerpColor(e,color(0),.4)),e)}function bleach_gradient(){return(t,o,e)=>(t=lerpColor(t,color(255),1-e/baseHeight),t)}function bleach_noise(){const t=R.random(50,150)*initialThreadSize,o=R.random(1e4),e=R.random(1e4),r=R.random(.2,.8),a=R.random(.1),i=round(R.random());return(s,n,l)=>{const h=noise(n/t+o,l/t+e,R.random(.3)*i);return h<r?s=lerpColor(s,color(255),h+.5):h<r+a&&(s=lerpColor(s,color(255),map(h,r,r+a,r+.5,0))),s}}function bleach_large(){const t=R.random(20,100)*initialThreadSize,o=R.random(1e4),e=R.random(1e4);return(r,a,i)=>(val=i/baseHeight,noise(a/t+o,i/t+e)<val&&(r=lerpColor(r,color(255),val)),r)}function strips(){const t=R.random(3),o=R.random(90,180);return(e,r,a)=>((r+floor(a/t))%(o*initialThreadSize)<o/2*initialThreadSize&&(e=lerpColor(e,color(255),.4)),e)}function painters_camo(){camoColors.sort(()=>R.random_dec()-.5);for(let t=0;t<4;t++)paintersLayers.push({s:R.random(100,400),val:R.random(.4,.6),z:R.random(10),color:color(camoColors[t])});return(t,o,e)=>{for(let r=paintersLayers.length-1;r>=0;r--){const a=paintersLayers[r];noise(o/a.s,e/a.s,a.z)<a.val&&(t=lerpColor(t,a.color,.8))}return t}}function painters_grad(){const t=R.random(360);for(let o=0;o<2;o++)paintersLayers.push({s:R.random(100,400),val:R.random(.4,.6),z:R.random(10),color:makeColor((t+R.random(-60,60))%360,360,R.random(200,360))});return(t,o,e)=>{for(let r=paintersLayers.length-1;r>=0;r--){const a=paintersLayers[r];t=lerpColor(t,a.color,noise(o/a.s,e/a.s,a.z)*(1-e/baseHeight))}return t}}function painters_pollock(){polockImage=createGraphics(baseWidth,baseHeight);const t=map(initialThreadSize,.5,2,500,150),o=R.random();for(let e=0;e<t;e++){polockImage.fill(R.random_choice([color(0),color(255)])),polockImage.noStroke();const t=v(R.random(baseWidth),R.random(baseHeight)),e=v(R.random(-.1,.1),R.random(-.1,.1)),r=R.random(200,30)*initialThreadSize*o;let a=R.random(100);for(let o=0;o<r;o++){const i=noise(a,10)**2*map(o,0,r,45,5)*initialThreadSize;a+=.02,polockImage.circle(t.x,t.y,i),t.add(e),e.rotate(R.random(-4,4)),e.setMag(1.04*e.mag())}}return(t,o,e)=>{const r=polockImage.get(o,e);return r[3]>0?lerpColor(t,color(r),.7):t}}function getColorFunc(){let t=R.random_dec();if(t<.5)return null;let o=[bleach_gradient,bleach_large,bleach_noise,strips,checkers,painters_pollock,null];return["largeRips","fringeComp"].includes(composition.name)||o.push(painters_camo),"withDivide"==composition.name&&(o=[bleach_gradient,bleach_large,bleach_noise,strips,checkers]),res=R.random_choice(o),res}function initColorFunc(t){return t?{func:t(),offsetX:R.random(-35,35),offsetY:R.random(-35,35)}:null}function makeColor(t,o=360,e=360){colorMode(HSB,360);let r=color(t,o,e);return colorMode(RGB),r=r.toRGB(),r}function neighborColor(t,o=0,e=null,r=null){colorMode(HSB,360);const a=hue(t)+o,i=null==e?R.random(360):map(saturation(t),0,100,0,360)+e,s=null==r?R.random(360):brightness(t)+r;let n=color(a,i,s);return colorMode(RGB),n=n.toRGB(),n}async function franzim(t,o,e,r=.9){windTarget||(windTarget=R.random(360)),threadSize=initialThreadSize*r,o.setMag(1);let a=[t];const i=o.copy().rotate(90),s=ceil(e/10);for(let t=0;t<=s;t++){const t=a[a.length-1],e=40*noise(t.x/50,t.y/50)-20,r=noise(35*a[a.length-1].x/baseWidth,35*a[a.length-1].y/baseHeight),s=60*(r-.5),n=Math.sign(windTarget-o.heading()),l=s+R.random(-2,2)+n;o.rotate(l),i.rotate(l);const h=t.copy().add(o.copy().mult(10));h.add(i.copy().mult(e)),a.push(h)}if(a=toCrv(a),a.length<2)return;for(let t=0;t<a.length;t++)await burn(a[t].copy().add(6*t/a.length,6*t/a.length).mult(globalScale),threadSize*globalScale*map(t,0,a.length,1,4),5);const n=color(R.random_choice(warpColors));n.setAlpha(150),await thread(a,n,5,50)}async function thread(t,o,e=1,r=120){if(t[0].x<0||t[0].y<0||t[0].x>baseWidth||t[0].y>baseHeight)return;newPs=t.map(t=>t.copy().mult(globalScale)),noFill(),noStroke();let a=newPs.map(t=>t.copy());if(!(a.length<2||crvLength(a)<1)){newPs.length<10&&(a=toCrv(newPs)),fill(o),a.forEach(t=>circle(t.x,t.y,threadSize*globalScale)),noFill(),strokeWeight(.2*threadSize*globalScale),o.setAlpha(r),stroke(o),e*=width/1e3;for(let t=0;t<e;t++)for(let t=0;t<a.length;t++)await tinyThread(a[t])}}async function tinyThread(t,o=1){noFill(),beginShape(),curveVertex(t.x,t.y),curveVertex(t.x,t.y),curveVertex(t.x+threadSize*globalScale*cos(tinyThreadDir+=35)*o,t.y+threadSize*globalScale*sin(tinyThreadDir+=35)*o),curveVertex(t.x+threadSize*globalScale*sin(tinyThreadDir+=70)*o,t.y+threadSize*globalScale*cos(tinyThreadDir+=70)*o),curveVertex(t.x+threadSize*globalScale*cos(tinyThreadDir+=100)*o,t.y+threadSize*globalScale*sin(tinyThreadDir+=105)*o),endShape(),tinyThreadDir>1e4&&(tinyThreadDir=0)}class PatternShape{constructor(t){this.ps=t}draw(){beginShape(),this.ps.forEach(t=>vertex(t.x,t.y)),endShape(CLOSE)}center(){let t=v(0,0);return this.ps.forEach(o=>t.add(o)),t.div(this.ps.length),t}rotate(t){const o=this.center();this.rotateAround(o,t)}rotateAround(t,o){const e=this.ps.map(o=>o.copy().sub(t));e.forEach(t=>t.rotate(o)),e.forEach(o=>o.add(t)),this.ps=e}rotatedContainingSquare(t){const o=this.center();this.rotate(-t);const e=this.containingSquare();return e.rotateAround(o,t),this.rotate(t),e}bounds(){return{top:this.ps.reduce((t,o)=>t.y<o.y?t:o).y,bottom:this.ps.reduce((t,o)=>t.y>o.y?t:o).y,left:this.ps.reduce((t,o)=>t.x<o.x?t:o).x,right:this.ps.reduce((t,o)=>t.x>o.x?t:o).x}}containingSquare(){const t=this.bounds();return new SquarePatternShape(t.left,t.top,t.right-t.left,t.bottom-t.top)}toCrv(){this.ps=this.crv()}crv(){let t=[];for(let o=0;o<this.ps.length;o++){const e=toCrv([this.ps[o],this.ps[(o+1)%this.ps.length]]);t=t.concat(e.slice(0,e.length-1))}return t}goAlong(t){for(const o of this.ps)t(o)}async asyncGoAlong(t){for(const o of this.ps)await t(o)}fillet(t){const o=[];for(let e=0;e<this.ps.length;e++){const r=this.ps[e],a=this.ps[(e+1)%this.ps.length],i=this.ps[(e+2)%this.ps.length],s=vsub(a,r).setMag(t),n=vsub(a,i).setMag(t);o.push(vadd(a,n)),o.push(vadd(a,s))}return this.ps=o,this}}const p2i=(t,o,e)=>4*((round(t)-1/e)*e+(round(o)-1/e)*e*(round(baseWidth)*e));class LayoutPattern2 extends PatternShape{constructor(t){super(t)}makeGraphics(){this.graphics=createGraphics(baseWidth,baseHeight),this.graphics.beginShape(),this.ps.forEach(t=>this.graphics.vertex(t.x,t.y)),this.graphics.endShape(CLOSE),this.graphicsDensity=this.graphics.pixelDensity(),this.graphics.loadPixels()}pointInPattern(t){return this.graphics||this.makeGraphics(),this.graphics.get(t.x,t.y)[3]>0}getOffset(t){let o=[...this.ps];return o.push(this.ps[0]),o=o.map((o,e)=>{const r=this.ps[(e+1)%this.ps.length],a=this.ps[(e+2)%this.ps.length],i=vsub(r,o),s=vsub(r,a);let n=s.angleBetween(i);return n<0&&(n+=360),s.rotate(n/2).setMag(t*initialThreadSize),vadd(r,s)}),o}stitches(t,o,e,r=!1){const a=new LayoutPattern2(this.getOffset(t)),i=a.crv(),s=[];o*=initialThreadSize,e*=initialThreadSize;for(let t=0;t<crvLength(i)-o;t+=r?e*R.random(.9,1.6):e){const e=placeOnCurve(i,t);if(!e)continue;t+=r?o*R.random(.9,1.6):o;const a=placeOnCurve(i,t);if(!a)break;(inCanvas(e)||inCanvas(a))&&s.push([e,a])}return s}dropShadowOn(t){const o=createGraphics(baseWidth,baseHeight);o.noStroke(),o.fill(0,10),o.beginShape(),this.crv().forEach(t=>o.vertex(t.x,t.y)),o.endShape(),this.crv().forEach(t=>o.circle(t.x,t.y,threadSize*R.random(15))),t.weft.forEach(t=>{t.forEach(t=>{if(t.ps.length>0){const e=t.ps[0],r=o.get(e.x,e.y);alpha(r)>0&&(t.darkness=.4-brightness(r)/360*(alpha(r)/255)*.4)}})})}prepareFoldedStitchings(){this.stitchPlaces=R.random()<.5?[12]:[9,25],this.stitchType=2==this.stitchPlaces.length?R.random_choice(["normal","doubleTrim","force"]):R.random_choice(["normal","trim","zigzag","force"]),this.extraStitchColor=R.random_choice([stitchColor,R.random_choice([color(0),color(255,0,0),color(255)])])}async drawStitches(t=null){if(!this.withStitches)return;let o=[];for(const t of this.stitchPlaces)o.push(this.stitches(t,12,4));["trim","doubleTrim"].includes(this.stitchType)&&o[o.length-1].splice(round(o[o.length-1].length*R.random(.3,.7)));for(let e of o)for(let o of e){const e=t.hasWeftOn(o[0]);if(e){const t=new Loop(o,stitchColor,1.3*initialThreadSize).wiggle().shadow();t.age=e.age,await t.draw(),await timeout()}}if("doubleTrim"==this.stitchType){const e=o[1][o[1].length-1],r=vsub(e[1],e[0]).setMag(5),a=r.copy().rotate(90),i=this.stitchPlaces[1]-this.stitchPlaces[0];for(let o=-1*globalScale;o<i+2*globalScale;o+=R.random(5)*globalScale){const i=vadd(e[0].add(r.copy().setMag(R.random(-2,2)*globalScale)),a.copy().setMag(o)),s=vadd(e[1].add(r.copy().setMag(R.random(-2,2)*globalScale)),a.copy().setMag(o)),n=t.hasWeftOn(i);if(n){const t=new Loop([i,s],this.extraStitchColor,1.3*initialThreadSize).wiggle().shadow();t.age=n.age,await t.draw(),await timeout()}}}if(["trim","force"].includes(this.stitchType)){const e=o[o.length-1],r="trim"==this.stitchType?e[e.length-1]:R.random_choice(e),a=vsub(r[1],r[0]),i=a.copy().rotate(90),s=R.random(50,100);for(let o=1;o<s;o+=R.random(5)){const e=vadd(r[1],a.copy().setMag(o*globalScale)),s=i.copy().rotate(R.random(-10,10)).setMag(R.random(5,10)*globalScale),n=vadd(e,s),l=vsub(e,s),h=t.hasWeftOn(n);if(h){const t=new Loop([n,l],this.extraStitchColor,1.3*initialThreadSize).wiggle().shadow();t.age=h.age,await t.draw(),await timeout()}}}if("zigzag"==this.stitchType){const t=round(o[0].length*R.random(.1,.7)),e=floor(R.random(t,.9*o[0].length));for(let r=t;r<e;r++){const t=o[0][r],e=vsub(t[1],t[0]).rotate(45),a=vadd(t[0],e);let i=new Loop([t[0],a],this.extraStitchColor,1.3*initialThreadSize).wiggle().shadow();await i.draw(),i=new Loop([a,t[1]],this.extraStitchColor,1.3*initialThreadSize).wiggle().shadow(),await i.draw(),await timeout()}}}}class SquarePatternShape extends LayoutPattern2{constructor(t,o,e,r){super([v(t,o),v(t,o+r),v(t+e,o+r),v(t+e,o)]),this.rotation=0}rotateAround(t,o){this.rotation=o,super.rotateAround(t,o)}getDimension(){const t=this.ps[0],o=vdist(this.ps[0],this.ps[3]),e=vdist(this.ps[0],this.ps[1]);return{pos:t,w:o,h:e,rotation:this.rotation}}}const gold=["#a67c00","#bf9b30","#ffbf00","#ffcf40","#ffdc73"],natural=["#ede8d3","#fafaf7","#fcfcfc"];let paintersLayers=[];const camoColors=["#2E2C24","#AC9F7C","#503F38","#56583D","#E5E7EB","#9D2328"],getBaseColor=()=>{let t=R.random_dec();t<.7?(patchStitch=R.random_choice([color(255,0,0),color(0),color(255)]),coloring={color:"Indigo",denimStitch:"Ochre",patchStitch:patchStitch}):coloring=t<.8?{color:"Charcoal",denimStitch:"White",patchStitch:"Black"}:{color:"Colored",denimStitch:"White",patchStitch:"Black"}},initBaseColor=()=>{if("Indigo"==coloring.color){const t=R.random(195,240);denimColor=makeColor(t,map(abs(t-220),0,25,360,250),R.random(180,360)),stitchColor=color("orange"),patchStitchColor=coloring.patchStitch}else"Charcoal"==coloring.color?(denimColor=makeColor(0,0,0),stitchColor=color(255),patchStitchColor=color(255)):(denimColor=makeColor(R.random(0,70),R.random(200,360),R.random(100,250)),stitchColor=color(255),patchStitchColor=color(0))};let windTarget;class Loop{constructor(t,o,e){this.threadSize=e||threadSize,this.originalColor=o,this.color=o,this.ps=t,this.age=0,this.darkness=0}wiggle(){const t=this.ps[0],o=this.ps[this.ps.length-1],e=vadd(t,o).div(2),r=vsub(t,o).rotate(90).normalize().mult(vdist(t,o)*R.random(-.05,.05));return e.add(r),this.ps=[t,e,o],this}shadow(t=!0,o={times:2,size:2,opacity:30,offset:v(2,0)}){return this.withShadow=!!t&&o,this}getFinalColor(){let t=this.color;return this.age&&(t=lerpColor(t,color(R.random_choice(natural)),this.age)),this.yellow&&(t=lerpColor(t,color("#ebe1a2"),this.yellow)),0!=this.darkness&&(t=neighborColor(t,0,.5*this.darkness*360,-.5*this.darkness*360)),t}applyColorFunc(t){if(t&&this.ps.length>0){const o=this.ps[0];this.color=t.func(this.color,o.x+t.offsetX,o.y+t.offsetY)}}async draw(){if(!(this.ps.length<=1)){if(this.withShadow)for(let t=0;t<this.withShadow.times;t++)for(const t of toCrv(this.ps))await burn(t.copy().add(this.withShadow.offset).mult(globalScale),this.threadSize*globalScale*(this.withShadow.size+R.random(-1,1)),this.withShadow.size.opacity);this.age&&(this.color=lerpColor(this.color,color(R.random_choice(natural)),this.age)),this.yellow&&(this.color=lerpColor(this.color,color("#ebe1a2"),this.yellow)),0!=this.darkness&&(this.color=neighborColor(this.color,0,0,-.5*this.darkness*360)),threadSize=this.threadSize,await thread(this.ps,this.color,3)}}dir(){return this.ps.length<=1?v(0,0):vsub(this.ps[this.ps.length-1],this.ps[0])}}let t1=0,tinyThreadDir=0;
↓ show full (12,581 bytes)