← back to Only CSS: Joint Animationcompare with ground truth →
model output
Claude Sonnet 4.6
Only CSS: Joint Animation
A 0.78T 0.24
1Looking at the animation, I can see two rectangular bars connected at a pivot point (like a hinge/scissors mechanism):
21. A gray bar with a yellow dot (pivot point on the right end)
32. A blue bar with a yellow dot (pivot point on the left end)
4
5They start horizontal, then the gray bar rotates up (~-30° to -90°) while the blue bar stays relatively horizontal, creating a folding/unfolding scissors-like motion. The pivot point is where they connect.
6
7The animation appears to:
8- Start: both bars horizontal, side by side
9- Middle: gray bar rotates up ~-60°, blue bar slightly angled
10- End: gray bar nearly vertical (~-80°), blue bar horizontal
11- Then reverses back
12
13Let me analyze more carefully - the gray bar rotates around its right end (pivot), and the blue bar rotates around its left end (same pivot point).
14
15<!DOCTYPE html>
16<html>
17<head>
18<style>
19 body { margin: 0; background: white; overflow: hidden; }
20 canvas { display: block; }
21</style>
22</head>
23<body>
24<canvas id="c"></canvas>
25<script>
26const canvas = document.getElementById('c');
27const ctx = canvas.getContext('2d');
28canvas.width = 1024;
29canvas.height = 768;
30
31const BAR_W = 280;
32const BAR_H = 70;
33const DOT_R = 10;
34
35// Pivot point in screen space
36const pivotX = 590;
37const pivotY = 383;
38
39// Gray bar: pivot is at its RIGHT end (center-right)
40// dot is at left side of gray bar
41// Blue bar: pivot is at its LEFT end (center-left)
42// dot is at left side of blue bar
43
44function drawBar(color, x, y, w, h, angle, pivotOffsetX, dotOffsetX) {
45 ctx.save();
46 ctx.translate(x, y);
47 ctx.rotate(angle);
48
49 // Draw rectangle centered at pivot offset
50 ctx.fillStyle = color;
51 ctx.beginPath();
52 ctx.rect(-pivotOffsetX, -h/2, w, h);
53 ctx.fill();
54
55 // Draw dot
56 ctx.fillStyle = '#f5c518';
57 ctx.beginPath();
58 ctx.arc(dotOffsetX - pivotOffsetX, 0, DOT_R, 0, Math.PI*2);
59 ctx.fill();
60 ctx.fillStyle = 'white';
61 ctx.beginPath();
62 ctx.arc(dotOffsetX - pivotOffsetX, 0, DOT_R*0.4, 0, Math.PI*2);
63 ctx.fill();
64
65 ctx.restore();
66}
67
68let startTime = null;
69const duration = 2000; // ms for one way
70const totalDuration = duration * 2;
71
72function easeInOut(t) {
73 return t < 0.5 ? 2*t*t : -1+(4-2*t)*t;
74}
75
76function animate(ts) {
77 if (!startTime) startTime = ts;
78 let elapsed = (ts - startTime) % (totalDuration + 800);
79
80 let t;
81 if (elapsed < duration) {
82 t = easeInOut(elapsed / duration);
83 } else if (elapsed < duration + 400) {
84 t = 1;
85 } else if (elapsed < totalDuration + 400) {
86 t = easeInOut(1 - (elapsed - duration - 400) / duration);
87 } else {
88 t = 0;
89 }
90
91 // Gray bar angle: 0 -> -90deg (rotates up)
92 const grayAngle = t * (-Math.PI / 2);
93 // Blue bar angle: 0 -> 0 (stays horizontal, slight variation)
94 const blueAngle = 0;
95
96 ctx.clearRect(0, 0, canvas.width, canvas.height);
97
98 // Gray bar: pivot at right end, dot at left
99 // width=280, pivot at right means pivotOffsetX = 280, dot at x=40 from left = dotOffsetX=40
100 drawBar('#999999', pivotX, pivotY, BAR_W, BAR_H, grayAngle, BAR_W - 40, 40);
101
102 // Blue bar: pivot at left end, dot at left side
103 // width=280, pivot at left means pivotOffsetX=0, dot at x=40
104 drawBar('#4aabcf', pivotX, pivotY, BAR_W, BAR_H, blueAngle, 0, 40);
105
106 requestAnimationFrame(animate);
107}
108
109requestAnimationFrame(animate);
110</script>
111</body>
112</html>