← back to Merry Christmas Tree!compare with ground truth →
model output
Gemini 3 Flash Preview
Merry Christmas Tree!
A 0.81T 0.32
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>Christmas Tree Animation</title>
7 <style>
8 @import url('https://fonts.googleapis.com/css2?family=Great+Vibes&display=swap');
9
10 body {
11 margin: 0;
12 padding: 0;
13 background-color: #0e101a;
14 display: flex;
15 justify-content: center;
16 align-items: center;
17 height: 100vh;
18 overflow: hidden;
19 }
20
21 .container {
22 position: relative;
23 width: 500px;
24 height: 650px;
25 }
26
27 svg {
28 width: 100%;
29 height: 100%;
30 }
31
32 /* The copper/gold color used for the tree and text */
33 :root {
34 --gold-color: #c08e5c;
35 --blue-glow: #00d4ff;
36 }
37
38 .tree-path {
39 fill: none;
40 stroke: var(--gold-color);
41 stroke-width: 2.5;
42 stroke-linecap: round;
43 stroke-linejoin: round;
44 stroke-dasharray: 1000;
45 stroke-dashoffset: 1000;
46 animation: drawTree 6s ease-in-out forwards;
47 }
48
49 @keyframes drawTree {
50 0% { stroke-dashoffset: 1000; }
51 100% { stroke-dashoffset: 0; }
52 }
53
54 #glow-follower {
55 position: absolute;
56 width: 8px;
57 height: 8px;
58 background: white;
59 border-radius: 50%;
60 top: 0;
61 left: 0;
62 box-shadow:
63 0 0 10px 4px white,
64 0 0 20px 8px var(--blue-glow),
65 0 0 40px 15px rgba(0, 212, 255, 0.4);
66 offset-path: path('M 210,480 C 130,480 220,430 220,430 C 160,430 235,370 235,370 C 190,370 250,280 250,280 C 310,370 265,370 265,370 C 340,430 280,430 280,430 C 370,480 290,480 290,480 M 242,482 Q 250,505 258,482 M 140,540 C 200,510 300,510 360,540');
67 animation: moveGlow 6s ease-in-out forwards;
68 z-index: 10;
69 }
70
71 @keyframes moveGlow {
72 0% { offset-distance: 0%; opacity: 1; }
73 95% { opacity: 1; }
74 100% { offset-distance: 100%; opacity: 0; }
75 }
76
77 .top-star {
78 fill: var(--gold-color);
79 opacity: 0;
80 transform: scale(0);
81 transform-origin: 250px 280px;
82 animation: popStar 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275) 2.2s forwards;
83 }
84
85 @keyframes popStar {
86 to { opacity: 1; transform: scale(1.2); }
87 }
88
89 .text-overlay {
90 position: absolute;
91 bottom: 50px;
92 width: 100%;
93 text-align: center;
94 color: var(--gold-color);
95 font-family: 'Great Vibes', cursive;
96 font-size: 28px;
97 opacity: 0;
98 animation: fadeIn 1.5s ease-out 6s forwards;
99 }
100
101 @keyframes fadeIn {
102 to { opacity: 1; }
103 }
104
105 /* Particle Stars */
106 .particle {
107 position: absolute;
108 pointer-events: none;
109 z-index: 5;
110 }
111
112 @keyframes particleAnim {
113 0% { transform: scale(1) rotate(0deg); opacity: 1; }
114 100% { transform: scale(0) rotate(180deg); opacity: 0; }
115 }
116 </style>
117</head>
118<body>
119
120 <div class="container" id="container">
121 <svg viewBox="0 0 500 650" id="main-svg">
122 <!-- Tree Path: Branches, Trunk, and Bottom Swoop combined -->
123 <path class="tree-path" d="M 210,480 C 130,480 220,430 220,430 C 160,430 235,370 235,370 C 190,370 250,280 250,280 C 310,370 265,370 265,370 C 340,430 280,430 280,430 C 370,480 290,480 290,480 M 242,482 Q 250,505 258,482 M 140,540 C 200,510 300,510 360,540"></path>
124
125 <!-- Peak Star -->
126 <path class="top-star" d="M 250,255 L 257,272 L 275,272 L 261,283 L 266,300 L 250,290 L 234,300 L 239,283 L 225,272 L 243,272 Z"></path>
127 </svg>
128
129 <!-- The Glowing Leading Light -->
130 <div id="glow-follower"></div>
131
132 <!-- Final Text -->
133 <div class="text-overlay">This is available to buy at my shop</div>
134 </div>
135
136 <script>
137 const container = document.getElementById('container');
138 const glow = document.getElementById('glow-follower');
139 const particleColors = ['#ff4d4d', '#4dff4d', '#ffffff', '#ffd700', '#00ffff', '#c08e5c'];
140
141 let startTime = null;
142 const duration = 6000; // Match CSS animation time
143
144 function createParticle(x, y) {
145 const star = document.createElement('div');
146 star.className = 'particle';
147
148 // Randomly choose between a small dot or a star shape
149 const isStar = Math.random() > 0.5;
150 const size = Math.random() * 8 + 4;
151
152 star.style.left = (x - size/2) + 'px';
153 star.style.top = (y - size/2) + 'px';
154 star.style.width = size + 'px';
155 star.style.height = size + 'px';
156
157 const color = particleColors[Math.floor(Math.random() * particleColors.length)];
158
159 if (isStar) {
160 star.style.backgroundColor = 'transparent';
161 star.style.clipPath = 'polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%)';
162 star.style.background = color;
163 } else {
164 star.style.background = color;
165 star.style.borderRadius = '50%';
166 }
167
168 star.style.animation = `particleAnim ${Math.random() * 1 + 0.5}s ease-out forwards`;
169 container.appendChild(star);
170
171 setTimeout(() => {
172 star.remove();
173 }, 1500);
174 }
175
176 function animate(timestamp) {
177 if (!startTime) startTime = timestamp;
178 const progress = timestamp - startTime;
179
180 if (progress < duration) {
181 const rect = glow.getBoundingClientRect();
182 const containerRect = container.getBoundingClientRect();
183
184 // Get center coordinates of the glow relative to container
185 const x = rect.left - containerRect.left + rect.width / 2;
186 const y = rect.top - containerRect.top + rect.height / 2;
187
188 // Spawn particles more frequently
189 if (Math.random() > 0.3) {
190 createParticle(x, y);
191 }
192
193 requestAnimationFrame(animate);
194 }
195 }
196
197 // Start particle generation
198 requestAnimationFrame(animate);
199 </script>
200</body>
201</html>