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

model output

Gemini 3 Flash Preview

Only CSS: Screw 2

A 0.65T 0.23
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>Screw Animation Recreated</title>
7    <style>
8        :root {
9            --bg-color: #1a252f;
10            --text-color: #ffffff;
11            --duration: 4s;
12            --ease: cubic-bezier(0.7, 0, 0.3, 1);
13        }
14
15        body, html {
16            margin: 0;
17            padding: 0;
18            width: 100%;
19            height: 100%;
20            display: flex;
21            justify-content: center;
22            align-items: center;
23            background-color: var(--bg-color);
24            overflow: hidden;
25            font-family: 'Impact', 'Arial Black', sans-serif;
26        }
27
28        .scene {
29            position: relative;
30            width: 600px;
31            height: 300px;
32            display: flex;
33            justify-content: center;
34            align-items: center;
35        }
36
37        /* Base text used for dimensions and hidden reference if needed */
38        .word-wrapper {
39            position: relative;
40            font-size: 140px;
41            letter-spacing: -2px;
42            text-transform: uppercase;
43            color: var(--text-color);
44            white-space: nowrap;
45            pointer-events: none;
46        }
47
48        .layer {
49            position: absolute;
50            top: 0;
51            left: 0;
52            width: 100%;
53            height: 100%;
54            display: flex;
55            justify-content: center;
56            align-items: center;
57            /* Centralizing the rotation point to the middle of the word */
58            transform-origin: center center;
59            animation: screw-spin var(--duration) var(--ease) infinite;
60            -webkit-mask-repeat: no-repeat;
61            mask-repeat: no-repeat;
62        }
63
64        @keyframes screw-spin {
65            0% {
66                transform: rotate(0deg) scale(1);
67            }
68            45%, 55% {
69                /* Outer rings rotate more, inner rotate less (set via JS) */
70                transform: rotate(var(--rot)) scale(var(--s));
71            }
72            100% {
73                transform: rotate(0deg) scale(1);
74            }
75        }
76
77        /* Overlay to add the subtle "cut lines" visible in the static state */
78        .cut-lines {
79            position: absolute;
80            width: 100%;
81            height: 100%;
82            pointer-events: none;
83            z-index: 10;
84        }
85    </style>
86</head>
87<body>
88
89    <div class="scene" id="container">
90        <!-- Layers will be injected here by JavaScript -->
91    </div>
92
93    <script>
94        const container = document.getElementById('container');
95        const text = "SCREW";
96        const layerCount = 18; // Number of concentric rings
97        const ringWidth = 16;  // Width of each ring in pixels
98        const gap = 1.5;       // Small gap to create the 'sliced' look
99
100        for (let i = 0; i < layerCount; i++) {
101            const layer = document.createElement('div');
102            layer.className = 'layer';
103            
104            // Text content
105            const content = document.createElement('div');
106            content.className = 'word-wrapper';
107            content.textContent = text;
108            layer.appendChild(content);
109
110            // Define ring boundaries
111            const inner = i * ringWidth;
112            const outer = (i + 1) * ringWidth - gap;
113
114            // Apply Masking to create the ring effect
115            // Using a radial gradient to mask everything except a specific circle ring
116            const mask = `radial-gradient(circle at center, transparent ${inner}px, black ${inner}px, black ${outer}px, transparent ${outer}px)`;
117            layer.style.webkitMaskImage = mask;
118            layer.style.maskImage = mask;
119
120            // Calculate rotation and scale offsets based on ring index
121            // Outer rings (higher i) travel further and scale slightly more
122            const rotationAmount = (i + 1) * 45; // Progressive rotation
123            const scaleAmount = 1 + (i * 0.03);   // Slight expansion to mimic vortex
124            
125            layer.style.setProperty('--rot', `${rotationAmount}deg`);
126            layer.style.setProperty('--s', scaleAmount);
127
128            // Stagger the animation slightly for a more fluid "screw" motion
129            layer.style.animationDelay = `${i * 0.02}s`;
130
131            container.appendChild(layer);
132        }
133
134        /**
135         * Note on logic:
136         * The video shows a word that is "sliced" into concentric rings. 
137         * Each ring rotates around the center of the word.
138         * Because the word is wide (rectangular) but the rotation is circular,
139         * the parts of the letters further from the center (like the 'S' and 'W') 
140         * move along much larger arcs than the 'R' in the center.
141         * This creates the "breaking apart" and "spiral" visual naturally.
142         */
143    </script>
144</body>
145</html>