diff --git a/sphere/index.html b/sphere/index.html index 2dc517c..2ecd366 100644 --- a/sphere/index.html +++ b/sphere/index.html @@ -98,7 +98,7 @@ function toPlane([x,y]){return new THREE.Vector3(x*lift,-1.001,y*lift)} const W=()=>innerWidth,H=()=>innerHeight; const renderer=new THREE.WebGLRenderer({antialias:true,alpha:false}); -renderer.setPixelRatio(Math.min(devicePixelRatio,2));renderer.setClearColor(new THREE.Color(css('--bg'))); +renderer.setPixelRatio(Math.min(devicePixelRatio,1.5));renderer.setClearColor(new THREE.Color(css('--bg'))); document.getElementById('stage').appendChild(renderer.domElement); const scene=new THREE.Scene(); const cam=new THREE.PerspectiveCamera(40,1,0.01,100);cam.position.set(2.6,-2.4,3.2); @@ -117,8 +117,11 @@ const invP=([x,y])=>{const r=x*x+y*y;return r<1e-12?[1e6,0]:[x/r,y/r]}; const trisDense=T.map(([lx,by,ay,rx,ty])=>{const A=P(lx,by),B=P(150,ay),Cc=P(rx,by);return{up:!!ty,pts:[...seg(A,B,600),...seg(B,Cc,600).slice(1),...seg(Cc,A,600).slice(1)]}}); const bindu2=new THREE.Mesh(new THREE.SphereGeometry(.022,16,12),new THREE.MeshBasicMaterial({color:C.bindu}));scene.add(bindu2); -function build(){ - group.clear();planeG.clear(); +const drop=g=>{g.traverse(o=>{if(o.geometry)o.geometry.dispose();if(o.material)o.material.dispose()});g.clear()}; +let pending=false; +function build(){if(pending)return;pending=true;requestAnimationFrame(()=>{pending=false;rebuild()})} +function rebuild(){ + drop(group);drop(planeG); const mk=(pts,col,op,g,f)=>g.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts.map(f)),new THREE.LineBasicMaterial({color:col,transparent:op<1,opacity:op}))); tris.forEach(t=>mk(t.pts,t.up?C.up:C.down,1,group,toSphere)); decor.forEach(d=>mk(d,C.fg,.45,group,toSphere)); @@ -142,7 +145,7 @@ function resize(){renderer.setSize(W(),H());cam.aspect=W()/H();cam.updateProject addEventListener('resize',resize);resize();build(); const reduce=matchMedia('(prefers-reduced-motion: reduce)').matches; if(reduce){ctl.autoRotate=false;document.getElementById('t-spin').setAttribute('aria-pressed','false')} -(function loop(){requestAnimationFrame(loop);ctl.update();renderer.render(scene,cam)})(); +(function loop(){requestAnimationFrame(loop);if(document.hidden)return;ctl.update();renderer.render(scene,cam)})(); const $=id=>document.getElementById(id); function setMode(m){mode=m;$('m-stereo').setAttribute('aria-pressed',m==='stereo');$('m-gnomo').setAttribute('aria-pressed',m==='gnomo');build()}