GLM 5.1 test

Reddit r/LocalLLaMA / 4/8/2026

💬 OpinionDeveloper Stack & InfrastructureSignals & Early TrendsTools & Practical UsageModels & Research

Key Points

  • The author shares a personal test deployment of GLM 5.1 from ZAI using the sglang container on an HGX H200, configured with tensor parallelism and speculative decoding settings (EAGLE, num draft steps, etc.).
  • They note being impressed by the model’s output but mention it spent an unusually long time “thinking” (about 7 minutes), with repeated self-checking.
  • The post includes a detailed coding prompt requesting a single-file, library-free HTML/CSS/vanilla JS Rubik’s Cube that can scramble and then solve itself with smooth, realistic layer rotations and animations.
  • It also references example processing of additional media (video and images) and links to an Instagram post that initially sparked their interest.

Processing video 4w0egf932ytg1...

Hello lads. Wanted to share my test of GLM 5.1 from ZAI

Deployed it on my company`s HGX H200 with this command

docker run -d \ --name name \ --restart unless-stopped \ --gpus all \ --shm-size 32g \ --ipc=host \ -v ... \ -p 1984:30000 \ lmsysorg/sglang:dev \ sglang serve \ --model-path /model \ --host 0.0.0.0 \ --port 30000 \ --tp 8 \ --reasoning-parser glm45 \ --tool-call-parser glm47 \ --speculative-algorithm EAGLE \ --speculative-num-steps 3 \ --speculative-eagle-topk 1 \ --speculative-num-draft-tokens 4 \ --mem-fraction-static 0.85 \ --served-model-name name \ --enable-metrics 

https://www.instagram.com/p/DWEcde4ESI_/

Just saw some stupid instagram post with this prompt and got interested. Can say. that i`m impressed. But mode thought for 7 minutes lol, reassuring itself multiple times

Processing img yual7fn02ytg1...

Processing img i3gr9by02ytg1...

Prompt

Create a single-file HTML page using only HTML, CSS, and vanilla JavaScript (no libraries). Build a centered 3D scene containing a fully functional Rubik’s Cube made of 27 smaller cubies. Each cubie must have correctly colored faces (classic cube colors). The cube should: - Start idle with a slight 3D perspective view - Include a "Start" button below the scene - When clicked, automatically scramble the cube with random realistic face rotations - Then solve itself step by step using reverse moves or a logical sequence - Each move must animate smoothly with easing (no instant jumps) - Rotations should affect only correct layers (like real cube physics) Animation requirements: - Total loop duration: ~30 seconds - Include phases: scramble → solve → short pause → repeat infinitely - Use smooth cubic-bezier or ease-in-out transitions Visual style: - Dark background (black or gradient) - Glowing cube faces with subtle reflections - Soft shadows and depth for realism - Clean modern UI button with hover animation Extra features: - Allow mouse drag to rotate the entire cube in real time - Maintain transform consistency (no breaking cube structure) - Ensure animation is smooth and optimized Output: - Return complete working code in one HTML file only - No explanation, only code 

Generated code

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Rubik's Cube</title> <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&display=swap" rel="stylesheet"> <style> *{margin:0;padding:0;box-sizing:border-box} body{ background: radial-gradient(ellipse at 30% 20%,rgba(18,22,55,0.5) 0%,transparent 55%), radial-gradient(ellipse at 70% 80%,rgba(55,12,28,0.3) 0%,transparent 55%), #030308; min-height:100vh; display:flex;flex-direction:column;align-items:center;justify-content:center; font-family:'Space Grotesk',sans-serif; overflow:hidden;user-select:none;-webkit-user-select:none; } #scene{ width:440px;height:440px; perspective:880px;perspective-origin:50% 48%; display:flex;align-items:center;justify-content:center; position:relative; } #scene::after{ content:'';position:absolute;bottom:12%;left:50%;transform:translateX(-50%); width:200px;height:30px; background:radial-gradient(ellipse,rgba(140,160,255,0.07) 0%,transparent 70%); border-radius:50%;pointer-events:none;filter:blur(8px); } #cube-container{ transform-style:preserve-3d;position:relative;cursor:grab; } #cube-container:active{cursor:grabbing} .cubie{ position:absolute;left:0;top:0;width:0;height:0; transform-style:preserve-3d; } .face{ position:absolute; width:60px;height:60px;left:-30px;top:-30px; border-radius:5px; backface-visibility:hidden; overflow:hidden; } .face::after{ content:'';position:absolute;inset:0;border-radius:inherit; background:linear-gradient(135deg,rgba(255,255,255,0.28) 0%,rgba(255,255,255,0.06) 30%,transparent 52%,rgba(0,0,0,0.13) 100%); pointer-events:none; } .face.front{transform:translateZ(33px)} .face.back{transform:rotateY(180deg) translateZ(33px)} .face.right{transform:rotateY(90deg) translateZ(33px)} .face.left{transform:rotateY(-90deg) translateZ(33px)} .face.top{transform:rotateX(90deg) translateZ(33px)} .face.bottom{transform:rotateX(-90deg) translateZ(33px)} .face-outer{ box-shadow:inset 0 0 10px rgba(255,255,255,0.06); border:1px solid rgba(255,255,255,0.08); } #status{ margin-top:28px;color:rgba(255,255,255,0.35); font-size:12px;letter-spacing:4px;text-transform:uppercase; min-height:20px;transition:color 0.5s ease;font-weight:600; } #start-btn{ margin-top:14px;padding:14px 52px; font-size:14px;font-weight:700;letter-spacing:4px; color:#fff;background:linear-gradient(135deg,#e94560,#c62a4a); border:none;border-radius:50px;cursor:pointer; transition:all 0.35s cubic-bezier(0.4,0,0.2,1); box-shadow:0 4px 24px rgba(233,69,96,0.3); font-family:'Space Grotesk',sans-serif; position:relative;overflow:hidden; } #start-btn::before{ content:'';position:absolute;top:0;left:-100%; width:100%;height:100%; background:linear-gradient(90deg,transparent,rgba(255,255,255,0.15),transparent); transition:left 0.55s ease; } #start-btn:hover::before{left:100%} #start-btn:hover{ transform:translateY(-3px); box-shadow:0 8px 32px rgba(233,69,96,0.45); background:linear-gradient(135deg,#f05a73,#d63350); } #start-btn:active{transform:translateY(1px);box-shadow:0 2px 12px rgba(233,69,96,0.25)} #start-btn:disabled{ background:linear-gradient(135deg,#2a2a35,#1e1e28); box-shadow:0 2px 10px rgba(0,0,0,0.3);cursor:default; color:rgba(255,255,255,0.25); } #start-btn:disabled:hover{transform:none;box-shadow:0 2px 10px rgba(0,0,0,0.3)} #start-btn:disabled::before{display:none} pulse{0%,100%{opacity:0.35}50%{opacity:0.7}} #status.active{animation:pulse 1.8s ease-in-out infinite} </style> </head> <body> <div id="scene"><div id="cube-container"></div></div> <div id="status">DRAG TO ROTATE</div> <button id="start-btn">START</button> <script> /* ========== Matrix Utilities ========== */ function mat3Mul(a,b){ const r=[[0,0,0],[0,0,0],[0,0,0]]; for(let i=0;i<3;i++)for(let j=0;j<3;j++)for(let k=0;k<3;k++)r[i][j]+=a[i][k]*b[k][j]; return r; } function mat3Css(m){ return `matrix3d(${m[0][0]},${m[1][0]},${m[2][0]},0,${m[0][1]},${m[1][1]},${m[2][1]},0,${m[0][2]},${m[1][2]},${m[2][2]},0,0,0,0,1)`; } function rotMat(axis,deg){ const a=deg*Math.PI/180,c=Math.cos(a),s=Math.sin(a); if(axis==='x')return[[1,0,0],[0,c,-s],[0,s,c]]; if(axis==='y')return[[c,0,s],[0,1,0],[-s,0,c]]; return[[c,-s,0],[s,c,0],[0,0,1]]; } function mat3Vec(m,v){ return{x:m[0][0]*v.x+m[0][1]*v.y+m[0][2]*v.z,y:m[1][0]*v.x+m[1][1]*v.y+m[1][2]*v.z,z:m[2][0]*v.x+m[2][1]*v.y+m[2][2]*v.z}; } function roundMat(m){return m.map(r=>r.map(v=>Math.round(v)))} /* ========== Easing ========== */ function easeIO(t){return t<0.5?4*t*t*t:1-Math.pow(-2*t+2,3)/2} /* ========== Constants ========== */ const SP=70; // spacing between cubie centers const CH=33; // cubie half-size (face translateZ) const COLORS={ right:'#b71234',left:'#ff5800',top:'#ffffff', bottom:'#ffd500',front:'#009b48',back:'#0046ad',inner:'#0e0e0e' }; /* Move definitions — CSS Y-down coordinate system */ const MOVES={ R :{axis:'x',layer:1, angle:90}, Ri:{axis:'x',layer:1, angle:-90}, L :{axis:'x',layer:-1,angle:-90}, Li:{axis:'x',layer:-1,angle:90}, U :{axis:'y',layer:-1,angle:90}, Ui:{axis:'y',layer:-1,angle:-90}, D :{axis:'y',layer:1, angle:-90}, Di:{axis:'y',layer:1, angle:90}, F :{axis:'z',layer:1, angle:90}, Fi:{axis:'z',layer:1, angle:-90}, B :{axis:'z',layer:-1,angle:-90}, Bi:{axis:'z',layer:-1,angle:90}, }; const MKEYS=Object.keys(MOVES); function inv(n){return n.endsWith('i')?n.slice(0,-1):n+'i'} /* ========== Cube State ========== */ const container=document.getElementById('cube-container'); const cubies=[]; const I3=[[1,0,0],[0,1,0],[0,0,1]]; function buildCube(){ for(let x=-1;x<=1;x++)for(let y=-1;y<=1;y++)for(let z=-1;z<=1;z++){ const cb={op:{x,y,z},m:JSON.parse(JSON.stringify(I3)),el:null}; const el=document.createElement('div');el.className='cubie'; const fc=[ {n:'front', c:z===1?COLORS.front:null}, {n:'back', c:z===-1?COLORS.back:null}, {n:'right', c:x===1?COLORS.right:null}, {n:'left', c:x===-1?COLORS.left:null}, {n:'top', c:y===-1?COLORS.top:null}, {n:'bottom',c:y===1?COLORS.bottom:null}, ]; fc.forEach(f=>{ const d=document.createElement('div'); d.className='face '+f.n; if(f.c){d.style.backgroundColor=f.c;d.classList.add('face-outer')} else{d.style.backgroundColor=COLORS.inner} el.appendChild(d); }); cb.el=el;container.appendChild(el); setTrans(cb); cubies.push(cb); } } function curPos(cb){ const p=mat3Vec(cb.m,cb.op); return{x:Math.round(p.x),y:Math.round(p.y),z:Math.round(p.z)}; } function transStr(cb){ return mat3Css(cb.m)+` translate3d(${cb.op.x*SP}px,${cb.op.y*SP}px,${cb.op.z*SP}px)`; } function setTrans(cb){cb.el.style.transform=transStr(cb)} /* ========== Move Animation ========== */ async function doMove(name,dur=480){ const d=MOVES[name],{axis,layer,angle}=d; const axU=axis.toUpperCase(); const aff=cubies.filter(c=>curPos(c)[axis]===layer); aff.forEach(c=>{c._b=transStr(c)}); const t0=performance.now(); await new Promise(res=>{ function tick(now){ const p=Math.min((now-t0)/dur,1),e=easeIO(p),a=angle*e; aff.forEach(c=>{c.el.style.transform=`rotate${axU}(${a}deg) ${c._b}`}); if(p<1)requestAnimationFrame(tick); else{ const rm=rotMat(axis,angle); aff.forEach(c=>{c.m=roundMat(mat3Mul(rm,c.m));setTrans(c)}); res(); } } requestAnimationFrame(tick); }); } /* ========== Scramble & Solve ========== */ let hist=[]; async function scramble(n=22){ hist=[];let last=''; for(let i=0;i<n;i++){ let mv,att=0; do{mv=MKEYS[Math.floor(Math.random()*MKEYS.length)];att++} while((mv===last||mv===inv(last))&&att<30); hist.push(mv);last=mv; await doMove(mv,420); } } async function solve(){ const rev=[...hist].reverse().map(inv); for(const mv of rev)await doMove(mv,420); hist=[]; } function delay(ms){return new Promise(r=>setTimeout(r,ms))} /* ========== Mouse / Touch Drag ========== */ let rx=-28,ry=38,drag=false,lx,ly; const scene=document.getElementById('scene'); function updCont(){container.style.transform=`rotateX(${rx}deg) rotateY(${ry}deg)`} scene.addEventListener('mousedown',e=>{drag=true;lx=e.clientX;ly=e.clientY}); window.addEventListener('mousemove',e=>{ if(!drag)return; ry+=(e.clientX-lx)*0.45;rx-=(e.clientY-ly)*0.45; rx=Math.max(-89,Math.min(89,rx));lx=e.clientX;ly=e.clientY;updCont(); }); window.addEventListener('mouseup',()=>{drag=false}); scene.addEventListener('touchstart',e=>{drag=true;lx=e.touches[0].clientX;ly=e.touches[0].clientY},{passive:true}); window.addEventListener('touchmove',e=>{ if(!drag)return;e.preventDefault(); const t=e.touches[0]; ry+=(t.clientX-lx)*0.45;rx-=(t.clientY-ly)*0.45; rx=Math.max(-89,Math.min(89,rx));lx=t.clientX;ly=t.clientY;updCont(); },{passive:false}); window.addEventListener('touchend',()=>{drag=false}); /* ========== Idle Auto-Rotation ========== */ let idle=true; function idleTick(){ if(!idle)return; ry+=0.1;updCont();requestAnimationFrame(idleTick); } /* ========== Status & Button ========== */ const statusEl=document.getElementById('status'); const btn=document.getElementById('start-btn'); let started=false; btn.addEventListener('click',()=>{ if(started)return;started=true;idle=false; btn.disabled=true; runLoop(); }); async function runLoop(){ while(true){ statusEl.textContent='SCRAMBLING';statusEl.style.color='rgba(233,69,96,0.7)'; statusEl.classList.add('active'); await scramble(22); statusEl.textContent='ANALYZING';statusEl.style.color='rgba(0,155,72,0.6)'; await delay(1400); statusEl.textContent='SOLVING';statusEl.style.color='rgba(0,200,83,0.7)'; await solve(); statusEl.textContent='SOLVED';statusEl.style.color='rgba(255,213,0,0.75)'; statusEl.classList.remove('active'); await delay(2800); statusEl.classList.add('active'); } } /* ========== Initialize ========== */ buildCube(); updCont(); idleTick(); </script> </body> </html>Hello lads. Wanted to share my test of GLM 5.1 from ZAIDeployed it on my company`s HGX H200 with this commanddocker run -d \ --name name \ --restart unless-stopped \ --gpus all \ --shm-size 32g \ --ipc=host \ -v ... \ -p 1984:30000 \ lmsysorg/sglang:dev \ sglang serve \ --model-path /model \ --host 0.0.0.0 \ --port 30000 \ --tp 8 \ --reasoning-parser glm45 \ --tool-call-parser glm47 \ --speculative-algorithm EAGLE \ --speculative-num-steps 3 \ --speculative-eagle-topk 1 \ --speculative-num-draft-tokens 4 \ --mem-fraction-static 0.85 \ --served-model-name name \ --enable-metricshttps://www.instagram.com/p/DWEcde4ESI_/Just saw some stupid instagram post with this prompt and got interested. Can say. that i`m impressed. But mode thought for 7 minutes lol, reassuring itself multiple timesPromptCreate a single-file HTML page using only HTML, CSS, and vanilla JavaScript (no libraries). Build a centered 3D scene containing a fully functional Rubik’s Cube made of 27 smaller cubies. Each cubie must have correctly colored faces (classic cube colors). The cube should: - Start idle with a slight 3D perspective view - Include a "Start" button below the scene - When clicked, automatically scramble the cube with random realistic face rotations - Then solve itself step by step using reverse moves or a logical sequence - Each move must animate smoothly with easing (no instant jumps) - Rotations should affect only correct layers (like real cube physics) Animation requirements: - Total loop duration: ~30 seconds - Include phases: scramble → solve → short pause → repeat infinitely - Use smooth cubic-bezier or ease-in-out transitions Visual style: - Dark background (black or gradient) - Glowing cube faces with subtle reflections - Soft shadows and depth for realism - Clean modern UI button with hover animation Extra features: - Allow mouse drag to rotate the entire cube in real time - Maintain transform consistency (no breaking cube structure) - Ensure animation is smooth and optimized Output: - Return complete working code in one HTML file only - No explanation, only codeGenerated code<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Rubik's Cube</title> <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&display=swap" rel="stylesheet"> <style> *{margin:0;padding:0;box-sizing:border-box} body{ background: radial-gradient(ellipse at 30% 20%,rgba(18,22,55,0.5) 0%,transparent 55%), radial-gradient(ellipse at 70% 80%,rgba(55,12,28,0.3) 0%,transparent 55%), #030308; min-height:100vh; display:flex;flex-direction:column;align-items:center;justify-content:center; font-family:'Space Grotesk',sans-serif; overflow:hidden;user-select:none;-webkit-user-select:none; } #scene{ width:440px;height:440px; perspective:880px;perspective-origin:50% 48%; display:flex;align-items:center;justify-content:center; position:relative; } #scene::after{ content:'';position:absolute;bottom:12%;left:50%;transform:translateX(-50%); width:200px;height:30px; background:radial-gradient(ellipse,rgba(140,160,255,0.07) 0%,transparent 70%); border-radius:50%;pointer-events:none;filter:blur(8px); } #cube-container{ transform-style:preserve-3d;position:relative;cursor:grab; } #cube-container:active{cursor:grabbing} .cubie{ position:absolute;left:0;top:0;width:0;height:0; transform-style:preserve-3d; } .face{ position:absolute; width:60px;height:60px;left:-30px;top:-30px; border-radius:5px; backface-visibility:hidden; overflow:hidden; } .face::after{ content:'';position:absolute;inset:0;border-radius:inherit; background:linear-gradient(135deg,rgba(255,255,255,0.28) 0%,rgba(255,255,255,0.06) 30%,transparent 52%,rgba(0,0,0,0.13) 100%); pointer-events:none; } .face.front{transform:translateZ(33px)} .face.back{transform:rotateY(180deg) translateZ(33px)} .face.right{transform:rotateY(90deg) translateZ(33px)} .face.left{transform:rotateY(-90deg) translateZ(33px)} .face.top{transform:rotateX(90deg) translateZ(33px)} .face.bottom{transform:rotateX(-90deg) translateZ(33px)} .face-outer{ box-shadow:inset 0 0 10px rgba(255,255,255,0.06); border:1px solid rgba(255,255,255,0.08); } #status{ margin-top:28px;color:rgba(255,255,255,0.35); font-size:12px;letter-spacing:4px;text-transform:uppercase; min-height:20px;transition:color 0.5s ease;font-weight:600; } #start-btn{ margin-top:14px;padding:14px 52px; font-size:14px;font-weight:700;letter-spacing:4px; color:#fff;background:linear-gradient(135deg,#e94560,#c62a4a); border:none;border-radius:50px;cursor:pointer; transition:all 0.35s cubic-bezier(0.4,0,0.2,1); box-shadow:0 4px 24px rgba(233,69,96,0.3); font-family:'Space Grotesk',sans-serif; position:relative;overflow:hidden; } #start-btn::before{ content:'';position:absolute;top:0;left:-100%; width:100%;height:100%; background:linear-gradient(90deg,transparent,rgba(255,255,255,0.15),transparent); transition:left 0.55s ease; } #start-btn:hover::before{left:100%} #start-btn:hover{ transform:translateY(-3px); box-shadow:0 8px 32px rgba(233,69,96,0.45); background:linear-gradient(135deg,#f05a73,#d63350); } #start-btn:active{transform:translateY(1px);box-shadow:0 2px 12px rgba(233,69,96,0.25)} #start-btn:disabled{ background:linear-gradient(135deg,#2a2a35,#1e1e28); box-shadow:0 2px 10px rgba(0,0,0,0.3);cursor:default; color:rgba(255,255,255,0.25); } #start-btn:disabled:hover{transform:none;box-shadow:0 2px 10px rgba(0,0,0,0.3)} #start-btn:disabled::before{display:none} pulse{0%,100%{opacity:0.35}50%{opacity:0.7}} #status.active{animation:pulse 1.8s ease-in-out infinite} </style> </head> <body> <div id="scene"><div id="cube-container"></div></div> <div id="status">DRAG TO ROTATE</div> <button id="start-btn">START</button> <script> /* ========== Matrix Utilities ========== */ function mat3Mul(a,b){ const r=[[0,0,0],[0,0,0],[0,0,0]]; for(let i=0;i<3;i++)for(let j=0;j<3;j++)for(let k=0;k<3;k++)r[i][j]+=a[i][k]*b[k][j]; return r; } function mat3Css(m){ return `matrix3d(${m[0][0]},${m[1][0]},${m[2][0]},0,${m[0][1]},${m[1][1]},${m[2][1]},0,${m[0][2]},${m[1][2]},${m[2][2]},0,0,0,0,1)`; } function rotMat(axis,deg){ const a=deg*Math.PI/180,c=Math.cos(a),s=Math.sin(a); if(axis==='x')return[[1,0,0],[0,c,-s],[0,s,c]]; if(axis==='y')return[[c,0,s],[0,1,0],[-s,0,c]]; return[[c,-s,0],[s,c,0],[0,0,1]]; } function mat3Vec(m,v){ return{x:m[0][0]*v.x+m[0][1]*v.y+m[0][2]*v.z,y:m[1][0]*v.x+m[1][1]*v.y+m[1][2]*v.z,z:m[2][0]*v.x+m[2][1]*v.y+m[2][2]*v.z}; } function roundMat(m){return m.map(r=>r.map(v=>Math.round(v)))} /* ========== Easing ========== */ function easeIO(t){return t<0.5?4*t*t*t:1-Math.pow(-2*t+2,3)/2} /* ========== Constants ========== */ const SP=70; // spacing between cubie centers const CH=33; // cubie half-size (face translateZ) const COLORS={ right:'#b71234',left:'#ff5800',top:'#ffffff', bottom:'#ffd500',front:'#009b48',back:'#0046ad',inner:'#0e0e0e' }; /* Move definitions — CSS Y-down coordinate system */ const MOVES={ R :{axis:'x',layer:1, angle:90}, Ri:{axis:'x',layer:1, angle:-90}, L :{axis:'x',layer:-1,angle:-90}, Li:{axis:'x',layer:-1,angle:90}, U :{axis:'y',layer:-1,angle:90}, Ui:{axis:'y',layer:-1,angle:-90}, D :{axis:'y',layer:1, angle:-90}, Di:{axis:'y',layer:1, angle:90}, F :{axis:'z',layer:1, angle:90}, Fi:{axis:'z',layer:1, angle:-90}, B :{axis:'z',layer:-1,angle:-90}, Bi:{axis:'z',layer:-1,angle:90}, }; const MKEYS=Object.keys(MOVES); function inv(n){return n.endsWith('i')?n.slice(0,-1):n+'i'} /* ========== Cube State ========== */ const container=document.getElementById('cube-container'); const cubies=[]; const I3=[[1,0,0],[0,1,0],[0,0,1]]; function buildCube(){ for(let x=-1;x<=1;x++)for(let y=-1;y<=1;y++)for(let z=-1;z<=1;z++){ const cb={op:{x,y,z},m:JSON.parse(JSON.stringify(I3)),el:null}; const el=document.createElement('div');el.className='cubie'; const fc=[ {n:'front', c:z===1?COLORS.front:null}, {n:'back', c:z===-1?COLORS.back:null}, {n:'right', c:x===1?COLORS.right:null}, {n:'left', c:x===-1?COLORS.left:null}, {n:'top', c:y===-1?COLORS.top:null}, {n:'bottom',c:y===1?COLORS.bottom:null}, ]; fc.forEach(f=>{ const d=document.createElement('div'); d.className='face '+f.n; if(f.c){d.style.backgroundColor=f.c;d.classList.add('face-outer')} else{d.style.backgroundColor=COLORS.inner} el.appendChild(d); }); cb.el=el;container.appendChild(el); setTrans(cb); cubies.push(cb); } } function curPos(cb){ const p=mat3Vec(cb.m,cb.op); return{x:Math.round(p.x),y:Math.round(p.y),z:Math.round(p.z)}; } function transStr(cb){ return mat3Css(cb.m)+` translate3d(${cb.op.x*SP}px,${cb.op.y*SP}px,${cb.op.z*SP}px)`; } function setTrans(cb){cb.el.style.transform=transStr(cb)} /* ========== Move Animation ========== */ async function doMove(name,dur=480){ const d=MOVES[name],{axis,layer,angle}=d; const axU=axis.toUpperCase(); const aff=cubies.filter(c=>curPos(c)[axis]===layer); aff.forEach(c=>{c._b=transStr(c)}); const t0=performance.now(); await new Promise(res=>{ function tick(now){ const p=Math.min((now-t0)/dur,1),e=easeIO(p),a=angle*e; aff.forEach(c=>{c.el.style.transform=`rotate${axU}(${a}deg) ${c._b}`}); if(p<1)requestAnimationFrame(tick); else{ const rm=rotMat(axis,angle); aff.forEach(c=>{c.m=roundMat(mat3Mul(rm,c.m));setTrans(c)}); res(); } } requestAnimationFrame(tick); }); } /* ========== Scramble & Solve ========== */ let hist=[]; async function scramble(n=22){ hist=[];let last=''; for(let i=0;i<n;i++){ let mv,att=0; do{mv=MKEYS[Math.floor(Math.random()*MKEYS.length)];att++} while((mv===last||mv===inv(last))&&att<30); hist.push(mv);last=mv; await doMove(mv,420); } } async function solve(){ const rev=[...hist].reverse().map(inv); for(const mv of rev)await doMove(mv,420); hist=[]; } function delay(ms){return new Promise(r=>setTimeout(r,ms))} /* ========== Mouse / Touch Drag ========== */ let rx=-28,ry=38,drag=false,lx,ly; const scene=document.getElementById('scene'); function updCont(){container.style.transform=`rotateX(${rx}deg) rotateY(${ry}deg)`} scene.addEventListener('mousedown',e=>{drag=true;lx=e.clientX;ly=e.clientY}); window.addEventListener('mousemove',e=>{ if(!drag)return; ry+=(e.clientX-lx)*0.45;rx-=(e.clientY-ly)*0.45; rx=Math.max(-89,Math.min(89,rx));lx=e.clientX;ly=e.clientY;updCont(); }); window.addEventListener('mouseup',()=>{drag=false}); scene.addEventListener('touchstart',e=>{drag=true;lx=e.touches[0].clientX;ly=e.touches[0].clientY},{passive:true}); window.addEventListener('touchmove',e=>{ if(!drag)return;e.preventDefault(); const t=e.touches[0]; ry+=(t.clientX-lx)*0.45;rx-=(t.clientY-ly)*0.45; rx=Math.max(-89,Math.min(89,rx));lx=t.clientX;ly=t.clientY;updCont(); },{passive:false}); window.addEventListener('touchend',()=>{drag=false}); /* ========== Idle Auto-Rotation ========== */ let idle=true; function idleTick(){ if(!idle)return; ry+=0.1;updCont();requestAnimationFrame(idleTick); } /* ========== Status & Button ========== */ const statusEl=document.getElementById('status'); const btn=document.getElementById('start-btn'); let started=false; btn.addEventListener('click',()=>{ if(started)return;started=true;idle=false; btn.disabled=true; runLoop(); }); async function runLoop(){ while(true){ statusEl.textContent='SCRAMBLING';statusEl.style.color='rgba(233,69,96,0.7)'; statusEl.classList.add('active'); await scramble(22); statusEl.textContent='ANALYZING';statusEl.style.color='rgba(0,155,72,0.6)'; await delay(1400); statusEl.textContent='SOLVING';statusEl.style.color='rgba(0,200,83,0.7)'; await solve(); statusEl.textContent='SOLVED';statusEl.style.color='rgba(255,213,0,0.75)'; statusEl.classList.remove('active'); await delay(2800); statusEl.classList.add('active'); } } /* ========== Initialize ========== */ buildCube(); updCont(); idleTick(); </script> </body> </html> 
submitted by /u/Soft-Wedding4595
[link] [comments]