Guest User

Shitpost project

a guest
May 13th, 2026
5
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5 19.30 KB | Source Code | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="utf-8">
  5.     <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
  6.     <title>First project</title>
  7.     <style>
  8.         body,html{
  9.             margin:0;padding:0;
  10.             width:100%;height:100%;
  11.             overflow:hidden;background:#000
  12.         }
  13.         canvas{
  14.             display:block;width:100%;height:100%;
  15.             image-rendering:pixelated
  16.         }
  17.     </style>
  18. </head>
  19. <body>
  20. <canvas id="canvas"></canvas>
  21. <script>
  22. const canvas=document.getElementById("canvas"),
  23.       ctx=canvas.getContext("2d");
  24. Object.getOwnPropertyNames(Math).forEach(p=>window[p]=Math[p]);TAU=PI*2;
  25. mod=(n,m)=>(n%m+m)%m;fract=x=>(x%1+1)%1;
  26. mix=(a,b,t)=>a*(1-t)+b*t;//a+(b-a)*t;
  27. createArray=(n,v)=>Array.from({length:n},(_,i)=>typeof v==="function"?v(i):v);
  28. charRange=(s,e)=>Array(e-s+1).fill().map((_,i)=>String.fromCharCode(s+i)).join("");
  29. rand=(a,b)=>typeof b==="undefined"?random()*(typeof a==="undefined"?1:a):a+random()*(b-a);
  30. clamp=(v,a,b)=>min(max(v,a),b);dist=(x0,y0,x1,y1)=>sqrt(pow(x1-x0,2)+pow(y1-y0,2));
  31. let width,height,imgDat,pixBuf,
  32.     pixelSize=6;
  33. resize=()=>{
  34.     const dpr=window.devicePixelRatio||1,
  35.           iw=window.innerWidth,ih=window.innerHeight;
  36.     canvas.width=width=floor(iw*dpr/pixelSize);
  37.     canvas.height=height=floor(ih*dpr/pixelSize);
  38.     imgDat=ctx.createImageData(width,height);
  39.     pixBuf=new Uint32Array(imgDat.data.buffer);
  40. };
  41. const audioCtx=new AudioContext();
  42. let audioNode,audioTime=0,sampleRate=audioCtx.sampleRate,sampleDt=1/sampleRate;
  43. fbCall=()=>{};
  44. funcbeat=SR=>{
  45.     let num=4,freqs,amps,phases,timer=1,
  46.     randomize=init=>{
  47.         if(init){
  48.             freqs=createArray(num,()=>[0,0]);
  49.             amps=createArray(num,()=>0);
  50.             adds=createArray(num,()=>[0,0,0]);
  51.             phases=createArray(num,()=>rand());
  52.         }
  53.         for(let i=0;i<num;i++){
  54.             freqs[i][0]=mix(100,1e3,rand()**3);
  55.             freqs[i][1]=mix(100,1e3,rand()**3);
  56.             amps[i]=rand()*2e3;
  57.             adds[i][0]=rand(-3e3,4e3)*sampleDt;
  58.             adds[i][1]=rand(-1e3,1e2)*sampleDt;
  59.             adds[i][2]=rand(-1e3,1e2)*sampleDt;
  60.         }
  61.     };
  62.     randomize(true);
  63.     return t=>{
  64.         let sum=0;
  65.         for(let i=0;i<num;i++){
  66.             phases[i]=fract(phases[i]+(freqs[i][0]+amps[i]*sin(timer*freqs[i][1]*TAU))*sampleDt);
  67.             freqs[i][0]+=adds[i][1];freqs[i][1]+=adds[i][2];amps[i]+=adds[i][0];
  68.             sum+=sin(phases[i]*TAU);
  69.         }
  70.         timer-=sampleDt;
  71.         if(timer<=0){randomize();timer+=(rand()**10)*4;fbCall();}
  72.         return tanh((sum/num)+rand(-.01,.01))*.05;
  73.     };
  74. };
  75. function initAudio(){
  76.     if(audioNode)return;
  77.     audioNode=audioCtx.createScriptProcessor(4096,0,1);
  78.     const fb=funcbeat(sampleRate);
  79.     audioNode.onaudioprocess=e=>{
  80.         const out=e.outputBuffer.getChannelData(0);
  81.         for(let i=0;i<out.length;i++){
  82.             //out[i]=sin(audioTime*440*TAU)/(1+audioTime*200);
  83.             out[i]=fb(audioTime);
  84.             audioTime+=sampleDt;
  85.         }
  86.     };
  87.     audioNode.connect(audioCtx.destination);
  88. }
  89. const pset=(x,y,c)=>{if(x>=0&&x<width&&y>=0&&y<height)pixBuf[y*width+x]=c},
  90. line=(x0,y0,x1,y1,c)=>{
  91.     x0=floor(x0);y0=floor(y0);x1=floor(x1);y1=floor(y1);
  92.     const dx=abs(x1-x0),sx=x0<x1?1:-1,dy=-abs(y1-y0),sy=y0<y1?1:-1;
  93.     let err=dx+dy;
  94.     while(1){
  95.         pset(x0,y0,c);
  96.         if(x0===x1&&y0===y1)break;
  97.         const e2=2*err;
  98.         if(e2>=dy){err+=dy;x0+=sx}
  99.         if(e2<=dx){err+=dx;y0+=sy}
  100.     }
  101. },
  102. rect=(x,y,w,h,c)=>{
  103.     for(let j=floor(y);j<y+h;j++)for(let i=floor(x);i<x+w;i++)pset(i,j,c);
  104. },
  105. rectb=(x,y,w,h,c)=>{
  106.     for(let i=floor(x);i<x+w;i++){pset(i,y,c);pset(i,y+h-1,c)}
  107.     for(let j=floor(y);j<y+h;j++){pset(x,j,c);pset(x+w-1,j,c)}
  108. },
  109. circb=(xc,yc,r,c)=>{
  110.     xc=floor(xc);yc=floor(yc);r=floor(r);
  111.     let x=0,y=r,d=3-2*r;
  112.     const plot=(x,y)=>{pset(xc+x,yc+y,c);pset(xc-x,yc+y,c);pset(xc+x,yc-y,c);pset(xc-x,yc-y,c);pset(xc+y,yc+x,c);pset(xc-y,yc+x,c);pset(xc+y,yc-x,c);pset(xc-y,yc-x,c)};
  113.     while(y>=x){plot(x,y);x++;if(d>0){y--;d=d+4*(x-y)+10}else d=d+4*x+6}
  114. },
  115. circ=(xc,yc,r,c)=>{
  116.     xc=floor(xc);yc=floor(yc);r=floor(r);
  117.     let x=0,y=r,d=3-2*r;
  118.     const span=(x,y,w)=>{for(let i=x-w;i<=x+w;i++){pset(i,yc+y,c);pset(i,yc-y,c)}};
  119.     while(y>=x){span(xc,y,x);span(xc,x,y);x++;if(d>0){y--;d=d+4*(x-y)+10}else d=d+4*x+6}
  120. };
  121. tri=(x0,y0,x1,y1,x2,y2,c)=>{
  122.     x0=floor(x0);y0=floor(y0);x1=floor(x1);y1=floor(y1);x2=floor(x2);y2=floor(y2);
  123.     let minX=x0,maxX=x0,minY=y0,maxY=y0;
  124.     if(x1<minX)minX=x1;if(x1>maxX)maxX=x1;if(x2<minX)minX=x2;if(x2>maxX)maxX=x2;
  125.     if(y1<minY)minY=y1;if(y1>maxY)maxY=y1;if(y2<minY)minY=y2;if(y2>maxY)maxY=y2;
  126.     if(maxX-minX>maxY-minY){
  127.         if(x0>x1){let t=x0;x0=x1;x1=t;t=y0;y0=y1;y1=t}
  128.         if(x0>x2){let t=x0;x0=x2;x2=t;t=y0;y0=y2;y2=t}
  129.         if(x1>x2){let t=x1;x1=x2;x2=t;t=y1;y1=y2;y2=t}
  130.         if(x0===x2){pset(x0,y0,c);return;}
  131.         let dx02=x2-x0,dx01=x1-x0,dx12=x2-x1;
  132.         for(let x=x0;x<x2;x++){
  133.             let ya=y0+floor((x-x0)*(y2-y0)/dx02),yb;
  134.             if(x<=x1&&dx01!==0)yb=y0+floor((x-x0)*(y1-y0)/dx01);
  135.             else if(dx12!==0)yb=y1+floor((x-x1)*(y2-y1)/dx12);
  136.             else yb=y1;
  137.             if(ya>yb){let t=ya;ya=yb;yb=t}
  138.             for(let y=ya;y<=yb;y++)pset(x,y,c);
  139.         }
  140.     }else{
  141.         if(y0>y1){let t=x0;x0=x1;x1=t;t=y0;y0=y1;y1=t}
  142.         if(y0>y2){let t=x0;x0=x2;x2=t;t=y0;y0=y2;y2=t}
  143.         if(y1>y2){let t=x1;x1=x2;x2=t;t=y1;y1=y2;y2=t}
  144.         if(y0===y2){for(let x=minX;x<=maxX;x++)pset(x,y0,c);return;}
  145.         let dy02=y2-y0,dy01=y1-y0,dy12=y2-y1;
  146.         for(let y=y0;y<y2;y++){
  147.             let xa=x0+floor((y-y0)*(x2-x0)/dy02),xb;
  148.             if(y<=y1&&dy01!==0)xb=x0+floor((y-y0)*(x1-x0)/dy01);
  149.             else if(dy12!==0)xb=x1+floor((y-y1)*(x2-x1)/dy12);
  150.             else xb=x1;
  151.             if(xa>xb){let t=xa;xa=xb;xb=t}
  152.             for(let x=xa;x<=xb;x++)pset(x,y,c);
  153.         }
  154.     }
  155. };
  156. trib=(x0,y0,x1,y1,x2,y2,c)=>{line(x0,y0,x1,y1,c);line(x1,y1,x2,y2,c);line(x2,y2,x0,y0,c);};
  157. dotLine=(x0,y0,x1,y1,sp,sh,c)=>{
  158.     let dx=x1-x0,dy=y1-y0,len=max(abs(dx),abs(dy)),
  159.         vx=dx/len,vy=dy/len;
  160.     for(let i=mod(-sh,sp);i<=len;i+=sp)pset(floor(x0+vx*i),floor(y0+vy*i),c);
  161. };
  162. vectorFont={
  163.     width:3,height:5,spacing:.25,leading:1,
  164.     //UPPERCASE
  165.     A:[[[0,4],[0,1],[1,0],[2,1],[2,4]],[[0,2],[2,2]]],
  166.     B:[[[0,0],[1.5,0],[2,1],[1.5,2],[0,2],[1.5,2],[2,3],[1.5,4],[0,4],[0,0]]],
  167.     C:[[[2,0],[0,0],[0,4],[2,4]]],
  168.     D:[[[0,0],[1,0],[2,1],[2,3],[1,4],[0,4],[0,0]]],
  169.     E:[[[2,0],[0,0],[0,4],[2,4]],[[0,2],[1.5,2]]],
  170.     F:[[[2,0],[0,0],[0,4]],[[0,2],[1.5,2]]],
  171.     G:[[[2,1],[2,0],[0,0],[0,4],[2,4],[2,2],[1,2]]],
  172.     H:[[[0,0],[0,4]],[[2,0],[2,4]],[[0,2],[2,2]]],
  173.     I:[[[1,0],[1,4]],[[0,0],[2,0]],[[0,4],[2,4]]],
  174.     J:[[[2,0],[2,3],[1,4],[0,3]]],
  175.     K:[[[0,0],[0,4]],[[2,0],[0,2],[2,4]]],
  176.     L:[[[0,0],[0,4],[2,4]]],
  177.     M:[[[0,4],[0,0],[1,2],[2,0],[2,4]]],
  178.     N:[[[0,4],[0,0],[2,4],[2,0]]],
  179.     O:[[[0,1],[1,0],[2,1],[2,3],[1,4],[0,3],[0,1]]],
  180.     P:[[[0,4],[0,0],[2,0],[2,2],[0,2]]],
  181.     Q:[[[0,1],[1,0],[2,1],[2,3],[1,4],[0,3],[0,1]],[[1,3],[2,5]]],
  182.     R:[[[0,4],[0,0],[2,0],[2,2],[0,2],[2,4]]],
  183.     S:[[[2,0],[0,0],[0,2],[2,2],[2,4],[0,4]]],
  184.     T:[[[1,0],[1,4]],[[0,0],[2,0]]],
  185.     U:[[[0,0],[0,4],[2,4],[2,0]]],
  186.     V:[[[0,0],[1,4],[2,0]]],W:[[[0,0],[0,4],[1,3],[2,4],[2,0]]],
  187.     X:[[[0,0],[2,4]],[[2,0],[0,4]]],
  188.     Y:[[[0,0],[1,2],[2,0]],[[1,2],[1,4]]],
  189.     Z:[[[0,0],[2,0],[0,4],[2,4]]],
  190.     //lowercase
  191.     a:[[[0,2],[2,2],[2,4],[0,4],[0,3],[2,3]]],
  192.     b:[[[0,0],[0,4],[2,4],[2,2],[0,2]]],
  193.     c:[[[2,2],[0,2],[0,4],[2,4]]],
  194.     d:[[[2,0],[2,4],[0,4],[0,2],[2,2]]],
  195.     e:[[[0,3],[2,3],[2,2],[0,2],[0,4],[2,4]]],
  196.     f:[[[2,0],[1,0],[1,4]],[[0,2],[2,2]]],
  197.     g:[[[2,4],[2,2],[0,2],[0,4],[2,4],[2,6],[0,6]]],
  198.     h:[[[0,0],[0,4]],[[0,2],[2,2],[2,4]]],
  199.     i:[[[1,1],[1,1]],[[1,2],[1,4]]],
  200.     j:[[[1,1],[1,1]],[[1,2],[1,5],[0,5]]],
  201.     k:[[[0,0],[0,4]],[[2,2],[0,3]],[[1,3],[2,4]]],
  202.     l:[[[1,0],[1,4]]],
  203.     m:[[[0,2],[0,4]],[[1,2],[1,4]],[[2,2],[2,4]],[[0,2],[2,2]]],
  204.     n:[[[0,2],[0,4]],[[0,2],[2,2],[2,4]]],
  205.     o:[[[0,2],[2,2],[2,4],[0,4],[0,2]]],
  206.     p:[[[0,2],[0,6]],[[0,2],[2,2],[2,4],[0,4]]],
  207.     q:[[[2,2],[2,6]],[[2,2],[0,2],[0,4],[2,4]]],
  208.     r:[[[0,2],[0,4]],[[0,3],[2,2]]],
  209.     s:[[[2,2],[0,2],[0,3],[2,3],[2,4],[0,4]]],
  210.     t:[[[1,0],[1,4]],[[0,2],[2,2]]],
  211.     u:[[[0,2],[0,4],[2,4],[2,2]]],
  212.     v:[[[0,2],[1,4],[2,2]]],
  213.     w:[[[0,2],[0,4],[1,3],[2,4],[2,2]]],
  214.     x:[[[0,2],[2,4]],[[2,2],[0,4]]],
  215.     y:[[[0,2],[0,4],[2,4],[2,2]],[[2,4],[2,6],[0,6]]],
  216.     z:[[[0,2],[2,2],[0,4],[2,4]]],
  217.     //digits & symbols
  218.     1:[[[1,0],[1,4]],[[0,1],[1,0]]],
  219.     2:[[[0,1],[1,0],[2,1],[0,4],[2,4]]],
  220.     3:[[[0,0],[2,0],[1,2],[2,4],[0,4]]],
  221.     4:[[[0,0],[0,2],[2,2]],[[2,0],[2,4]]],
  222.     5:[[[2,0],[0,0],[0,2],[2,2],[2,4],[0,4]]],
  223.     6:[[[2,0],[0,2],[0,4],[2,4],[2,2],[0,2]]],
  224.     7:[[[0,0],[2,0],[0,4]]],
  225.     8:[[[0,0],[0,1],[2,3],[2,4],[0,4],[0,3],[2,1],[2,0],[0,0]]],
  226.     9:[[[2,2],[0,2],[0,0],[2,0],[2,4],[0,4]]],
  227.     0:[[[0,0],[2,0],[2,4],[0,4],[0,0]],[[2,0],[0,4]]],
  228.     "!":[[[1,0],[1,2]],[[1,4],[1,4]]],
  229.     "?":[[[0,1],[1,0],[2,1],[1,2],[1,3]],[[1,4],[1,4]]],
  230.     ".":[[[1,4],[1,4]]],
  231.     ",":[[[1,4],[1,5]]],
  232.     ":":[[[1,1],[1,1]],[[1,3],[1,3]]],
  233.     ";":[[[1,1],[1,1]],[[1,3],[1,4]]],
  234.     " ":[],
  235.     "-":[[[0,2],[2,2]]],
  236.     "+":[[[1,1],[1,3]],[[0,2],[2,2]]],
  237.     "=":[[[0,1.5],[2,1.5]],[[0,2.5],[2,2.5]]],
  238.     "/":[[[2,0],[0,4]]],
  239.     "(":[[[1,0],[0,1],[0,3],[1,4]]],
  240.     ")":[[[0,0],[1,1],[1,3],[0,4]]],
  241.     "[":[[[1.5,0],[0.5,0],[0.5,4],[1.5,4]]],"]":[[[0.5,0],[1.5,0],[1.5,4],[0.5,4]]],
  242.     "{":[[[2,.25],[1.5,0],[1,1],[1,1.75],[0,2],[1,2.25],[1,3],[1.5,4],[2,3.75]]],"}":[[[0,.25],[0.5,0],[1,1],[1,1.75],[2,2],[1,2.25],[1,3],[.5,4],[0,3.75]]],
  243.     "<":[[[2,0],[0,2],[2,4]]],">":[[[0,0],[2,2],[0,4]]],
  244.     "|":[[[1,0],[1,4]]],"\\":[[[0,0],[2,4]]],"_":[[[0,4],[2,4]]],"^":[[[0,1],[1,0],[2,1]]],"`":[[[0,0],[1,1]]],"~":[[[0,3],[0.5,2],[1.5,3],[2,2]]],
  245.     "@":[[[2,4],[0,4],[0,0],[2,0],[2,2],[1,2],[1,1]]],"#":[[[0.5,0],[0.5,4]],[[1.5,0],[1.5,4]],[[0,1],[2,1]],[[0,3],[2,3]]],
  246.     "$":[[[0,4],[2,4],[2,2],[0,2],[0,0],[2,0]],[[1,-0.5],[1,4.5]]],"%":[[[0,4],[2,0]],[[0.5,0.5],[0.5,0.5]],[[1.5,3.5],[1.5,3.5]]],
  247.     "&":[[[2,4],[0,1],[1,0],[2,1],[0,4],[1,4],[2,3]]],"*":[[[1,1],[1,3]],[[0.5,1.5],[1.5,2.5]],[[1.5,1.5],[0.5,2.5]]],
  248.     "'":[[[1,0],[1,1]]],'"':[[[0.5,0],[0.5,1]],[[1.5,0],[1.5,1]]]
  249. };
  250. vectorText=(str,x,y,s,c)=>{
  251.     let tx=0,ty=0;
  252.     str.split("").forEach(char=>{
  253.         if(char==="\n"){tx=0;ty+=(vectorFont.height+vectorFont.leading)*s;return}
  254.         const g=vectorFont[char]||vectorFont[char.toUpperCase()];
  255.         if(g)g.forEach(p=>{
  256.             for(let j=0;j<p.length-1;j++)line(x+tx+p[j][0]*s,y+ty+p[j][1]*s,x+tx+p[j+1][0]*s,y+ty+p[j+1][1]*s,c);
  257.         });
  258.         tx+=(vectorFont.width+vectorFont.spacing)*s;
  259.     });
  260. };
  261. mouseX=mouseY=pmouseX=pmouseY=mouseXpress=mouseYpress=0;mouseDown=pmouseDown=mouseClicked=mouseReleased=false;
  262. const trackMouse=e=>{
  263.     if(e.cancelable)e.preventDefault();
  264.     if(audioCtx.state==="suspended")audioCtx.resume();
  265.     initAudio();
  266.     const r=canvas.getBoundingClientRect(),t=(e.touches&&e.touches.length)?e.touches[0]:e;
  267.     if(e.type!=="touchend"&&e.type!=="pointerup"){
  268.         mouseX=((t.clientX-r.left)*(width/r.width))|0;
  269.         mouseY=((t.clientY-r.top)*(height/r.height))|0;
  270.     }
  271.     if(e.type==="pointerdown"||e.type==="touchstart")mouseDown=true;
  272.     if(e.type==="pointerup"||e.type==="touchend")mouseDown=false;
  273. };
  274. ["pointerdown","pointermove","pointerup","touchstart","touchmove","touchend"].forEach(ev=>canvas.addEventListener(ev,trackMouse,{passive:false}));
  275. mInRect=(x,y,w,h)=>mouseX>=x&&mouseX<x+w&&mouseY>=y&&mouseY<y+h;
  276. function parseBigInt(str,base=10){
  277.     return[...str].reduce((acc,curr)=>acc*BigInt(base)+BigInt(parseInt(curr,base)),0n);
  278. }
  279. font3x5="6fm,19,iv1,7tq,gbp,l2i,i,djo,429,9h,15c,3y8,cg,6bk,3ok,odr,n16,mn7,b6r,elp,b7z,oge,3on,o8f,bfz,sw,3yo,dhw,2t4,45t,6g3,jqi,i5m,bmz,jf2,bqj,mvj,3wv,l72,i5p,n13,8is,hyl,mkp,i2n,i23,8kq,3qj,kfe,hyj,b66,787,odp,8kt,p65,hwt,78t,mnb,jva,ebt,adv,16,m4g,h,nuo,bm1,jnk,l9g,jpc,7h0,beo,hxl,79e,41u,h8p,djn,iww,hxc,8e8,69s,fr4,4lc,akg,dsi,l6o,8jk,p4w,gu8,c3k,jwg,jx2,782,akz,bc".
  280. split(",").map(s=>parseBigInt(s,36));
  281. drawBigInt=(n,x,y,w,h,c)=>{
  282.     for(let i=0;i<w*h;i++)
  283.         if((n>>BigInt(i))&1n)
  284.             pset(x+mod(i,w),y+floor(i/w),c)
  285. }
  286. text3x5=(str,x,y,c)=>{
  287.     x=floor(x);y=floor(y);
  288.     let dx=0,dy=0;
  289.     for(let char of str){
  290.         if(char==="\n"){dx=0;dy+=6;continue;}
  291.         let code=char.charCodeAt(0)-33;
  292.         if(code>=0&&code<font3x5.length){
  293.             drawBigInt(font3x5[code],x+dx,y+dy,3,5,c);
  294.         }
  295.         dx+=4;
  296.     }
  297. }
  298. class BitmapEditor{
  299.     constructor(x,y,w,h,pS=4,n=0n){
  300.         Object.assign(this,{x,y,w,h,pS,n:BigInt(n),drag:false,c:true})
  301.     }
  302.     update(){
  303.             let{x,y,w,h,pS,n}=this,inside=mInRect(x,y,w*pS,h*pS);
  304.         if(mouseClicked){
  305.             this.drag=inside;
  306.             if(inside){
  307.                 let px=floor((mouseX-x)/pS),
  308.                     py=floor((mouseY-y)/pS),
  309.                     idx=BigInt(py*w+px);
  310.                 this.c=!((n>>idx)&1n);
  311.             }
  312.         }
  313.         if(mouseDown&&this.drag&&inside){
  314.             let px=clamp(floor((mouseX-x)/pS),0,w-1),
  315.                 py=clamp(floor((mouseY-y)/pS),0,h-1),
  316.                 idx=BigInt(py*w+px);
  317.             if(this.c)this.n|=1n<<idx;else this.n&=~(1n<<idx);
  318.         }
  319.     }
  320.     draw(){
  321.         let{x,y,w,h,pS,n}=this;
  322.         for(let i=0;i<w*h;i++){
  323.             const cx=x+mod(i,w)*pS,cy=y+floor(i/w)*pS;
  324.             rect(cx,cy,pS-1,pS-1,(n>>BigInt(i))&BigInt(1)?0xFFFFFFFF:0xFF000000);
  325.         }
  326.     }
  327.     toString(b=36){return this.n.toString(b);}
  328.     fromString(s,b=36){this.n=parseBigInt(s,b);}
  329.     static drawStr(str,x,y,w,h,pS=1){
  330.         let n=parseBigInt(str,36);
  331.         for(let i=0;i<w*h;i++){
  332.             if((n>>BigInt(i))&1n){
  333.                 const cx=x+mod(i,w)*pS,cy=y+floor(i/w)*pS;
  334.                 rect(cx,cy,pS,pS,0xFFFFFFFF);
  335.             }
  336.         }
  337.     }
  338. }
  339. class Button{
  340.     constructor(x,y,w,h,onClick){
  341.         Object.assign(this,{x,y,w,h,onClick,hold:false});
  342.     }
  343.     update(){
  344.         let{x,y,w,h}=this,inside=mInRect(x,y,w,h);
  345.         if(mouseClicked)this.hold=inside;
  346.         if(mouseReleased&&this.hold&&inside)this.onClick();
  347.     }
  348.     draw(){
  349.         let{x,y,w,h}=this,inside=mInRect(x,y,w,h);
  350.         rect(x,y,w,h,0xFFA0A0A0);
  351.         rectb(x,y,w,h,mouseDown&&this.hold&&inside?0xFFFFFFFF:0xFFCCCCCC);
  352.     }
  353. }
  354. window.addEventListener("resize",resize);
  355. resize();
  356. //init
  357. chooseRand=a=>a[floor(random()*a.length)];
  358. let zBuf=new Float32Array(0);
  359. const vec3=(x=0,y=0,z=0)=>({x,y,z}),
  360. dot=(v1,v2)=>v1.x*v2.x+v1.y*v2.y+v1.z*v2.z,
  361. normalize=v=>{let l=sqrt(v.x*v.x+v.y*v.y+v.z*v.z);return l===0?vec3():vec3(v.x/l,v.y/l,v.z/l)},
  362. rotX=(p,a)=>{let c=cos(a),s=sin(a);return vec3(p.x,p.y*c-p.z*s,p.y*s+p.z*c)},
  363. rotY=(p,a)=>{let c=cos(a),s=sin(a);return vec3(p.x*c+p.z*s,p.y,-p.x*s+p.z*c)},
  364. colSel={f:[i=>clamp(i,0,1),i=>clamp(i*i,0,1),i=>clamp(sin(i*PI),0,1),i=>clamp(cos(i*PI),0,1)],cur:[],init:()=>{
  365.     for(let i=0;i<3;i++)
  366.         colSel.cur[i]=chooseRand(colSel.f);
  367. }};colSel.init();
  368. getColor=i=>{
  369.     let r=floor(colSel.cur[0](i)*255),g=floor(colSel.cur[1](i)*255),b=floor(colSel.cur[2](i)*255);
  370.     return 0xFF000000|(b<<16)|(g<<8)|r;
  371. },
  372. tri3d=(p0,n0,p1,n1,p2,n2,lp,vp)=>{
  373.     let x0=floor(p0.x),y0=floor(p0.y),z0=p0.z,
  374.         x1=floor(p1.x),y1=floor(p1.y),z1=p1.z,
  375.         x2=floor(p2.x),y2=floor(p2.y),z2=p2.z,
  376.         minX=max(0,min(x0,x1,x2)),maxX=min(width-1,max(x0,x1,x2)),
  377.         minY=max(0,min(y0,y1,y2)),maxY=min(height-1,max(y0,y1,y2)),
  378.         denom=(y1-y2)*(x0-x2)+(x2-x1)*(y0-y2);
  379.     if(denom===0)return;
  380.     function pixel(x,y){
  381.         let w0=((y1-y2)*(x-x2)+(x2-x1)*(y-y2))/denom,w1=((y2-y0)*(x-x2)+(x0-x2)*(y-y2))/denom,w2=1-w0-w1;
  382.         if(w0<-0.001||w1<-0.001||w2<-0.001)return;
  383.         let z=w0*z0+w1*z1+w2*z2,idx=y*width+x;
  384.         if(z>zBuf[idx]){
  385.             zBuf[idx]=z;
  386.             let px=w0*p0.wx+w1*p1.wx+w2*p2.wx,py=w0*p0.wy+w1*p1.wy+w2*p2.wy,pz=w0*p0.wz+w1*p1.wz+w2*p2.wz,
  387.                 N=normalize(vec3(w0*n0.x+w1*n1.x+w2*n2.x,w0*n0.y+w1*n1.y+w2*n2.y,w0*n0.z+w1*n1.z+w2*n2.z)),
  388.                 L=normalize(vec3(lp.x-px,lp.y-py,lp.z-pz)),V=normalize(vec3(vp.x-px,vp.y-py,vp.z-pz)),
  389.                 R=vec3(2*dot(N,L)*N.x-L.x,2*dot(N,L)*N.y-L.y,2*dot(N,L)*N.z-L.z);
  390.             pixBuf[idx]=getColor(0.15+max(dot(N,L)*.5+.25,0)*.5+pow(max(dot(R,V),0),16)*0.3);
  391.         }
  392.     }
  393.     for(let y=minY;y<=maxY;y++){
  394.         for(let x=minX;x<=maxX;x++){
  395.             pixel(x,y);
  396.         }
  397.     }
  398. };
  399. let sphereVertices=[],sphereIndices=[],cubeVertices=[],cubeIndices=[];
  400. const initSphere=(rings,sectors)=>{
  401.     sphereVertices=[];sphereIndices=[];
  402.     for(let r=0;r<=rings;r++){
  403.         let phi=(r*PI)/rings,sinPhi=sin(phi),cosPhi=cos(phi);
  404.         for(let s=0;s<=sectors;s++){
  405.             let theta=(s*TAU)/sectors,x=cos(theta)*sinPhi,y=cosPhi,z=sin(theta)*sinPhi;
  406.             sphereVertices.push({pos:vec3(x,y,z),normal:vec3(x,y,z)});
  407.         }
  408.     }
  409.     for(let r=0;r<rings;r++)for(let s=0;s<sectors;s++){
  410.         let first=r*(sectors+1)+s,second=first+sectors+1;
  411.         sphereIndices.push(first,second,first+1,second,second+1,first+1);
  412.     }
  413. },
  414. initCube=()=>{
  415.     cubeVertices=[];cubeIndices=[];
  416.     let d=[[-1,-1,1],[1,-1,1],[1,1,1],[-1,1,1],[-1,-1,-1],[-1,1,-1],[1,1,-1],[1,-1,-1]],
  417.         f=[[0,1,2,3,[0,0,1]],[4,5,6,7,[0,0,-1]],[3,2,6,5,[0,1,0]],[0,4,7,1,[0,-1,0]],[1,7,6,2,[1,0,0]],[0,3,5,4,[-1,0,0]]];
  418.     f.forEach(w=>{
  419.         let n=vec3(w[4][0],w[4][1],w[4][2]),idx=cubeVertices.length;
  420.         w.slice(0,4).forEach(v=>cubeVertices.push({pos:vec3(d[v][0]*0.7,d[v][1]*0.7,d[v][2]*0.7),normal:n}));
  421.         cubeIndices.push(idx,idx+1,idx+2,idx,idx+2,idx+3);
  422.     });
  423. };
  424. initSphere(12,18);initCube();
  425. let rotDragX=0,rotDragY=0;
  426. linew=(x0,y0,x1,y1,w,c)=>{
  427.     let d=dist(x0,y0,x1,y1),dx=(x1-x0)/d,dy=(y1-y0)/d,r=w/2;
  428.     if(d<1e-11)return;
  429.     tri(x0+dy*r,y0-dx*r,x1+dy*r,y1-dx*r,x1-dy*r,y1+dx*r,c);
  430.     tri(x1-dy*r,y1+dx*r,x0-dy*r,y0+dx*r,x0+dy*r,y0-dx*r,c);
  431. };
  432. bgCol=0xFFA0A0A0;
  433. const setRandomBg=()=>{
  434.     let r=floor(random()*256),g=floor(random()*256),b=floor(random()*256);
  435.     bgCol=0xFF000000|(b<<16)|(g<<8)|r;
  436. };
  437. t=0;fbCall=()=>{setRandomBg();colSel.init();t=0;};
  438. scrollerText=(str,y,c,sh=0)=>text3x5(str,mod(sh-frame,width+(str.length*4))-str.length*4,y,c);
  439. frame=0;
  440. function render(){
  441.     mouseClicked=!pmouseDown&&mouseDown;mouseReleased=pmouseDown&&!mouseDown;
  442.     if(mouseClicked){mouseXpress=mouseX;mouseYpress=mouseY;}
  443.     //---
  444.     pixBuf.fill(bgCol);
  445.     rectb(0,0,width,height,bgCol^0xFFFFFF);
  446.     linew(mouseXpress,mouseYpress,mouseX,mouseY,t,0xFFA03030);
  447.     t++;
  448.     dotLine(mouseX,0,mouseX,height,4-mouseDown,frame/10,0xFFC0C0C0);
  449.     dotLine(0,mouseY,width,mouseY,4-mouseDown,frame/10,0xFFC0C0C0);
  450.     text3x5(`(${mouseX},${mouseY})`,mouseX+2,mouseY-7,0xFFD0D0D0);
  451.     //---
  452.     let totalPixels=width*height;
  453.     if(zBuf.length!==totalPixels)zBuf=new Float32Array(totalPixels);
  454.     zBuf.fill(-999999);
  455.     let fov=100,cx=width/2,cy=height/2,angX=frame*0.015+rotDragX,angY=frame*0.011+rotDragY,
  456.         lp=vec3(cos(frame*.04)*8,sin(frame*.02)*4,sin(frame*.01)*5),vp=vec3(cos(frame*.01)*8,sin(frame*.01)*4,sin(frame*.005)*5),
  457.     drawMesh=(ind,vert,tx)=>{
  458.         for(let i=0;i<ind.length;i+=3){
  459.             let v0=vert[ind[i]],v1=vert[ind[i+1]],v2=vert[ind[i+2]],
  460.                 rp0=rotY(rotX(v0.pos,angX),angY),rp1=rotY(rotX(v1.pos,angX),angY),rp2=rotY(rotX(v2.pos,angX),angY);
  461.                 rp0.x+=tx;rp1.x+=tx;rp2.x+=tx;
  462.             let zp0=rp0.z+3.5,zp1=rp1.z+3.5,zp2=rp2.z+3.5,
  463.                 p0_scr={x:(rp0.x*fov)/zp0+cx,y:(rp0.y*fov)/zp0+cy,z:1/zp0,wx:rp0.x,wy:rp0.y,wz:rp0.z},
  464.                 p1_scr={x:(rp1.x*fov)/zp1+cx,y:(rp1.y*fov)/zp1+cy,z:1/zp1,wx:rp1.x,wy:rp1.y,wz:rp1.z},
  465.                 p2_scr={x:(rp2.x*fov)/zp2+cx,y:(rp2.y*fov)/zp2+cy,z:1/zp2,wx:rp2.x,wy:rp2.y,wz:rp2.z};
  466.             if((p1_scr.x-p0_scr.x)*(p2_scr.y-p0_scr.y)-(p1_scr.y-p0_scr.y)*(p2_scr.x-p0_scr.x)>=0)continue;
  467.             let rn0=rotY(rotX(v0.normal,angX),angY),rn1=rotY(rotX(v1.normal,angX),angY),rn2=rotY(rotX(v2.normal,angX),angY);
  468.             tri3d(p0_scr,rn0,p1_scr,rn1,p2_scr,rn2,lp,vp);
  469.         }
  470.     };
  471.     drawMesh(sphereIndices,sphereVertices,-1);
  472.     drawMesh(cubeIndices,cubeVertices,1);
  473.     scrollerText("Everything you see here is pure unfiltered slop, but having something is better than nothing... probably?",4,0xFFFFFFFF);
  474.     scrollerText("Why isn't there a minimal website dedicated to similar projects like these at least? I'd like to see what other people would come up with. It would be a very nice gallery.",10,0xFFFFFFFF,100);
  475.     for(let i=0;i<4;i++){
  476.         let c=0xFF000000|(floor((i/4)*255)*0x010101);
  477.         vectorText("Woah, this looks\nfucking awful!",4,36-t*.03,2+sqrt(t)*(.02+i*.03),c);
  478.     }
  479.     vectorText("Woah, this looks\nfucking awful!",4,36,2,0xFFFFFFFF);
  480.     //---
  481.     ctx.putImageData(imgDat,0,0);
  482.     pmouseX=mouseX;pmouseY=mouseY;pmouseDown=mouseDown;
  483.     frame++;requestAnimationFrame(render);
  484. }
  485. requestAnimationFrame(render);
  486. </script></body></html>
Advertisement
Add Comment
Please, Sign In to add comment