| 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>Cinema</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:#000;overflow:hidden;height:100vh}canvas{display:block}#loading{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#000;color:#888;font-size:14px;z-index:20;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;transition:opacity .6s}#loading.hidden{opacity:0;pointer-events:none}.controls{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:10px;z-index:10;background:rgba(0,0,0,.8);border:1px solid rgba(255,255,255,.08);border-radius:10px;padding:8px 18px;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif}.ctrl-btn{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);color:rgba(255,255,255,.5);border-radius:6px;cursor:pointer;padding:6px 12px;font-size:12px;font-family:inherit;transition:background .15s,color .15s}.ctrl-btn:hover{background:rgba(255,255,255,.14);color:#fff}.ctrl-sep{width:1px;height:22px;background:rgba(255,255,255,.08)}.ctrl-label{font-size:10px;color:#444;text-transform:uppercase;letter-spacing:.7px}.ctrl-val{font-size:var(--font-size-caption-1);color:#c9a55a;font-weight:600;min-width:14px;text-align:center}.page-info{font-size:var(--font-size-caption-2);color:rgba(255,255,255,.25);min-width:60px;text-align:center}.ctrl-sm{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);color:rgba(255,255,255,.4);border-radius:4px;cursor:pointer;width:22px;height:22px;font-size:12px;display:flex;align-items:center;justify-content:center;font-family:inherit}.ctrl-sm:hover{background:rgba(255,255,255,.12);color:#fff}</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="c"></canvas><div class="controls"><button class="ctrl-btn" id="prevBtn">‹</button> <button class="ctrl-btn" id="playBtn">❚❚</button> <button class="ctrl-btn" id="nextBtn">›</button><div class="ctrl-sep"></div><span class="page-info" id="pageInfo">1 / ?</span><div class="ctrl-sep"></div><span class="ctrl-label">Speed</span> <button class="ctrl-sm" id="speedDown">−</button> <span class="ctrl-val" id="speedVal">3</span> <button class="ctrl-sm" id="speedUp">+</button><div class="ctrl-sep"></div><span class="ctrl-label">Grain</span> <button class="ctrl-sm" id="grainDown">−</button> <span class="ctrl-val" id="grainVal">3</span> <button class="ctrl-sm" id="grainUp">+</button></div><script src="/static/platform/icon.js"></script><script src="/static/view-lib/thumbnail.js"></script><script>const canvas=document.getElementById("c"),ctx=canvas.getContext("2d");let W,H;function resize(){W=canvas.width=window.innerWidth,H=canvas.height=window.innerHeight}resize();const BATCH=50;let allPhotos=[],totalPhotos=0,loadedUpTo=0,currentIdx=0,currentImg=null,nextImg=null,playing=!0,speed=3,grainLevel=3;const SPEED_DURATIONS=[8,6,4.5,3,2];let slideTimer=0,transitioning=!1,transitionPhase=0,transitionTimer=0,countdownNumber=3,scratches=[],dustSpecs=[],flickerAlpha=1,gateJitterX=0,gateJitterY=0;const grainCanvas=document.createElement("canvas"),grainCtx=grainCanvas.getContext("2d");function regenerateGrain(){const t=grainCtx.createImageData(256,256),e=t.data;for(let t=0;t<e.length;t+=4){const n=255*Math.random();e[t]=e[t+1]=e[t+2]=n,e[t+3]=255}grainCtx.putImageData(t,0,0)}async function loadBatch(t,e){const n=await fetch(ViewLib.Thumbnail.buildThumbnailListUrl(t,e)),a=await n.json();totalPhotos=a.total;const i=a.items.filter(t=>t.thumbnailId);for(const t of i)allPhotos.push(t);loadedUpTo=t+i.length}async function ensureLoaded(t){for(;t>=loadedUpTo&&loadedUpTo<totalPhotos;)await loadBatch(loadedUpTo,50)}function loadImage(t){return new Promise(e=>{if(t<0||t>=allPhotos.length)return void e(null);const n=new Image;n.onload=()=>e(n),n.onerror=()=>e(null),n.src=ViewLib.Thumbnail.buildThumbnailUrl(allPhotos[t].thumbnailId)})}function getScreenRect(){const t=.58*W;return{x:(W-t)/2,y:.08*H,w:t,h:.5*H}}function getPhotoRect(t,e){if(!t)return e;const n=t.width/t.height;let a,i;return n>e.w/e.h?(a=e.w-20,i=a/n):(i=e.h-20,a=i*n),{x:e.x+(e.w-a)/2,y:e.y+(e.h-i)/2,w:a,h:i}}function drawTheater(){ctx.fillStyle="#000",ctx.fillRect(0,0,W,H);const t=getScreenRect(),e=ctx.createRadialGradient(W/2,t.y+t.h/2,.3*t.h,W/2,t.y+t.h/2,.7*W);e.addColorStop(0,"rgba(40,35,25,0.3)"),e.addColorStop(1,"rgba(0,0,0,0)"),ctx.fillStyle=e,ctx.fillRect(0,0,W,H),drawCurtain(0,0,t.x-10,H,!0),drawCurtain(t.x+t.w+10,0,W-t.x-t.w-10,H,!1);const n=.7*t.y;ctx.fillStyle="#1a0808",ctx.fillRect(0,0,W,n),ctx.fillStyle="#1a0808";for(let t=0;t<W;t+=40)ctx.beginPath(),ctx.arc(t+20,n,20,0,Math.PI),ctx.fill();ctx.strokeStyle="#222",ctx.lineWidth=3,ctx.strokeRect(t.x-2,t.y-2,t.w+4,t.h+4),ctx.fillStyle="#1a1816",ctx.fillRect(t.x,t.y,t.w,t.h)}function drawCurtain(t,e,n,a,i){if(n<=0)return;const o=Math.max(3,Math.floor(n/25));for(let r=0;r<o;r++){const c=t+n/o*r,l=n/o,s=r/o,d=18+10*Math.sin(s*Math.PI*2+(i?0:1.5));ctx.fillStyle=`rgb(${d+20},${.3*d},${.3*d})`,ctx.fillRect(c,e,l+1,a)}if(i){const i=ctx.createLinearGradient(t+n-15,0,t+n,0);i.addColorStop(0,"rgba(0,0,0,0)"),i.addColorStop(1,"rgba(0,0,0,0.6)"),ctx.fillStyle=i,ctx.fillRect(t+n-15,e,15,a)}else{const n=ctx.createLinearGradient(t,0,t+15,0);n.addColorStop(0,"rgba(0,0,0,0.6)"),n.addColorStop(1,"rgba(0,0,0,0)"),ctx.fillStyle=n,ctx.fillRect(t,e,15,a)}}function drawSeats(){const t=getScreenRect(),e=t.y+t.h+30,n=H-e-30;if(n<30)return;const a=Math.min(5,Math.floor(n/22));for(let t=0;t<a;t++){const i=t/a,o=e+t*(n/a),r=W*(.45+.5*i),c=(W-r)/2,l=14+8*i,s=l+4+6*i,d=Math.floor(r/s),x=c+(r-d*s)/2,h=8+12*i;ctx.fillStyle=`rgb(${h},${h},${h+2})`;for(let t=0;t<d;t++){const e=x+t*s+s/2;ctx.beginPath(),ctx.arc(e,o,l/2,Math.PI,0),ctx.fill()}}}function drawProjectorBeam(t){const e=getScreenRect(),n=e.w+40;ctx.save(),ctx.globalAlpha=.03+.008*Math.sin(1.5*t),ctx.beginPath(),ctx.moveTo(W/2-4,0),ctx.lineTo(W/2+4,0),ctx.lineTo(e.x+e.w+20,e.y+e.h),ctx.lineTo(e.x-20,e.y+e.h),ctx.closePath(),ctx.fillStyle="#fff8e0",ctx.fill(),ctx.restore(),ctx.save(),ctx.globalAlpha=.15;for(let a=0;a<12;a++){const i=7.31*a,o=(.1*t+i)%1,r=W/2+Math.sin(3.7*i)*n/2*o,c=0+o*(e.y+e.h-0),l=1+.5*Math.sin(2.1*i+t);ctx.fillStyle="#fff8e0",ctx.beginPath(),ctx.arc(r,c,l,0,6.283),ctx.fill()}ctx.restore()}function drawPhoto(t,e,n,a){if(!t)return;const i=getPhotoRect(t,getScreenRect());ctx.save(),ctx.globalAlpha=e*flickerAlpha,ctx.drawImage(t,i.x+n,i.y+a,i.w,i.h),ctx.restore()}function updateFilmEffects(t,e){flickerAlpha=.94+.06*Math.random(),Math.random()<.03&&(flickerAlpha*=.85),gateJitterX=1.2*(Math.random()-.5),gateJitterY=.8*(Math.random()-.5),Math.random()<.06*grainLevel&&scratches.push({x:Math.random()*W,life:0,maxLife:.1+.3*Math.random(),width:.5+1.5*Math.random(),bright:Math.random()>.5});for(let e=scratches.length-1;e>=0;e--)scratches[e].life+=t,scratches[e].life>=scratches[e].maxLife&&scratches.splice(e,1);Math.random()<.04*grainLevel&&dustSpecs.push({x:Math.random()*W,y:Math.random()*H,size:1+3*Math.random(),life:0,maxLife:.3+.8*Math.random()});for(let e=dustSpecs.length-1;e>=0;e--)dustSpecs[e].life+=t,dustSpecs[e].life>=dustSpecs[e].maxLife&&dustSpecs.splice(e,1)}function drawFilmEffects(t){const e=getScreenRect(),n=[.02,.04,.06,.09,.13][grainLevel-1];ctx.save(),ctx.globalAlpha=n,ctx.globalCompositeOperation="overlay";const a=Math.floor(128*Math.random()),i=Math.floor(128*Math.random()),o=ctx.createPattern(grainCanvas,"repeat");ctx.translate(a,i),ctx.fillStyle=o,ctx.fillRect(-a,-i,W+128,H+128),ctx.restore(),Math.random()<.3&®enerateGrain();for(const t of scratches){const e=1-t.life/t.maxLife;ctx.save(),ctx.globalAlpha=e*(t.bright?.3:.15),ctx.strokeStyle=t.bright?"#fff":"#000",ctx.lineWidth=t.width,ctx.beginPath(),ctx.moveTo(t.x,0),ctx.lineTo(t.x+3*(Math.random()-.5),H),ctx.stroke(),ctx.restore()}for(const t of dustSpecs){const e=1-t.life/t.maxLife;ctx.save(),ctx.globalAlpha=.4*e,ctx.fillStyle=Math.random()>.5?"#fff":"#000",ctx.beginPath(),ctx.arc(t.x,t.y,t.size,0,6.283),ctx.fill(),ctx.restore()}const r=ctx.createRadialGradient(W/2,H/2,.25*Math.min(W,H),W/2,H/2,.7*Math.max(W,H));r.addColorStop(0,"rgba(0,0,0,0)"),r.addColorStop(1,"rgba(0,0,0,0.5)"),ctx.fillStyle=r,ctx.fillRect(0,0,W,H),ctx.save(),ctx.globalAlpha=.06,ctx.globalCompositeOperation="overlay",ctx.fillStyle="#d4a050",ctx.fillRect(e.x,e.y,e.w,e.h),ctx.restore()}function drawCountdown(t,e){const n=getScreenRect(),a=n.x+n.w/2,i=n.y+n.h/2;ctx.fillStyle="#2a2518",ctx.fillRect(n.x,n.y,n.w,n.h),ctx.strokeStyle="rgba(180,160,120,0.4)",ctx.lineWidth=1,ctx.beginPath(),ctx.moveTo(a,n.y),ctx.lineTo(a,n.y+n.h),ctx.moveTo(n.x,i),ctx.lineTo(n.x+n.w,i),ctx.stroke();const o=.3*Math.min(n.w,n.h);ctx.strokeStyle="rgba(180,160,120,0.5)",ctx.lineWidth=2,ctx.beginPath(),ctx.arc(a,i,o,0,6.283),ctx.stroke(),ctx.strokeStyle="rgba(200,180,140,0.6)",ctx.lineWidth=3,ctx.beginPath(),ctx.arc(a,i,.85*o,-Math.PI/2,-Math.PI/2+e*Math.PI*2),ctx.stroke(),ctx.fillStyle="rgba(200,180,140,0.8)",ctx.font=`bold ${1.2*o}px sans-serif`,ctx.textAlign="center",ctx.textBaseline="middle",ctx.fillText(t.toString(),a,i),ctx.fillStyle="rgba(0,0,0,0.6)";for(let t=n.y;t<n.y+n.h;t+=22)ctx.fillRect(n.x+4,t,8,4.8),ctx.fillRect(n.x+n.w-12,t,8,4.8)}function startTransition(){transitioning=!0,transitionPhase=0,transitionTimer=0,countdownNumber=3}function updateTransition(t){if(transitionTimer+=t,0===transitionPhase){const t=.5,e=transitionTimer;countdownNumber=3-Math.floor(e/t),countdownNumber<1&&(transitionPhase=1,transitionTimer=0)}else 1===transitionPhase?transitionTimer>.15&&(transitionPhase=2,transitionTimer=0,currentImg=nextImg,nextImg=null):2===transitionPhase&&transitionTimer>.5&&(transitioning=!1,transitionTimer=0)}function drawTransition(){const t=getScreenRect();if(0===transitionPhase){const t=.5,e=transitionTimer%t/t;drawCountdown(Math.max(1,countdownNumber),e)}else if(1===transitionPhase){const e=transitionTimer/.15;ctx.fillStyle=`rgba(255,250,230,${.8*(1-e)})`,ctx.fillRect(t.x,t.y,t.w,t.h)}else if(2===transitionPhase){const t=Math.min(1,transitionTimer/.5);currentImg&&drawPhoto(currentImg,t,gateJitterX,gateJitterY)}}async function goTo(t){t<0&&(t=totalPhotos-1),t>=totalPhotos&&(t=0),await ensureLoaded(t),t>=allPhotos.length||(currentIdx=t,updatePageInfo(),nextImg=await loadImage(t),startTransition(),ensureLoaded(t+1))}function goNext(){goTo(currentIdx+1)}function goPrev(){goTo(currentIdx-1)}function updatePageInfo(){document.getElementById("pageInfo").textContent=currentIdx+1+" / "+totalPhotos}grainCanvas.width=256,grainCanvas.height=256,regenerateGrain();let lastTime=0;function animate(t){const e=lastTime?(t-lastTime)/1e3:.016;lastTime=t;const n=t/1e3;if(playing&&!transitioning){slideTimer+=e;slideTimer>=SPEED_DURATIONS[speed-1]&&(slideTimer=0,goNext())}transitioning&&updateTransition(e),updateFilmEffects(e,n),drawTheater(),drawProjectorBeam(n);const a=getScreenRect();transitioning?drawTransition():currentImg&&drawPhoto(currentImg,1,gateJitterX,gateJitterY),ctx.save();const i=ctx.createLinearGradient(a.x,0,a.x+8,0);i.addColorStop(0,"rgba(0,0,0,0.4)"),i.addColorStop(1,"rgba(0,0,0,0)"),ctx.fillStyle=i,ctx.fillRect(a.x,a.y,8,a.h);const o=ctx.createLinearGradient(a.x+a.w,0,a.x+a.w-8,0);if(o.addColorStop(0,"rgba(0,0,0,0.4)"),o.addColorStop(1,"rgba(0,0,0,0)"),ctx.fillStyle=o,ctx.fillRect(a.x+a.w-8,a.y,8,a.h),ctx.restore(),drawSeats(),drawFilmEffects(n),playing&&!transitioning){const t=slideTimer/SPEED_DURATIONS[speed-1];ctx.fillStyle="rgba(201,165,90,0.25)",ctx.fillRect(a.x,a.y+a.h-2,a.w*t,2)}requestAnimationFrame(animate)}const playBtn=document.getElementById("playBtn");async function init(){await loadBatch(0,50),allPhotos.length&&(currentImg=await loadImage(0),currentIdx=0,updatePageInfo(),document.getElementById("loading").classList.add("hidden"),requestAnimationFrame(animate))}document.getElementById("prevBtn").addEventListener("click",()=>{slideTimer=0,goPrev()}),document.getElementById("nextBtn").addEventListener("click",()=>{slideTimer=0,goNext()}),playBtn.addEventListener("click",()=>{playing=!playing,playBtn.innerHTML=playing?"❚❚":"▶"}),document.getElementById("speedDown").addEventListener("click",()=>{speed=Math.max(1,speed-1),document.getElementById("speedVal").textContent=speed}),document.getElementById("speedUp").addEventListener("click",()=>{speed=Math.min(5,speed+1),document.getElementById("speedVal").textContent=speed}),document.getElementById("grainDown").addEventListener("click",()=>{grainLevel=Math.max(1,grainLevel-1),document.getElementById("grainVal").textContent=grainLevel}),document.getElementById("grainUp").addEventListener("click",()=>{grainLevel=Math.min(5,grainLevel+1),document.getElementById("grainVal").textContent=grainLevel}),document.addEventListener("keydown",t=>{"ArrowLeft"===t.key?(t.preventDefault(),slideTimer=0,goPrev()):"ArrowRight"===t.key||" "===t.key?(t.preventDefault(),slideTimer=0,goNext()):"p"!==t.key&&"P"!==t.key||(playing=!playing,playBtn.innerHTML=playing?"❚❚":"▶")}),window.addEventListener("resize",resize),init()</script></body></html>