| Server IP : 127.0.0.1 / Your IP : 216.73.216.109 Web Server : Apache/2.4.54 (Win64) OpenSSL/1.1.1q PHP/8.1.10 System : Windows NT DESKTOP-E5T4RUN 10.0 build 19045 (Windows 10) AMD64 User : SERVERWEB ( 0) PHP Version : 8.1.10 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Users/SERVERWEB/AppData/Local/Microsoft/OneDrive/26.074.0420.0001/WebAssets/ |
Upload File : |
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Instant Photos</title><script src="/static/platform/vibe-telemetry.js"></script><script src="/static/platform/od4-fetch.js"></script><script src="/static/platform/ecs.js"></script><script src="/static/view-lib/sql.js"></script><link rel="stylesheet" href="/static/tokens/scrollbar.css"><style>*{margin:0;padding:0;box-sizing:border-box}body{background:#111;color:#e0e0e0;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;overflow:hidden;width:100vw;height:100vh}canvas{display:block;width:100%;height:100%;cursor:grab}canvas.grabbing{cursor:grabbing}#loading{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);font-size:var(--font-size-body-2-stronger);color:#e0e0e0;transition:opacity .8s;z-index:10}#loading.hidden{opacity:0;pointer-events:none}.action-bar{position:fixed;bottom:20px;right:20px;display:flex;gap:10px;z-index:10}.action-btn{padding:12px 24px;background:#7b9dff;color:#111;border:none;border-radius:6px;font-family:inherit;font-size:14px;font-weight:700;cursor:pointer;transition:background .15s,transform .15s}.action-btn:hover{background:#97b3ff;transform:scale(1.05)}</style><script src="/static/view-lib/theme-sync.js"></script><script src="/static/view-lib/user-activity.js"></script><script>ViewLib.ThemeSync.applyDirFromParent()</script></head><body><div id="loading">Loading photos...</div><canvas id="canvas"></canvas><div class="action-bar"><button id="random-btn" class="action-btn">Random</button> <button id="arrange-btn" class="action-btn">Arrange</button> <button id="scatter-btn" class="action-btn">Scatter</button></div><script src="/static/view-lib/messages.js"></script><script src="/static/platform/icon.js"></script><script src="/static/view-lib/thumbnail.js"></script><script src="/static/view-lib/filters.js"></script><script>!function(){"use strict";const t=document.getElementById("canvas"),n=t.getContext("2d"),e=document.getElementById("loading"),o=document.getElementById("scatter-btn"),a=document.getElementById("arrange-btn"),r=document.getElementById("random-btn");let i,l;const s=[],h=[];let c=[],d=performance.now(),f=0,u=0,m=1;let y=null,x={x:0,y:0},w=!1,v=0,g=0,M=!1,b=[];const p=400,L=new Set;let E=[],I=0;function S(){E=s.map((t,n)=>n);for(let t=E.length-1;t>0;t--){const n=Math.floor(Math.random()*(t+1));[E[t],E[n]]=[E[n],E[t]]}I=0}function Y(){i=window.innerWidth,l=window.innerHeight,t.width=i,t.height=l}function X(t,n){return{x:(t-f)/m,y:(n-u)/m}}Y(),window.addEventListener("resize",Y);const B=ViewLib.Filters.parseUrlFilterState(),C=ViewLib.Filters.buildApiQueryString(B);async function k(t){const n=t?`&sort=${t}`:"";try{const t=await fetch(ViewLib.Thumbnail.buildThumbnailListUrl(0,200,C+n)),o=await t.json(),a=new Set,r=o.items.filter(t=>t.thumbnailId&&!a.has(t.thumbnailId)&&a.add(t.thumbnailId)).map(t=>new Promise(n=>{const e=new Image;e.onload=()=>{s.push(e),h.push(t.thumbnailId),n()},e.onerror=()=>n(),e.src=ViewLib.Thumbnail.buildThumbnailUrl(t.thumbnailId)}));await Promise.all(r),e.classList.add("hidden")}catch(t){e.textContent="Failed to load photos"}}function T(t,n){const e=I>=E.length?null:s[E[I++]];if(!e)return null;const o=104/(e.naturalWidth/e.naturalHeight||1),a=o+8+28;return{x:t,y:n,rotation:.4*(Math.random()-.5),vx:0,vy:0,vr:0,w:120,h:a,photoW:104,photoH:o,img:e}}function F(){c=[],L.clear();const t=X(0,0),n=X(i,l);for(;I<E.length;){const e=T(t.x+Math.random()*(n.x-t.x),t.y+Math.random()*(n.y-t.y));if(!e)break;c.push(e)}const e=p,o=Math.floor((t.x-e)/p),a=Math.floor((n.x+e)/p),r=Math.floor((t.y-e)/p),s=Math.floor((n.y+e)/p);for(let t=o;t<=a;t++)for(let n=r;n<=s;n++)L.add(V(t,n))}function V(t,n){return t+","+n}function W(){if(0===s.length||I>=E.length)return;const t=X(0,0),n=X(i,l),e=p,o=Math.floor((t.x-e)/p),a=Math.floor((n.x+e)/p),r=Math.floor((t.y-e)/p),h=Math.floor((n.y+e)/p);for(let t=o;t<=a;t++)for(let n=r;n<=h;n++){const e=V(t,n);if(!L.has(e)){L.add(e);for(let e=0;e<10;e++){if(I>=E.length)return;const e=T(t*p+Math.random()*p,n*p+Math.random()*p);e&&c.push(e)}}}}function H(t,n,e){const o=t-e.x,a=n-e.y,r=Math.cos(-e.rotation),i=Math.sin(-e.rotation),l=o*r-a*i,s=o*i+a*r;return l>=-e.w/2&&l<=e.w/2&&s>=-e.h/2&&s<=e.h/2}function O(t){n.save(),n.translate(t.x,t.y),n.rotate(t.rotation),n.shadowColor="rgba(0,0,0,0.5)",n.shadowBlur=15/m,n.shadowOffsetX=3/m,n.shadowOffsetY=3/m,n.fillStyle="#ffffff",n.fillRect(-t.w/2,-t.h/2,t.w,t.h),n.shadowColor="transparent",n.shadowBlur=0,n.shadowOffsetX=0,n.shadowOffsetY=0,n.drawImage(t.img,-t.w/2+8,-t.h/2+8,t.photoW,t.photoH),n.restore()}function P(){requestAnimationFrame(P);const t=performance.now(),e=Math.min((t-d)/1e3,.1);d=t,function(t){for(const n of c)n!==y&&(n.x+=n.vx*t,n.y+=n.vy*t,n.rotation+=n.vr*t,n.vx*=.97,n.vy*=.97,n.vr*=.95,Math.abs(n.vx)<.5&&(n.vx=0),Math.abs(n.vy)<.5&&(n.vy=0),Math.abs(n.vr)<.01&&(n.vr=0))}(e),function(){const t=n.createLinearGradient(0,0,i,l);t.addColorStop(0,"#2a1f15"),t.addColorStop(1,"#1a1510"),n.fillStyle=t,n.fillRect(0,0,i,l),n.save(),n.translate(f,u),n.scale(m,m);const e=X(0,0),o=X(i,l);n.strokeStyle="rgba(255,220,180,0.03)",n.lineWidth=1/m;for(let t=40*Math.floor(e.y/40);t<o.y;t+=40)n.beginPath(),n.moveTo(e.x,t),n.lineTo(o.x,t),n.stroke();n.restore()}();const o=X(-200,-200),a=X(i+200,l+200);n.save(),n.translate(f,u),n.scale(m,m);for(const t of c)t.x+t.w<o.x||t.x-t.w>a.x||t.y+t.h<o.y||t.y-t.h>a.y||O(t);n.restore()}o.addEventListener("click",function(){const t=X(0,0),n=X(i,l);c.forEach(e=>{e.x=t.x+Math.random()*(n.x-t.x),e.y=t.y+Math.random()*(n.y-t.y),e.rotation=.4*(Math.random()-.5),e.vx=300*(Math.random()-.5),e.vy=300*(Math.random()-.5),e.vr=2*(Math.random()-.5)})}),a.addEventListener("click",function(){if(0===c.length)return;const t=Math.max(1,Math.ceil(Math.sqrt(c.length))),n=-(140*t)/2,e=-176*Math.ceil(c.length/t)/2;c.forEach((o,a)=>{const r=a%t,i=Math.floor(a/t);o.x=n+140*r+70,o.y=e+176*i+88,o.rotation=.12*(Math.random()-.5),o.vx=0,o.vy=0,o.vr=0}),f=i/2,u=l/2,m=1}),r.addEventListener("click",async()=>{r.disabled=!0,e.textContent="Loading photos...",e.classList.remove("hidden"),s.length=0,h.length=0,c=[],L.clear(),await k("random"),S(),F(),r.disabled=!1}),t.addEventListener("mousedown",n=>{if(0!==n.button)return;const e=X(n.clientX,n.clientY);M=!1,b=[{x:n.clientX,y:n.clientY,t:performance.now()}];for(let n=c.length-1;n>=0;n--)if(H(e.x,e.y,c[n]))return y=c[n],c.splice(n,1),c.push(y),x.x=e.x-y.x,x.y=e.y-y.y,y.vx=0,y.vy=0,y.vr=0,void t.classList.add("grabbing");w=!0,v=n.clientX-f,g=n.clientY-u,t.classList.add("grabbing")}),window.addEventListener("mousemove",t=>{const n=performance.now();if(b.push({x:t.clientX,y:t.clientY,t:n}),b.length>5&&b.shift(),y){const n=X(t.clientX,t.clientY);y.x=n.x-x.x,y.y=n.y-x.y,M=!0}else if(w){const n=t.clientX-v,e=t.clientY-g;(Math.abs(n-f)>2||Math.abs(e-u)>2)&&(M=!0),f=n,u=e,W()}}),window.addEventListener("mouseup",()=>{if(y){const t=performance.now(),n=b.filter(n=>t-n.t<100);if(n.length>=2){const t=n[0],e=n[n.length-1],o=(e.t-t.t)/1e3;o>.001&&(y.vx=(e.x-t.x)/o/m,y.vy=(e.y-t.y)/o/m,y.vr=2*(Math.random()-.5))}y=null}w=!1,t.classList.remove("grabbing")}),t.addEventListener("wheel",t=>{t.preventDefault();const n=t.clientX,e=t.clientY,o=m,a=.001*-t.deltaY;m=Math.min(4,Math.max(.15,m*(1+a)));const r=m/o;f=n-r*(n-f),u=e-r*(e-u),W()},{passive:!1}),ViewLib.Messages.setupSpotlightResponder(function(){return h}),k().then(()=>{f=i/2,u=l/2,S(),F(),P()})}()</script></body></html>