File: C:/Users/fred/AppData/Local/Microsoft/OneDrive/26.168.0830.0006/WebAssets/static/views/flag.js
const canvas=document.getElementById("c"),ctx=canvas.getContext("2d");canvas.width=window.innerWidth,canvas.height=window.innerHeight;const COLS=12,ROWS=8,ITERS=5,GRAVITY=.15,DAMPING=.985;let windLevel=3,gustPower=0,particles=[],constraints=[],cellImages=[],restDist,originX,originY,dragIdx=-1;function buildCloth(){const a=canvas.width,c=canvas.height;restDist=Math.min(a*.55/COLS,c*.6/ROWS,75),originX=a*.18,originY=c*.15,particles=[],constraints=[];for(let e=0;e<=ROWS;e++)for(let i=0;i<=COLS;i++){const t=originX+i*restDist,o=originY+e*restDist;particles.push({x:t,y:o,ox:t,oy:o,pinned:i===0,dragging:!1})}const n=COLS+1;for(let e=0;e<=ROWS;e++)for(let i=0;i<=COLS;i++){const t=e*n+i;i<COLS&&constraints.push({a:t,b:t+1,rest:restDist}),e<ROWS&&constraints.push({a:t,b:t+n,rest:restDist})}}function simulate(a){const c=windLevel*.4+gustPower;gustPower*=.96;for(const n of particles){if(n.pinned||n.dragging)continue;const e=(n.x-n.ox)*DAMPING,i=(n.y-n.oy)*DAMPING;n.ox=n.x,n.oy=n.y;const t=c*(Math.sin(a*2+n.y*.01)*.7+Math.sin(a*4.3+n.x*.02)*.3),o=c*Math.sin(a*1.8+n.x*.015)*.12;n.x+=e+t,n.y+=i+GRAVITY+o}for(let n=0;n<ITERS;n++)for(const e of constraints){const i=particles[e.a],t=particles[e.b],o=t.x-i.x,l=t.y-i.y,r=Math.sqrt(o*o+l*l);if(r<.001)continue;const d=(r-e.rest)/r*.5;!i.pinned&&!i.dragging&&(i.x+=o*d,i.y+=l*d),!t.pinned&&!t.dragging&&(t.x-=o*d,t.y-=l*d)}}function texTri(a,c,n,e,i,t,o,l,r,d,h,f,g){const s=c*(i-o)+e*(o-n)+t*(n-i);if(Math.abs(s)<.01)return;const m=(l*(i-o)+d*(o-n)+f*(n-i))/s,u=(r*(i-o)+h*(o-n)+g*(n-i))/s,p=(l*(t-e)+d*(c-t)+f*(e-c))/s,w=(r*(t-e)+h*(c-t)+g*(e-c))/s,b=(l*(e*o-t*i)+d*(t*n-c*o)+f*(c*i-e*n))/s,v=(r*(e*o-t*i)+h*(t*n-c*o)+g*(c*i-e*n))/s;ctx.save(),ctx.beginPath(),ctx.moveTo(l,r),ctx.lineTo(d,h),ctx.lineTo(f,g),ctx.closePath(),ctx.clip(),ctx.setTransform(m,u,p,w,b,v),ctx.drawImage(a,0,0),ctx.restore()}function renderCloth(){const a=COLS+1;for(let c=0;c<ROWS;c++)for(let n=0;n<COLS;n++){const e=cellImages[c*COLS+n];if(!e)continue;const i=particles[c*a+n],t=particles[c*a+n+1],o=particles[(c+1)*a+n],l=particles[(c+1)*a+n+1],r=e.width,d=e.height;texTri(e,0,0,r,0,0,d,i.x,i.y,t.x,t.y,o.x,o.y),texTri(e,r,0,r,d,0,d,t.x,t.y,l.x,l.y,o.x,o.y)}}function drawPole(){const a=particles[0],c=particles[ROWS*(COLS+1)];ctx.strokeStyle="#555",ctx.lineWidth=6,ctx.lineCap="round",ctx.beginPath(),ctx.moveTo(a.x-4,a.y-20),ctx.lineTo(c.x-4,c.y+20),ctx.stroke(),ctx.fillStyle="#777",ctx.beginPath(),ctx.arc(a.x-4,a.y-24,6,0,6.283),ctx.fill()}async function init(){buildCloth();const a=COLS*ROWS,e=(await(await fetch("/api/thumbnails?offset=0&limit="+a,{_od4ApiName:"thumbnail.batch"})).json()).items.filter(t=>t.thumbnailId);for(let t=e.length-1;t>0;t--){const o=Math.floor(Math.random()*(t+1));[e[t],e[o]]=[e[o],e[t]]}const i=[];for(let t=0;t<a;t++){const o=e[t%e.length];i.push(new Promise(l=>{const r=new Image;r.onload=()=>l(r),r.onerror=()=>l(null),r.dataset.od4ApiName="thumbnail.single",r.src="/api/thumbnail/"+o.thumbnailId}))}cellImages=(await Promise.all(i)).filter(Boolean),document.getElementById("loading").classList.add("hidden"),requestAnimationFrame(animate)}function animate(a){const c=a/1e3,n=canvas.width,e=canvas.height;simulate(c),ctx.clearRect(0,0,n,e);const i=ctx.createRadialGradient(n*.6,e*.4,0,n*.6,e*.4,n*.7);i.addColorStop(0,"#161620"),i.addColorStop(1,"#111"),ctx.fillStyle=i,ctx.fillRect(0,0,n,e),drawPole(),ctx.setTransform(1,0,0,1,0,0),renderCloth(),ctx.setTransform(1,0,0,1,0,0),requestAnimationFrame(animate)}canvas.addEventListener("mousedown",a=>{const c=a.clientX,n=a.clientY;let e=50,i=-1;for(let t=0;t<particles.length;t++){const o=Math.hypot(particles[t].x-c,particles[t].y-n);o<e&&(e=o,i=t)}i>=0&&!particles[i].pinned&&(dragIdx=i,particles[i].dragging=!0)}),canvas.addEventListener("mousemove",a=>{dragIdx>=0&&(particles[dragIdx].x=a.clientX,particles[dragIdx].y=a.clientY)}),canvas.addEventListener("mouseup",()=>{dragIdx>=0&&(particles[dragIdx].dragging=!1,dragIdx=-1)}),canvas.addEventListener("touchstart",a=>{const c=a.touches[0],n=c.clientX,e=c.clientY;let i=60,t=-1;for(let o=0;o<particles.length;o++){const l=Math.hypot(particles[o].x-n,particles[o].y-e);l<i&&(i=l,t=o)}t>=0&&!particles[t].pinned&&(dragIdx=t,particles[t].dragging=!0),a.preventDefault()},{passive:!1}),canvas.addEventListener("touchmove",a=>{if(dragIdx>=0){const c=a.touches[0];particles[dragIdx].x=c.clientX,particles[dragIdx].y=c.clientY}a.preventDefault()},{passive:!1}),canvas.addEventListener("touchend",()=>{dragIdx>=0&&(particles[dragIdx].dragging=!1,dragIdx=-1)}),document.getElementById("windDown").onclick=()=>{windLevel=Math.max(0,windLevel-1),document.getElementById("windEl").textContent=windLevel},document.getElementById("windUp").onclick=()=>{windLevel=Math.min(6,windLevel+1),document.getElementById("windEl").textContent=windLevel},document.getElementById("gustBtn").onclick=()=>{gustPower=8},window.addEventListener("resize",()=>{canvas.width=window.innerWidth,canvas.height=window.innerHeight,buildCloth()}),init();