// Noise Lab — Exported Texture // Generated: 2026-09-02T08:39:03.258Z // Filename: noise-texture // Seed: 81771 | Scale: 36 | Octaves: 1 | Persistence: 0.2 | Falloff: 0.95 // Contrast: 1.85 | Brightness: 0.85 | Noise: turbulence | Mode: gradient // Stretch: 0.5x1.4 | Rotation: 171° | Tileable: false // Grain: 0.57 | Vignette: 0.75 | Blur: 0 // Invert: false | Posterize: off | Threshold: off // Blend: colorize 0.6 | Displacement: 12 | SamplingScale: 1 // Aspect: 3:1 | ExportSize: 1024 // Gradient stops: 7 stops // — Standalone vanilla JS — no dependencies. Creates a canvas and draws the texture.} (function() { // Seeded RNG — mulberry32 function mulberry32(a) { return function() { let t = (a += 0x6d2b79f5); t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; } // Perlin 2D class Perlin2D { constructor(seed) { this.p = new Uint8Array(512); const rand = mulberry32(seed); const perm = Array.from({length:256}, (_,i)=>i); for (let i=255;i>0;i--) { const j = Math.floor(rand()*(i+1)); const tmp = perm[i]; perm[i]=perm[j]; perm[j]=tmp; } for (let i=0;i<512;i++) this.p[i]=perm[i & 255]; } fade(t){ return t*t*t*(t*(t*6-15)+10); } lerp(a,b,t){ return a + t*(b-a); } grad(hash,x,y){ const h = hash & 3; const u = h < 2 ? x : y; const v = h < 2 ? y : x; return ((h & 1) ? -u : u) + ((h & 2) ? -v : v); } noise(x,y){ const X = Math.floor(x) & 255; const Y = Math.floor(y) & 255; x -= Math.floor(x); y -= Math.floor(y); const u = this.fade(x), v = this.fade(y); const A = this.p[X]+Y, AA=this.p[A], AB=this.p[A+1]; const B = this.p[X+1]+Y, BA=this.p[B], BB=this.p[B+1]; return this.lerp( this.lerp(this.grad(this.p[AA],x,y), this.grad(this.p[BA],x-1,y), u), this.lerp(this.grad(this.p[AB],x,y-1), this.grad(this.p[BB],x-1,y-1), u), v ); } } function cellularNoise(x,y,seed){ const xi=Math.floor(x), yi=Math.floor(y); let minDist=10; for(let j=-1;j<=1;j++){ for(let i=-1;i<=1;i++){ const cx=xi+i, cy=yi+j; const r=mulberry32(seed + cx*374761393 + cy*668265263 + 999); const px=cx+r(), py=cy+r(); const dx=px-x, dy=py-y; const d=Math.sqrt(dx*dx+dy*dy); if(disValidHex(s.color)); if(filtered.length===0) return {r:128,g:128,b:128}; if(filtered.length===1) return hexToRgb(filtered[0].color); const stops=[...filtered].sort((a,b)=>a.pos-b.pos); if(t<=stops[0].pos) return hexToRgb(stops[0].color,false); if(t>=stops[stops.length-1].pos) return hexToRgb(stops[stops.length-1].color,true); for(let i=0;i=stops[i].pos && t<=stops[i+1].pos){ const denom=stops[i+1].pos-stops[i].pos; const local=denom===0?0:(t-stops[i].pos)/denom; return lerpColor(stops[i].color, stops[i+1].color, local); } } return hexToRgb(stops[0].color,false); } const perlin = new Perlin2D(PARAMS.seed); const grainRand = mulberry32(PARAMS.seed + 9999); function fbm(x,y){ const lacunarity = 1 + PARAMS.falloff * 2; let amp=1, freq=1, sum=0, max=0; for(let i=0;i1) v=1; return v; } function render(canvas, w, h, offX, offY){ offX = offX||0; offY=offY||0; const ctx=canvas.getContext("2d"); if(!ctx) return; canvas.width=w; canvas.height=h; const imgData=ctx.createImageData(w,h); const data=imgData.data; const cx=w/2, cy=h/2; const rad=PARAMS.rotation*Math.PI/180; const cosR=Math.cos(rad), sinR=Math.sin(rad); const maxDist=Math.sqrt(cx*cx+cy*cy); const baseScale=PARAMS.scale; // For image mode: provide your own ImageData as 'imageData' variable below if needed. // Example: const imageData = ctx.getImageData(...) from your uploaded image. // If null, image mode falls back to gradient. let imageData = null; // <-- replace with your ImageData for image blend modes let imgW=0, imgH=0, imgPixels=null; if(imageData){ imgW=imageData.width; imgH=imageData.height; imgPixels=imageData.data; } for(let y=0;y0){ const g=(grainRand()-0.5)*PARAMS.grain*0.5; v+=g; v=Math.max(0,Math.min(1,v)); } if(PARAMS.vignette>0){ const dx=x-cx, dy=y-cy; const dist=Math.sqrt(dx*dx+dy*dy)/maxDist; const vig=1 - dist*PARAMS.vignette*0.9; v*=vig; v=Math.max(0,Math.min(1,v)); } let r,g,b; if(PARAMS.mode==="bw"){ let vv=v; if(PARAMS.invert) vv=1-vv; if(PARAMS.thresholdOn){ vv=vv>PARAMS.threshold?1:0; } else if(PARAMS.usePosterize){ const levels=Math.max(2,Math.min(16,Math.round(PARAMS.posterize))); vv=Math.round(vv*(levels-1))/(levels-1); } const c=Math.round(vv*255); r=g=b=c; } else if(PARAMS.mode==="gradient"){ const col=getGradientColor(v); r=col.r; g=col.g; b=col.b; } else { // image mode if(imgPixels && imgW && imgH){ let u=(sampleX*0.5+0.5)%1, vv2=(sampleY*0.5+0.5)%1; if(u<0) u+=1; if(vv2<0) vv2+=1; if(PARAMS.blendMode==="displacement"){ const disp=(v-0.5)*(PARAMS.displacement/50)*0.5; u=(u+disp)%1; vv2=(vv2+disp)%1; if(u<0) u+=1; if(vv2<0) vv2+=1; } const ix=Math.floor(u*(imgW-1)), iy=Math.floor(vv2*(imgH-1)); const idx=(iy*imgW+ix)*4; const ir=imgPixels[idx], ig=imgPixels[idx+1], ib=imgPixels[idx+2]; if(PARAMS.blendMode==="colorize" || PARAMS.blendMode==="blend"){ const col=getGradientColor(v); r=Math.round(ir*(1-PARAMS.blendAmount)+col.r*PARAMS.blendAmount); g=Math.round(ig*(1-PARAMS.blendAmount)+col.g*PARAMS.blendAmount); b=Math.round(ib*(1-PARAMS.blendAmount)+col.b*PARAMS.blendAmount); } else { r=ir; g=ig; b=ib; if(PARAMS.blendAmount<1){ const col=getGradientColor(v); r=Math.round(r*PARAMS.blendAmount + col.r*(1-PARAMS.blendAmount)*0.3 + r*(1-PARAMS.blendAmount)*0.7); g=Math.round(g*PARAMS.blendAmount + col.g*(1-PARAMS.blendAmount)*0.3 + g*(1-PARAMS.blendAmount)*0.7); b=Math.round(b*PARAMS.blendAmount + col.b*(1-PARAMS.blendAmount)*0.3 + b*(1-PARAMS.blendAmount)*0.7); } } } else { const col=getGradientColor(v); r=col.r; g=col.g; b=col.b; } } const idx=(y*w+x)*4; data[idx]=r; data[idx+1]=g; data[idx+2]=b; data[idx+3]=255; } } ctx.putImageData(imgData,0,0); if(PARAMS.blur>0) canvas.style.filter="blur("+(PARAMS.blur*0.5)+"px)"; } // ---- Create canvas and draw ---- let w = PARAMS.exportSize, h = PARAMS.exportSize; if(PARAMS.aspect==="16:9"){ w=PARAMS.exportSize; h=Math.round(PARAMS.exportSize*9/16); } else if(PARAMS.aspect==="9:16"){ w=Math.round(PARAMS.exportSize*9/16); h=PARAMS.exportSize; } else if(PARAMS.aspect==="3:1"){ w=PARAMS.exportSize; h=Math.round(PARAMS.exportSize/3); } const canvas = document.createElement("canvas"); canvas.width=w; canvas.height=h; canvas.style.width=w+"px"; canvas.style.height=h+"px"; canvas.style.display="block"; canvas.style.maxWidth="100%"; // Append to body or to a container with id="noise-container" if it exists const container = document.getElementById("noise-container") || document.body; container.appendChild(canvas); render(canvas, w, h, 0, 0); // Expose for reuse / animation window.noiseLabRender = render; window.noiseLabCanvas = canvas; window.noiseLabParams = PARAMS; })();