animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Only CSS: Joint Animation

model output

Claude Sonnet 4.6

Only CSS: Joint Animation

A 0.83T 0.30
compare with ground truth →
1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width, initial-scale=1.0">
6<title>Morphing Bar Animation</title>
7<style>
8  * { margin: 0; padding: 0; box-sizing: border-box; }
9  body {
10    width: 1024px;
11    height: 768px;
12    background: white;
13    display: flex;
14    align-items: center;
15    justify-content: center;
16    overflow: hidden;
17  }
18  canvas {
19    position: absolute;
20    top: 0; left: 0;
21  }
22</style>
23</head>
24<body>
25<canvas id="c" width="1024" height="768"></canvas>
26<script>
27const canvas = document.getElementById('c');
28const ctx = canvas.getContext('2d');
29
30const COLOR = '#4BADD3';
31const LINE_WIDTH = 52;
32
33// Animation: horizontal bar → V shape → L shape → V shape → horizontal bar (loop)
34// Total duration: ~3 seconds per cycle
35
36// Key points for the shape:
37// Frame 1 (t=0): Horizontal bar from ~(365,385) to ~(880,385)
38// Frame 2 (t=0.3): V shape - left segment goes up-left, right segment goes right
39//   left end: ~(370,390), bend: ~(615,490), right end: ~(870,460)
40// Frame 3 (t=0.6): L shape - vertical segment up, horizontal segment right
41//   top: ~(415,340), bend: ~(415,580), right end: ~(720,580)
42// Frame 4-5: hold L shape
43// Frame 6: back to V
44// Then back to horizontal
45
46// I'll animate using parametric interpolation between keyframes
47
48function lerp(a, b, t) { return a + (b - a) * t; }
49
50function lerpPt(p1, p2, t) {
51  return { x: lerp(p1.x, p2.x, t), y: lerp(p1.y, p2.y, t) };
52}
53
54// Keyframe shapes: each shape is [p1, p2, p3] where p2 is the bend point
55const shapes = {
56  horizontal: [
57    { x: 365, y: 385 },
58    { x: 622, y: 385 }, // midpoint as bend (straight)
59    { x: 880, y: 385 }
60  ],
61  vShape: [
62    { x: 370, y: 370 },
63    { x: 610, y: 490 },
64    { x: 870, y: 460 }
65  ],
66  lShape: [
67    { x: 415, y: 330 },
68    { x: 415, y: 575 },
69    { x: 720, y: 575 }
70  ]
71};
72
73function easeInOut(t) {
74  return t < 0.5 ? 2*t*t : -1+(4-2*t)*t;
75}
76
77function drawShape(p1, bend, p3) {
78  ctx.clearRect(0, 0, 1024, 768);
79  ctx.strokeStyle = COLOR;
80  ctx.lineWidth = LINE_WIDTH;
81  ctx.lineCap = 'round';
82  ctx.lineJoin = 'round';
83  
84  ctx.beginPath();
85  ctx.moveTo(p1.x, p1.y);
86  ctx.lineTo(bend.x, bend.y);
87  ctx.lineTo(p3.x, p3.y);
88  ctx.stroke();
89}
90
91function interpShape(s1, s2, t) {
92  return [
93    lerpPt(s1[0], s2[0], t),
94    lerpPt(s1[1], s2[1], t),
95    lerpPt(s1[2], s2[2], t)
96  ];
97}
98
99// Timeline (seconds):
100// 0.0 - 0.5: horizontal → vShape
101// 0.5 - 1.2: vShape → lShape
102// 1.2 - 2.0: hold lShape
103// 2.0 - 2.7: lShape → vShape
104// 2.7 - 3.2: vShape → horizontal
105// 3.2 - 3.7: hold horizontal
106// 3.7: loop
107
108const CYCLE = 3700; // ms
109
110function animate(timestamp) {
111  const t = (timestamp % CYCLE) / CYCLE;
112  const ms = t * CYCLE;
113  
114  let shape;
115  
116  if (ms < 500) {
117    // horizontal → vShape
118    const p = easeInOut(ms / 500);
119    shape = interpShape(shapes.horizontal, shapes.vShape, p);
120  } else if (ms < 1200) {
121    // vShape → lShape
122    const p = easeInOut((ms - 500) / 700);
123    shape = interpShape(shapes.vShape, shapes.lShape, p);
124  } else if (ms < 2000) {
125    // hold lShape
126    shape = shapes.lShape;
127  } else if (ms < 2700) {
128    // lShape → vShape
129    const p = easeInOut((ms - 2000) / 700);
130    shape = interpShape(shapes.lShape, shapes.vShape, p);
131  } else if (ms < 3200) {
132    // vShape → horizontal
133    const p = easeInOut((ms - 2700) / 500);
134    shape = interpShape(shapes.vShape, shapes.horizontal, p);
135  } else {
136    // hold horizontal
137    shape = shapes.horizontal;
138  }
139  
140  drawShape(shape[0], shape[1], shape[2]);
141  requestAnimationFrame(animate);
142}
143
144requestAnimationFrame(animate);
145</script>
146</body>
147</html>