animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Houdini Gradient Border Button

model output

Claude Sonnet 4.6

Houdini Gradient Border Button

A 0.93T 0.27
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>Shiny Border</title>
7<style>
8  * {
9    margin: 0;
10    padding: 0;
11    box-sizing: border-box;
12  }
13
14  body {
15    background: #000;
16    display: flex;
17    justify-content: center;
18    align-items: center;
19    min-height: 100vh;
20    font-family: Arial, sans-serif;
21  }
22
23  .btn-wrapper {
24    position: relative;
25    padding: 2px;
26    background: transparent;
27  }
28
29  .btn {
30    position: relative;
31    padding: 12px 30px;
32    background: #000;
33    color: #fff;
34    font-size: 14px;
35    letter-spacing: 0.5px;
36    border: none;
37    cursor: pointer;
38    display: block;
39    z-index: 1;
40  }
41
42  .border-canvas {
43    position: absolute;
44    top: 0;
45    left: 0;
46    width: 100%;
47    height: 100%;
48    pointer-events: none;
49  }
50</style>
51</head>
52<body>
53
54<div class="btn-wrapper">
55  <canvas class="border-canvas" id="borderCanvas"></canvas>
56  <button class="btn">Shiny Border</button>
57</div>
58
59<script>
60  const canvas = document.getElementById('borderCanvas');
61  const wrapper = canvas.parentElement;
62
63  function resize() {
64    canvas.width = wrapper.offsetWidth;
65    canvas.height = wrapper.offsetHeight;
66  }
67  resize();
68
69  const ctx = canvas.getContext('2d');
70
71  const duration = 3000; // ms for one full loop
72  let startTime = null;
73
74  function getPerimeter(w, h) {
75    return 2 * (w + h);
76  }
77
78  function pointOnRect(t, w, h) {
79    // t goes 0..1 around the rectangle starting from top-left going clockwise
80    const perim = getPerimeter(w, h);
81    const dist = t * perim;
82
83    if (dist <= w) {
84      // top edge: left to right
85      return { x: dist, y: 0 };
86    } else if (dist <= w + h) {
87      // right edge: top to bottom
88      return { x: w, y: dist - w };
89    } else if (dist <= 2 * w + h) {
90      // bottom edge: right to left
91      return { x: w - (dist - w - h), y: h };
92    } else {
93      // left edge: bottom to top
94      return { x: 0, y: h - (dist - 2 * w - h) };
95    }
96  }
97
98  function animate(timestamp) {
99    if (!startTime) startTime = timestamp;
100    const elapsed = (timestamp - startTime) % duration;
101    const t = elapsed / duration;
102
103    const w = canvas.width;
104    const h = canvas.height;
105
106    ctx.clearRect(0, 0, w, h);
107
108    // Draw dim border
109    ctx.strokeStyle = 'rgba(0, 80, 120, 0.4)';
110    ctx.lineWidth = 1;
111    ctx.strokeRect(0.5, 0.5, w - 1, h - 1);
112
113    // Draw shiny spot traveling around the border
114    const trailLength = 0.15; // fraction of perimeter
115    const steps = 80;
116
117    for (let i = 0; i <= steps; i++) {
118      const frac = i / steps;
119      const tPos = (t - frac * trailLength + 1) % 1;
120      const pt = pointOnRect(tPos, w - 1, h - 1);
121
122      // alpha: brightest at head (frac=1), fades at tail (frac=0)
123      const alpha = frac * frac;
124      const brightness = Math.floor(100 + frac * 155);
125      
126      ctx.beginPath();
127      ctx.arc(pt.x + 0.5, pt.y + 0.5, 1.5, 0, Math.PI * 2);
128      ctx.fillStyle = `rgba(0, ${brightness}, ${brightness + 50}, ${alpha})`;
129      ctx.fill();
130    }
131
132    // Draw the bright head
133    const headPt = pointOnRect(t, w - 1, h - 1);
134    
135    // Glow effect at head
136    const grad = ctx.createRadialGradient(
137      headPt.x + 0.5, headPt.y + 0.5, 0,
138      headPt.x + 0.5, headPt.y + 0.5, 8
139    );
140    grad.addColorStop(0, 'rgba(100, 220, 255, 1)');
141    grad.addColorStop(0.3, 'rgba(0, 180, 220, 0.6)');
142    grad.addColorStop(1, 'rgba(0, 100, 150, 0)');
143
144    ctx.beginPath();
145    ctx.arc(headPt.x + 0.5, headPt.y + 0.5, 8, 0, Math.PI * 2);
146    ctx.fillStyle = grad;
147    ctx.fill();
148
149    requestAnimationFrame(animate);
150  }
151
152  requestAnimationFrame(animate);
153</script>
154</body>
155</html>