Model profile
Claude Haiku
24/24answered (R6–R30)
0DNF / pending
7.18avg. score · 14 scored rounds (R6–R30)
Low participation: this average is drawn from only 14 of 24 rounds (58%). Not directly comparable to models with fuller participation.
Rounds & answers 24
▶ R6 · Extraction → JSON Open round →
{"name":"AquaPur X2 Trinkbrunnen","brand":"PetFlow","price_eur":29.99,"weight_g":800,"features":["Dreifach-Filter","2-Watt-Pumpsystem","spuelmaschinenfester Edelstahlaufsatz"],"in_stock":false}▶ R7 · Sentiment classification Open round →
[{"id":1,"sentiment":"positive"},{"id":2,"sentiment":"negative"},{"id":3,"sentiment":"neutral"},{"id":4,"sentiment":"negative"},{"id":5,"sentiment":"positive"},{"id":6,"sentiment":"neutral"},{"id":7,"sentiment":"neutral"},{"id":8,"sentiment":"negative"},{"id":9,"sentiment":"positive"},{"id":10,"sentiment":"neutral"}]▶ R8 · Translation DE↔EN Open round →
That's old hat — those who lag behind lose out. We've pulled the wagon out of the mud, but we can't rush ahead now. --- Im Essen zeigt sich die Wahrheit: Unser knappes Budget zwar zu Kompromissen, aber der Start gelang reibungslos.
▶ R9 · One-liner code Open round →
1. ^\d{4}-(0[1-9]|1[0-2])-([0-2]\d|3[01])$
2. SELECT customer_id, SUM(amount) AS total FROM orders GROUP BY customer_id ORDER BY total DESC LIMIT 5;
3. .items[].id
4. nav a[href^="http"], nav a[href^="https"]
5. cut -d' ' -f1 access.log | sort -u | wc -l▶ R10 · Facts quiz Open round →
1. Canberra 2. 1989 3. W 4. I'm a teapot 5. Franz Kafka 6. Jupiter 7. 101010 8. 443 9. Linus Torvalds 10. 97
▶ R11 · Micro-copy & slogans Open round →
1. Frisches Wasser, glückliche Katzen, täglich. 2. Handgebacken, täglich frisch, vom Herzen. 3. Die beste KI finden, einfach vergleichen. 4. Stille finden, Musik genießen, Welt ausblenden. 5. Ein Passwort, alle Ihre Konten sicher.
▶ R13 · Image prompts Open round →
1. Luxury smartwatch on mahogany desk with morning sunlight, professional product photography 2. Wireless earbuds in minimalist white room, soft shadows, clean aesthetic 3. Running sneakers on wet pavement at sunrise, motion blur background, urban style
▶ R14 · Product names Open round →
1. HydroMind — Stay hydrated, stay focused 2. AquaRemind — Never forget to drink water 3. FluidTrack — Your personal hydration assistant today 4. WaterBuddy — Drink smart, live healthier always 5. AquaPulse — Hydration at your fingertips always
▶ R15 · CSS spinner Open round →
```html
<div class="spinner"></div>
<style>
.spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
```▶ R16 · Explain it to a child (German) Open round →
Ein Akku ist wie eine unsichtbare Pumpe, die Strom speichert, genau wie ein Wassertank Wasser speichert. Wenn du dein Handy ladest, wird der Akku mit elektrischer Energie gefüllt. Beim Benutzen des Handys gibt der Akku diese Energie ab, wie Wasser aus einem Wasserhahn fließt. Wenn der Akku leer ist, musst du ihn wieder aufladen, sonst funktioniert dein Handy nicht mehr.
▶ R17 · Logic riddle★ 6.5/10 Open round →
Ich ziehe aus der Kiste mit dem Etikett "Gemischt". Da alle Etiketten falsch sind, ist diese Kiste entweder "Äpfel" oder "Birnen" — abhängig von der gezogenen Frucht. Die Kiste, deren Etikett der tatsächlichen Frucht entspricht, trägt jetzt das korrekte Label. Die verbleibenden zwei Kisten erhalten die zwei restlichen Etiketten, wobei die mit "Äpfel"-Etikett "Birnen" und die mit "Birnen"-Etikett "Gemischt" sein muss.
📝 Mapping only holds for the apple case; case analysis missing, middle section muddled
▶ R18 · German registers & tone★ 8.5/10 Open round →
1. Leider müssen wir Sie informieren, dass wir den vereinbarten Liefertermin nicht einhalten können. 2. Der Liefertermin kann nicht erreicht werden. 3. Hey, das wird eng – wir schaffen den Termin leider nicht.
▶ R19 · Table QA★ 10/10 Open round →
1. VitaSip 2. 830 3. PureFlow 4. 19,51 5. 3
▶ R20 · JSON repair★ 10/10 Open round →
{"name": "Trinkflasche Pro", "price": 29.90, "tags": ["outdoor", "sport"], "stock": {"berlin": 12, "muenchen": 7, "hamburg": null}, "active": true}▶ R21 · Sorting race bubble/insertion/selectionOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<title>Sorting Race</title>
<style>
body { display: flex; gap: 20px; padding: 20px; background: #222; margin: 0; }
canvas { border: 1px solid #666; background: #111; }
.panel { text-align: center; }
.label { color: #fff; margin-bottom: 10px; font-weight: bold; }
.status { color: #fff; height: 20px; margin-top: 5px; }
.done { color: #0f0; }
</style>
</head>
<body>
<div class="panel"><div class="label">Bubble Sort</div><canvas id="c1" width="250" height="300"></canvas><div id="s1" class="status"></div></div>
<div class="panel"><div class="label">Insertion Sort</div><canvas id="c2" width="250" height="300"></canvas><div id="s2" class="status"></div></div>
<div class="panel"><div class="label">Selection Sort</div><canvas id="c3" width="250" height="300"></canvas><div id="s3" class="status"></div></div>
<script>
const data = Array.from({length: 40}, (_, i) => i + 1).sort(() => Math.random() - 0.5);
function draw(canvas, arr, h) {
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#111';
ctx.fillRect(0, 0, canvas.width, canvas.height);
const w = canvas.width / arr.length;
const mh = Math.max(...arr);
for (let i = 0; i < arr.length; i++) {
ctx.fillStyle = h.includes(i) ? '#f00' : '#0f0';
const barH = (arr[i] / mh) * (canvas.height - 20);
ctx.fillRect(i * w, canvas.height - barH, w - 1, barH);
}
}
function* bubbleSort(arr) {
const a = [...arr];
for (let i = 0; i < a.length; i++) {
for (let j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) [a[j], a[j + 1]] = [a[j + 1], a[j]];
yield [a, [j, j + 1]];
}
}
yield [a, []];
}
function* insertionSort(arr) {
const a = [...arr];
for (let i = 1; i < a.length; i++) {
let k = i;
while (k > 0 && a[k - 1] > a[k]) {
[a[k - 1], a[k]] = [a[k], a[k - 1]];
k--;
yield [a, [k, i]];
}
}
yield [a, []];
}
function* selectionSort(arr) {
const a = [...arr];
for (let i = 0; i < a.length; i++) {
let m = i;
for (let j = i + 1; j < a.length; j++) {
if (a[j] < a[m]) m = j;
yield [a, [i, m]];
}
[a[i], a[m]] = [a[m], a[i]];
}
yield [a, []];
}
const gen = [bubbleSort(data), insertionSort(data), selectionSort(data)];
const done = [false, false, false];
const canv = [document.getElementById('c1'), document.getElementById('c2'), document.getElementById('c3')];
const status = [document.getElementById('s1'), document.getElementById('s2'), document.getElementById('s3')];
const arrays = [data.slice(), data.slice(), data.slice()];
function frame() {
for (let i = 0; i < 3; i++) {
if (!done[i]) {
const r = gen[i].next();
if (!r.done) {
arrays[i] = r.value[0];
draw(canv[i], arrays[i], r.value[1]);
} else {
done[i] = true;
draw(canv[i], arrays[i], []);
status[i].textContent = 'DONE';
status[i].classList.add('done');
}
}
}
if (!done.every(x => x)) requestAnimationFrame(frame);
}
frame();
</script>
</body>
</html>▶ R22 · Hexagon ballsOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Hexagon</title><style>body{margin:0;background:#000}</style></head><body><canvas id="c"></canvas><script>
const c=document.getElementById('c'),x=c.getContext('2d'),W=800,H=600,cx=W/2,cy=H/2,R=150;
const balls=Array(8).fill().map(()=>({x:cx+Math.random()*50-25,y:cy+Math.random()*50-25,vx:(Math.random()-0.5)*4,vy:(Math.random()-0.5)*4,r:8}));
c.width=W;c.height=H;let a=0;
function hex(rot){const v=[];for(let i=0;i<6;i++){const t=rot+i*Math.PI/3;v.push({x:cx+R*Math.cos(t),y:cy+R*Math.sin(t)});}return v;}
function segPt(p1,p2,b){const dx=p2.x-p1.x,dy=p2.y-p1.y,L=Math.hypot(dx,dy),u=Math.max(0,Math.min(1,((b.x-p1.x)*dx+(b.y-p1.y)*dy)/(L*L))),px=p1.x+u*dx,py=p1.y+u*dy,d=Math.hypot(b.x-px,b.y-py);return{px,py,d,nx:-dy/L,ny:dx/L};}
function loop(){a+=0.01;const v=hex(a);balls.forEach(b=>{b.vy+=0.3;b.x+=b.vx;b.y+=b.vy;b.vx*=0.98;b.vy*=0.98;
for(let i=0;i<6;i++){const s=segPt(v[i],v[(i+1)%6],b);if(s.d<b.r){const pen=b.r-s.d+0.01;b.x+=s.nx*pen;b.y+=s.ny*pen;const vn=b.vx*s.nx+b.vy*s.ny;b.vx=(b.vx-vn*s.nx)*0.95-vn*s.nx;b.vy=(b.vy-vn*s.ny)*0.95-vn*s.ny;}}});
for(let i=0;i<8;i++)for(let j=i+1;j<8;j++){const b1=balls[i],b2=balls[j],dx=b2.x-b1.x,dy=b2.y-b1.y,d=Math.hypot(dx,dy);if(d<16&&d>0.5){const nx=dx/d,ny=dy/d,overlap=(16-d)/2;b1.x-=nx*overlap;b1.y-=ny*overlap;b2.x+=nx*overlap;b2.y+=ny*overlap;const dvx=b2.vx-b1.vx,dvy=b2.vy-b1.vy,dvn=dvx*nx+dvy*ny;if(dvn>0){b1.vx+=dvn*nx*0.95;b1.vy+=dvn*ny*0.95;b2.vx-=dvn*nx*0.95;b2.vy-=dvn*ny*0.95;}}}
x.fillStyle='#000';x.fillRect(0,0,W,H);x.strokeStyle='#0f0';x.lineWidth=2;x.beginPath();x.moveTo(v[0].x,v[0].y);for(let i=1;i<6;i++)x.lineTo(v[i].x,v[i].y);x.closePath();x.stroke();x.fillStyle='#f00';balls.forEach(b=>{x.beginPath();x.arc(b.x,b.y,b.r,0,2*Math.PI);x.fill();});requestAnimationFrame(loop);}loop();
</script></body></html>▶ R23 · Pendulum waveOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Pendulum</title><style>body{margin:0;background:#000}</style></head><body><canvas id="c"></canvas><script>
const c=document.getElementById('c'),x=c.getContext('2d'),W=900,H=500;
c.width=W;c.height=H;const n=15,g=980;
const pends=Array(n).fill().map((_, i)=>{const L=50+i*8;return{L,amp:0.5,T:2*Math.PI*Math.sqrt(L/g),cx:W/(n+1)*(i+1),cy:80};});
let t=0;function loop(){t+=0.016;x.fillStyle='#000';x.fillRect(0,0,W,H);
for(let i=0;i<n;i++){const p=pends[i],th=p.amp*Math.sin(2*Math.PI*t/p.T),bx=p.cx+p.L*Math.sin(th),by=p.cy+p.L*Math.cos(th);
x.strokeStyle='#08f';x.lineWidth=1.5;x.beginPath();x.moveTo(p.cx,p.cy);x.lineTo(bx,by);x.stroke();
x.fillStyle='#0ff';x.beginPath();x.arc(bx,by,4,0,2*Math.PI);x.fill();}requestAnimationFrame(loop);}loop();
</script></body></html>▶ R24 · Maze race BFS/DFS/A*STAT★ 3.5/10 Open round →
📝 broken layout: panels overlap/are cut off, no recognizable maze, path not highlighted (3.5)
Show code
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Pathfinding</title><style>body{margin:0;background:#000}</style></head><body><canvas id="c"></canvas><script>
const c=document.getElementById('c'),x=c.getContext('2d'),W=1200,H=400,S=25,CW=H/S;
c.width=W;c.height=H;const maze=Array(S).fill().map(()=>Array(S).fill(0));
for(let i=0;i<S;i++)for(let j=0;j<S;j++)if(i===0||j===0||i===S-1||j===S-1||Math.random()<0.2)maze[i][j]=1;maze[0][0]=1;maze[S-1][S-1]=1;
function search(algo){const vis=new Set(),Q=[[0,0]],steps=[];let found=false;
while(Q.length&&!found){const curr=(algo==='astar')?Q.sort((a,b)=>Math.abs(a[0]-(S-1))+Math.abs(a[1]-(S-1))-Math.abs(b[0]-(S-1))-Math.abs(b[1]-(S-1)))[0]:algo==='dfs'?Q.pop():Q.shift();
const k=`${curr[0]},${curr[1]}`;if(vis.has(k))continue;vis.add(k);steps.push([...curr]);if(curr[0]===S-1&&curr[1]===S-1){found=true;break;}
for(const[di,dj]of[[0,1],[1,0],[0,-1],[-1,0]]){const ni=curr[0]+di,nj=curr[1]+dj,nk=`${ni},${nj}`;if(ni>=0&&ni<S&&nj>=0&&nj<S&&maze[ni][nj]&&!vis.has(nk))Q.push([ni,nj]);}}return steps;}
const bfs=search('bfs'),dfs=search('dfs'),astar=search('astar'),maxSteps=Math.max(bfs.length,dfs.length,astar.length);
let frame=0;function draw(){x.fillStyle='#000';x.fillRect(0,0,W,H);
const algos=[{name:'BFS',steps:bfs,ox:0},{name:'DFS',steps:dfs,ox:400},{name:'A*',steps:astar,ox:800}];
for(const a of algos){x.fillStyle='#222';x.fillRect(a.ox,0,400,H);for(let i=0;i<S;i++)for(let j=0;j<S;j++){if(maze[i][j]){x.fillStyle='#444';x.fillRect(a.ox+j*CW,i*CW,CW-1,CW-1);}}
for(let i=0;i<Math.min(frame,a.steps.length);i++){const[si,sj]=a.steps[i];x.fillStyle=i===a.steps.length-1?'#f00':'#0f0';x.fillRect(a.ox+sj*CW,si*CW,CW-1,CW-1);}
if(frame>=a.steps.length){x.fillStyle='#0f0';x.font='bold 16px Arial';x.fillText('DONE',a.ox+10,30);}}frame++;if(frame<=maxSteps+30)requestAnimationFrame(draw);}draw();
</script></body></html>▶ R25 · Sorting race quick/merge/heapERRBLANK★ 1/10 Open round →
Show code
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Sorting</title><style>body{margin:0;background:#000}</style></head><body><canvas id="c"></canvas><script>
const c=document.getElementById('c'),x=c.getContext('2d'),W=1200,H=400;
c.width=W;c.height=H;const arr=Array(60).fill().map((_,i)=>i+1).sort(()=>Math.random()-0.5),n=60;
function recordSort(cmp,swap){const a=[...arr],moves=[];
function doSwap(i,j){const t=a[i];a[i]=a[j];a[j]=t;moves.push([i,j]);}function doSet(i,v){a[i]=v;moves.push([i,-1]);}
const f=(cmp===1)?function qs(l,r){if(l>=r)return;const p=a[r],i=l-1;for(let j=l;j<r;j++)if(a[j]<p){doSwap(++i,j);}doSwap(i+1,r);qs(l,i);qs(i+2,r);}:(cmp===2)?function ms(l,r){if(l>=r)return;const m=Math.floor((l+r)/2);ms(l,m);ms(m+1,r);let i=l,j=m+1,k=0,b=[];while(i<=m&&j<=r)b[k++]=a[i]<a[j]?a[i++]:a[j++];while(i<=m)b[k++]=a[i++];while(j<=r)b[k++]=a[j++];for(let p=0;p<k;p++)doSet(l+p,b[p]);}:function hs(n){const h=(i)=>2*i+1;function heapify(i,len){let l=i;const left=h(i),right=h(i)+1;if(left<len&&a[left]>a[l])l=left;if(right<len&&a[right]>a[l])l=right;if(l!==i){doSwap(i,l);heapify(l,len);}}
for(let i=Math.floor(n/2)-1;i>=0;i--)heapify(i,n);for(let i=n-1;i>0;i--){doSwap(0,i);heapify(0,i);}};
f(0,n-1);return moves;}
const qmoves=recordSort(1),mmoves=recordSort(2),hmoves=recordSort(3),maxMoves=Math.max(qmoves.length,mmoves.length,hmoves.length);
let frame=0;function draw(){x.fillStyle='#000';x.fillRect(0,0,W,H);
const algos=[{name:'Quicksort',moves:qmoves,ox:0},{name:'Mergesort',moves:mmoves,ox:400},{name:'Heapsort',moves:hmoves,ox:800}];
for(const algo of algos){x.fillStyle='#222';x.fillRect(algo.ox,0,400,H);const a=[...arr];
for(let i=0;i<Math.min(frame,algo.moves.length);i++){const[i,j]=algo.moves[i];if(j>=0){const t=a[i];a[i]=a[j];a[j]=t;}}
const bw=400/n;for(let i=0;i<n;i++){const h=H*(a[i]/n);x.fillStyle=frame<algo.moves.length?'#08f':'#0f0';x.fillRect(algo.ox+i*bw,H-h,bw-1,h);}
if(frame>=algo.moves.length){x.fillStyle='#0f0';x.font='bold 16px Arial';x.fillText('DONE',algo.ox+10,30);}}frame++;if(frame<=maxMoves+50)requestAnimationFrame(draw);}draw();
</script></body></html>▶ R26 · Projectile ballisticsOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Projectile Motion</title>
<style>
body { margin: 0; overflow: hidden; background: #1a1a1a; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
canvas.width = 1200;
canvas.height = 600;
const g = 0.5;
const v0 = 15;
const angles = [20, 35, 50, 65, 75];
let balls = [];
let time = 0;
let allLanded = false;
function init() {
balls = angles.map(angle => {
const rad = angle * Math.PI / 180;
return {
x: 50,
y: 550,
vx: v0 * Math.cos(rad),
vy: -v0 * Math.sin(rad),
trail: [],
color: `hsl(${angle * 3}, 100%, 60%)`,
landed: false
};
});
time = 0;
allLanded = false;
}
function update() {
allLanded = true;
balls.forEach(ball => {
if (!ball.landed) {
ball.vy += g;
ball.x += ball.vx;
ball.y += ball.vy;
ball.trail.push({x: ball.x, y: ball.y});
if (ball.trail.length > 50) ball.trail.shift();
if (ball.y >= 550) {
ball.y = 550;
ball.landed = true;
} else {
allLanded = false;
}
}
});
if (allLanded && time > 60) init();
time++;
}
function draw() {
ctx.fillStyle = '#1a1a1a';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#666';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(0, 550);
ctx.lineTo(1200, 550);
ctx.stroke();
for (let i = 0; i <= 12; i++) {
const x = i * 100;
ctx.strokeStyle = '#444';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(x, 545);
ctx.lineTo(x, 555);
ctx.stroke();
ctx.fillStyle = '#888';
ctx.font = '12px monospace';
ctx.fillText(i * 100, x - 15, 575);
}
balls.forEach(ball => {
ctx.strokeStyle = ball.color;
ctx.globalAlpha = 0.3;
ctx.lineWidth = 2;
ctx.beginPath();
ball.trail.forEach((p, i) => {
if (i === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
});
ctx.stroke();
ctx.globalAlpha = 1;
ctx.fillStyle = ball.color;
ctx.beginPath();
ctx.arc(ball.x, ball.y, 5, 0, Math.PI * 2);
ctx.fill();
});
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
init();
loop();
</script>
</body>
</html>▶ R27 · Double-pendulum chaosOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Double Pendulum Chaos</title>
<style>
body { margin: 0; overflow: hidden; background: #000; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 800;
const g = 9.81;
const L1 = 150, L2 = 150;
const m1 = 1, m2 = 1;
let p1 = {th1: Math.PI/4, th2: Math.PI/3, w1: 0, w2: 0, trail: [], col: '#ff6b6b'};
let p2 = {th1: Math.PI/4 + 0.001, th2: Math.PI/3, w1: 0, w2: 0, trail: [], col: '#4ecdc4'};
function step(p, dt) {
const s = Math.sin(p.th1 - p.th2);
const c = Math.cos(p.th1 - p.th2);
const a1 = (m2*L2*p.w2*p.w2*s*c + (m1+m2)*g*Math.sin(p.th2)*L2 - (m1+m2)*L1*p.w1*p.w1*s) / ((m1+m2)*L1 - m2*L2*c*c);
const a2 = (-m2*L2*a1*c - (m1+m2)*g*Math.sin(p.th1) + (m1+m2)*L1*p.w1*p.w1*s) / ((m1+m2)*L2 - m2*L1*c*c);
p.w1 += a1 * dt;
p.w2 += a2 * dt;
p.th1 += p.w1 * dt;
p.th2 += p.w2 * dt;
}
function getPendulumTips(p) {
const cx = canvas.width / 2, cy = 100;
const x1 = cx + L1 * Math.sin(p.th1);
const y1 = cy + L1 * Math.cos(p.th1);
const x2 = x1 + L2 * Math.sin(p.th2);
const y2 = y1 + L2 * Math.cos(p.th2);
return {x1, y1, x2, y2};
}
function draw() {
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
[p1, p2].forEach(p => {
const {x1, y1, x2, y2} = getPendulumTips(p);
const cx = canvas.width / 2, cy = 100;
ctx.strokeStyle = p.col;
ctx.globalAlpha = 0.2;
ctx.lineWidth = 1;
ctx.beginPath();
p.trail.forEach((pt, i) => {
if (i === 0) ctx.moveTo(pt.x, pt.y);
else ctx.lineTo(pt.x, pt.y);
});
ctx.stroke();
ctx.globalAlpha = 1;
ctx.strokeStyle = p.col;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.fillStyle = p.col;
ctx.beginPath();
ctx.arc(x2, y2, 4, 0, Math.PI*2);
ctx.fill();
p.trail.push({x: x2, y: y2});
if (p.trail.length > 200) p.trail.shift();
});
}
function loop() {
step(p1, 0.01);
step(p2, 0.01);
draw();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>▶ R28 · Particle fountainOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Particle Fountain</title>
<style>
body { margin: 0; overflow: hidden; background: #1a1a1a; font-family: monospace; }
canvas { display: block; }
#wind { position: absolute; top: 10px; left: 10px; color: #aaa; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<div id="wind">Wind: <input type="range" id="windSlider" min="-5" max="5" value="0" step="0.1"> <span id="windVal">0</span></div>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 600;
let particles = [];
const g = 0.2;
let wind = 0;
const windSlider = document.getElementById('windSlider');
const windVal = document.getElementById('windVal');
windSlider.addEventListener('input', (e) => {
wind = parseFloat(e.target.value);
windVal.textContent = wind.toFixed(1);
});
function emit() {
for (let i = 0; i < 15; i++) {
particles.push({
x: canvas.width / 2 + (Math.random() - 0.5) * 20,
y: canvas.height - 10,
vx: (Math.random() - 0.5) * 4,
vy: -Math.random() * 8 - 2,
life: 1.0,
r: Math.random() * 4 + 2
});
}
}
function update() {
particles = particles.filter(p => {
p.vy += g;
p.vx += wind * 0.02;
p.x += p.vx;
p.y += p.vy;
p.life -= 0.008;
if (p.y >= canvas.height - 10) {
p.vy *= -0.6;
p.y = canvas.height - 10;
p.life -= 0.02;
}
return p.life > 0;
});
if (Math.random() < 0.8) emit();
}
function draw() {
ctx.fillStyle = '#1a1a1a';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#444';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(0, canvas.height - 10);
ctx.lineTo(canvas.width, canvas.height - 10);
ctx.stroke();
particles.forEach(p => {
ctx.fillStyle = `rgba(100, 200, 255, ${p.life})`;
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
ctx.fill();
});
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
emit();
loop();
</script>
</body>
</html>▶ R29 · Orbital mechanicsOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Orbital Mechanics</title>
<style>
body { margin: 0; overflow: hidden; background: #000; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
canvas.width = 1200;
canvas.height = 900;
const G = 1;
const M = 10000;
const bodies = [
{x: 600, y: 450, vx: 0, vy: 0, r: 8, col: '#ffcc00', m: M, trail: []},
{x: 800, y: 450, vx: 0, vy: -9, r: 4, col: '#4488ff', m: 1, trail: []},
{x: 950, y: 450, vx: 0, vy: -6, r: 3, col: '#44ff88', m: 1, trail: []},
{x: 1100, y: 450, vx: 0, vy: -4.5, r: 2, col: '#ff8844', m: 1, trail: []},
{x: 700, y: 450, vx: 0, vy: -12, r: 3, col: '#ff00ff', m: 1, trail: []}
];
function update() {
bodies.forEach((b, i) => {
if (i === 0) return;
let ax = 0, ay = 0;
const dx = bodies[0].x - b.x;
const dy = bodies[0].y - b.y;
const r2 = dx*dx + dy*dy;
const r = Math.sqrt(r2);
const f = G * M / r2;
ax = f * dx / r;
ay = f * dy / r;
b.vx += ax * 0.01;
b.vy += ay * 0.01;
b.x += b.vx;
b.y += b.vy;
b.trail.push({x: b.x, y: b.y});
if (b.trail.length > 300) b.trail.shift();
});
}
function draw() {
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
bodies.forEach(b => {
ctx.strokeStyle = b.col;
ctx.globalAlpha = 0.15;
ctx.lineWidth = 1;
ctx.beginPath();
b.trail.forEach((p, i) => {
if (i === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
});
ctx.stroke();
ctx.globalAlpha = 1;
ctx.fillStyle = b.col;
ctx.beginPath();
ctx.arc(b.x, b.y, b.r, 0, Math.PI * 2);
ctx.fill();
});
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>▶ R30 · Spring-mass chainBLANK★ 1.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Spring-Mass Chain</title>
<style>
body { margin: 0; overflow: hidden; background: #1a1a1a; }
canvas { display: block; cursor: grab; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
canvas.width = 1000;
canvas.height = 400;
const k = 0.5, damping = 0.95;
const masses = [];
const numMasses = 12;
const spacing = canvas.width / (numMasses + 1);
let grabbed = -1;
for (let i = 0; i < numMasses; i++) {
masses.push({
x: spacing * (i + 1),
y: canvas.height / 2,
px: spacing * (i + 1),
py: canvas.height / 2
});
}
canvas.addEventListener('mousedown', (e) => {
const rect = canvas.getBoundingClientRect();
const mx = e.clientX - rect.left;
const my = e.clientY - rect.top;
for (let i = 0; i < masses.length; i++) {
const dx = masses[i].x - mx, dy = masses[i].y - my;
if (dx*dx + dy*dy < 100) {
grabbed = i;
break;
}
}
});
canvas.addEventListener('mousemove', (e) => {
if (grabbed >= 0) {
const rect = canvas.getBoundingClientRect();
masses[grabbed].x = e.clientX - rect.left;
masses[grabbed].y = e.clientY - rect.top;
masses[grabbed].px = masses[grabbed].x;
masses[grabbed].py = masses[grabbed].y;
}
});
canvas.addEventListener('mouseup', () => grabbed = -1);
function update() {
for (let i = 0; i < numMasses; i++) {
if (i === grabbed) continue;
const vx = (masses[i].x - masses[i].px) * damping;
const vy = (masses[i].y - masses[i].py) * damping;
masses[i].px = masses[i].x;
masses[i].py = masses[i].y;
masses[i].x += vx;
masses[i].y += vy + 0.1;
}
for (let i = 0; i < numMasses - 1; i++) {
const dx = masses[i+1].x - masses[i].x;
const dy = masses[i+1].y - masses[i].y;
const len = Math.sqrt(dx*dx + dy*dy);
const force = (len - spacing) * k / len;
const fx = force * dx, fy = force * dy;
if (i !== grabbed) {
masses[i].x += fx;
masses[i].y += fy;
}
if (i+1 !== grabbed) {
masses[i+1].x -= fx;
masses[i+1].y -= fy;
}
}
}
function draw() {
ctx.fillStyle = '#1a1a1a';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#666';
ctx.lineWidth = 2;
ctx.beginPath();
masses.forEach((m, i) => {
if (i === 0) ctx.moveTo(m.x, m.y);
else ctx.lineTo(m.x, m.y);
});
ctx.stroke();
masses.forEach((m, i) => {
ctx.fillStyle = (i === grabbed) ? '#ffff00' : '#4488ff';
ctx.beginPath();
ctx.arc(m.x, m.y, 6, 0, Math.PI * 2);
ctx.fill();
});
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>