jupiter-vector-moons.js

total 0
used 0
limit 0
/* title: Jupiter Vector Planet categories: 3d, astronomy, animation files: head point pointlist stage --- Hollow Jupiter with vector winds, a particle Great Red Spot, and four orbiting moons. */ let seed=41821; function rnd(){seed=(Math.imul(seed,1664525)+1013904223)|0;return (seed>>>0)/4294967296;} class MainStage extends Stage { canvas='playspace' mounted(){ this.t=0;this.pitch=.30;this.yaw=0;this.zoom=1;this.dx=0;this.dy=0; this.spot=Array.from({length:650},()=>({r:Math.sqrt(rnd()),a:rnd()*6.283,s:.004+rnd()*.003})); this.moons=[ {name:'Io',r:1.55,s:.011,a:.3,c:'#efc98a',size:2.3}, {name:'Europa',r:2.1,s:.007,a:1.7,c:'#e2ddc8',size:2.1}, {name:'Ganymede',r:2.75,s:.0045,a:3.2,c:'#bcb5a5',size:3.1}, {name:'Callisto',r:3.55,s:.0025,a:5.0,c:'#918579',size:2.8} ]; this.minors=Array.from({length:28},(_,i)=>({r:2.8+rnd()*1.4,a:rnd()*6.283,s:(.0008+rnd()*.0017)*(i%3===0?-1:1),incl:(rnd()-.5)*2.7,node:rnd()*6.283})); const el=document.getElementById('playspace'); if(el){ el.style.touchAction='none';let prev=null; el.addEventListener('pointerdown',e=>{prev={x:e.clientX,y:e.clientY,id:e.pointerId};el.setPointerCapture(e.pointerId);}); el.addEventListener('pointermove',e=>{if(!prev||prev.id!==e.pointerId)return;this.yaw+=(e.clientX-prev.x)*.008;this.pitch=Math.max(-1.55,Math.min(1.55,this.pitch+(e.clientY-prev.y)*.008));prev.x=e.clientX;prev.y=e.clientY;}); const end=e=>{if(prev&&prev.id===e.pointerId)prev=null;}; el.addEventListener('pointerup',end);el.addEventListener('pointercancel',end); el.addEventListener('wheel',e=>{e.preventDefault();this.zoom=Math.max(.4,Math.min(2.7,this.zoom*Math.exp(-e.deltaY*.001)));},{passive:false}); } } draw(ctx){ this.clear(ctx);this.t++; const w=ctx.canvas.width,h=ctx.canvas.height,cx=w/2+this.dx,cy=h*.49+this.dy,R=Math.min(w*.125,h*.17)*this.zoom; const cp=Math.cos(this.pitch),sp=Math.sin(this.pitch),cyaw=Math.cos(this.yaw),syaw=Math.sin(this.yaw); const project=(x,y,z)=>{ const xx=x*cyaw+z*syaw,zz=-x*syaw+z*cyaw; return {x:cx+xx*R,y:cy-(y*cp-zz*sp)*R,z:y*sp+zz*cp}; }; const globe=(lat,lon)=>{ const c=Math.cos(lat),a=lon+this.t*.0007; return project(c*Math.sin(a),Math.sin(lat),c*Math.cos(a)); }; ctx.save(); for(const m of this.moons){ ctx.strokeStyle='rgba(169,180,190,.11)';ctx.lineWidth=.6;ctx.beginPath(); for(let j=0;j<=160;j++){const a=j*Math.PI*2/160,p=project(m.r*Math.cos(a),0,m.r*Math.sin(a));if(j===0)ctx.moveTo(p.x,p.y);else ctx.lineTo(p.x,p.y);} ctx.stroke(); } const moon=(m,front)=>{const a=m.a+this.t*m.s,p=project(m.r*Math.cos(a),0,m.r*Math.sin(a));if((p.z>=0)!==front)return;if(!front&&(p.x-cx)**2+(p.y-cy)**2{for(const m of this.minors){ const a=m.a+this.t*m.s,x=m.r*Math.cos(a),z=m.r*Math.sin(a),c=Math.cos(m.incl),n=m.node; const p=project(x*Math.cos(n)-z*c*Math.sin(n),z*Math.sin(m.incl),x*Math.sin(n)+z*c*Math.cos(n)); if((p.z>=0)!==front)continue; if(!front&&(p.x-cx)**2+(p.y-cy)**2moon(m,false)); ctx.globalAlpha=1;ctx.strokeStyle='rgba(220,193,166,.8)';ctx.lineWidth=1;ctx.beginPath();ctx.arc(cx,cy,R,0,6.283);ctx.stroke(); for(let k=-9;k<=9;k++){ const lat=k*.126;ctx.strokeStyle=k%3===0?'rgba(211,149,113,.57)':'rgba(232,204,168,.33)';ctx.lineWidth=.8;ctx.beginPath();let on=false; for(let j=0;j<=220;j++){ const lon=-Math.PI+j*Math.PI/110,p=globe(lat+.012*Math.sin(7*lon+k+this.t*.004),lon); if(p.z<0){on=false;continue;} if(!on){ctx.moveTo(p.x,p.y);on=true;}else ctx.lineTo(p.x,p.y); }ctx.stroke(); } for(const q of this.spot){ const a=q.a+this.t*q.s*(1.2-q.r),p=globe(-.35+.16*q.r*Math.sin(a),-.57+.28*q.r*Math.cos(a)); if(p.z<0)continue; ctx.globalAlpha=.3+.6*p.z;ctx.fillStyle=q.r<.55?'#e3a087':'#b95c4b'; ctx.beginPath();ctx.arc(p.x,p.y,Math.max(.5,R/175),0,6.283);ctx.fill(); } tiny(true);this.moons.forEach(m=>moon(m,true)); ctx.globalAlpha=1;ctx.fillStyle='#d8bfaa';ctx.font='12px sans-serif';ctx.textAlign='center';ctx.fillText('JUPITER • FOUR GALILEAN MOONS',cx,Math.min(h-12,cy+R*1.5));ctx.restore(); } } ;stage=MainStage.go();
Run
Meta Data
title Jupiter Vector Planet
imports ()
files ('head', 'point', 'pointlist', 'stage')
unused_keys ()
unknown_keys ('categories',)
categories ['3d, astronomy, animation']
filepath_exists True
path jupiter-vector-moons.js
filepath jupiter-vector-moons.js
clean_files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/compass.js', '../point_src/center.js', '../point_src/point-content.js', '../point_src/pointdraw.js', '../point_src/relative-xy.js', '../point_src/pointcast.js', '../point_src/point.js', '../point_src/pointlistdraw.js', '../point_src/pointlistgradient.js', '../point_src/pointlistshape.js', '../point_src/pointlistgenerator.js', '../point_src/unpack.js', '../point_src/pointlist.js', '../point_src/pointlistpen.js', '../point_src/stage-hooks.js', '../point_src/stage-resize.js', '../point_src/functions/resolve.js', '../point_src/stage.js')
markdown {'html': '<p>Hollow Jupiter with vector winds, a particle Great Red Spot, and four orbiting moons.</p>', 'content': 'title: Jupiter Vector Planet\ncategories: 3d, astronomy, animation\nfiles:\n head\n point\n pointlist\n stage\n---\nHollow Jupiter with vector winds, a particle Great Red Spot, and four orbiting moons.'}