hyperframes 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/cli.js +940 -380
- package/dist/hyperframe-runtime.js +8 -4
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +8 -4
- package/dist/skills/hyperframes-captions/SKILL.md +195 -29
- package/dist/skills/hyperframes-compose/SKILL.md +1 -0
- package/dist/skills/hyperframes-compose/house-style.md +2 -2
- package/dist/studio/assets/index-CLmYRLY-.css +1 -0
- package/dist/studio/assets/index-CRvFpc0E.js +84 -0
- package/dist/studio/index.html +2 -2
- package/dist/templates/_shared/CLAUDE.md +14 -2
- package/dist/templates/blank/compositions/captions.html +3 -0
- package/dist/templates/blank/index.html +1 -1
- package/dist/templates/decision-tree/compositions/decision_tree.html +420 -0
- package/dist/templates/decision-tree/index.html +56 -0
- package/dist/templates/generators.ts +32 -0
- package/dist/templates/kinetic-type/compositions/main-graphics.html +588 -0
- package/dist/templates/kinetic-type/index.html +61 -0
- package/dist/templates/nyt-graph/compositions/nyt-chart.html +450 -0
- package/dist/templates/nyt-graph/index.html +51 -0
- package/dist/templates/product-promo/assets/figma-cursors.svg +30 -0
- package/dist/templates/product-promo/assets/figma-logo-pieces.svg +15 -0
- package/dist/templates/product-promo/assets/figma-logo-pills.svg +6 -0
- package/dist/templates/product-promo/compositions/scene1-logo-intro.html +189 -0
- package/dist/templates/product-promo/compositions/scene2-4-canvas.html +570 -0
- package/dist/templates/product-promo/compositions/scene5-logo-outro.html +226 -0
- package/dist/templates/product-promo/index.html +158 -0
- package/package.json +2 -2
- package/dist/studio/assets/index-2uBPlHR_.css +0 -1
- package/dist/studio/assets/index-uQ8cgxb3.js +0 -92
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
<template id="nyt-chart-template">
|
|
2
|
+
<div data-composition-id="nyt-chart" data-width="1920" data-height="1080" data-duration="15">
|
|
3
|
+
<!-- Google Fonts Import -->
|
|
4
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
5
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
6
|
+
<link
|
|
7
|
+
href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&family=Libre+Franklin:wght@300;400;600&display=block"
|
|
8
|
+
rel="stylesheet"
|
|
9
|
+
/>
|
|
10
|
+
|
|
11
|
+
<div class="chart-container">
|
|
12
|
+
<!-- Header Section -->
|
|
13
|
+
<div class="header">
|
|
14
|
+
<h1 class="headline">Monthly Revenue vs. Conversion Rate</h1>
|
|
15
|
+
<p class="subtitle">Jan–Jun 2024, in thousands</p>
|
|
16
|
+
<div class="key">
|
|
17
|
+
<div class="key-item">
|
|
18
|
+
<div class="key-box revenue-box"></div>
|
|
19
|
+
<span class="key-text">Revenue</span>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="key-item">
|
|
22
|
+
<div class="key-line conversion-line"></div>
|
|
23
|
+
<span class="key-text">Conversion Rate</span>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<!-- SVG Chart Area -->
|
|
29
|
+
<svg class="chart-svg" viewBox="0 0 1600 700" preserveAspectRatio="xMidYMid meet">
|
|
30
|
+
<!-- Gridlines Group -->
|
|
31
|
+
<g class="gridlines"></g>
|
|
32
|
+
|
|
33
|
+
<!-- X-Axis Labels -->
|
|
34
|
+
<g class="x-axis-labels"></g>
|
|
35
|
+
|
|
36
|
+
<!-- Bars Group (Revenue) -->
|
|
37
|
+
<g class="bars-group"></g>
|
|
38
|
+
|
|
39
|
+
<!-- Bar Labels Group -->
|
|
40
|
+
<g class="bar-labels-group"></g>
|
|
41
|
+
|
|
42
|
+
<!-- Line Group (Conversion Rate) -->
|
|
43
|
+
<g class="line-group">
|
|
44
|
+
<path class="conversion-path" fill="none" stroke="#326FA8" stroke-width="1.5" />
|
|
45
|
+
<circle class="line-dot" r="5" fill="#326FA8" style="opacity: 0" />
|
|
46
|
+
</g>
|
|
47
|
+
|
|
48
|
+
<!-- Line Labels Group -->
|
|
49
|
+
<g class="line-labels-group"></g>
|
|
50
|
+
|
|
51
|
+
<!-- Baseline -->
|
|
52
|
+
<line x1="100" y1="600" x2="1500" y2="600" stroke="black" stroke-width="1" />
|
|
53
|
+
</svg>
|
|
54
|
+
|
|
55
|
+
<!-- Source Line -->
|
|
56
|
+
<div class="source">Source: Internal analytics</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<style>
|
|
60
|
+
[data-composition-id="nyt-chart"] {
|
|
61
|
+
width: 1920px;
|
|
62
|
+
height: 1080px;
|
|
63
|
+
background-color: #faf9f6;
|
|
64
|
+
font-family: "Libre Franklin", sans-serif;
|
|
65
|
+
color: #333;
|
|
66
|
+
display: flex;
|
|
67
|
+
justify-content: center;
|
|
68
|
+
align-items: center;
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
[data-composition-id="nyt-chart"] .chart-container {
|
|
73
|
+
width: 1600px;
|
|
74
|
+
height: 900px;
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
position: relative;
|
|
78
|
+
transform: scale(1.15);
|
|
79
|
+
transform-origin: center center;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
[data-composition-id="nyt-chart"] .header {
|
|
83
|
+
margin-bottom: 40px;
|
|
84
|
+
text-align: left;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-composition-id="nyt-chart"] .headline {
|
|
88
|
+
font-family: "Libre Baskerville", serif;
|
|
89
|
+
font-size: 42px;
|
|
90
|
+
margin: 0;
|
|
91
|
+
padding: 0;
|
|
92
|
+
clip-path: inset(0 100% 0 0);
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
[data-composition-id="nyt-chart"] .subtitle {
|
|
97
|
+
font-size: 16px;
|
|
98
|
+
color: #d4d4d4;
|
|
99
|
+
margin: 8px 0 16px 0;
|
|
100
|
+
clip-path: inset(0 100% 0 0);
|
|
101
|
+
white-space: nowrap;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
[data-composition-id="nyt-chart"] .key {
|
|
105
|
+
display: flex;
|
|
106
|
+
gap: 24px;
|
|
107
|
+
opacity: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
[data-composition-id="nyt-chart"] .key-item {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
gap: 8px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
[data-composition-id="nyt-chart"] .key-box {
|
|
117
|
+
width: 10px;
|
|
118
|
+
height: 10px;
|
|
119
|
+
background-color: #5c5c5c;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
[data-composition-id="nyt-chart"] .key-line {
|
|
123
|
+
width: 16px;
|
|
124
|
+
height: 1.5px;
|
|
125
|
+
background-color: #326fa8;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
[data-composition-id="nyt-chart"] .key-text {
|
|
129
|
+
font-size: 13px;
|
|
130
|
+
color: #666;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
[data-composition-id="nyt-chart"] .chart-svg {
|
|
134
|
+
width: 100%;
|
|
135
|
+
height: 600px;
|
|
136
|
+
overflow: visible;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
[data-composition-id="nyt-chart"] .source {
|
|
140
|
+
position: absolute;
|
|
141
|
+
bottom: 0;
|
|
142
|
+
left: 0;
|
|
143
|
+
font-size: 11px;
|
|
144
|
+
color: #999;
|
|
145
|
+
opacity: 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
[data-composition-id="nyt-chart"] .grid-line {
|
|
149
|
+
stroke: #e8e8e8;
|
|
150
|
+
stroke-width: 0.5px;
|
|
151
|
+
opacity: 0;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
[data-composition-id="nyt-chart"] .axis-label {
|
|
155
|
+
font-size: 14px;
|
|
156
|
+
fill: #666;
|
|
157
|
+
text-anchor: middle;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[data-composition-id="nyt-chart"] .bar {
|
|
161
|
+
fill: #5c5c5c;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
[data-composition-id="nyt-chart"] .bar-label {
|
|
165
|
+
font-size: 14px;
|
|
166
|
+
fill: #333;
|
|
167
|
+
text-anchor: middle;
|
|
168
|
+
opacity: 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
[data-composition-id="nyt-chart"] .line-label {
|
|
172
|
+
font-size: 14px;
|
|
173
|
+
fill: #326fa8;
|
|
174
|
+
font-weight: 600;
|
|
175
|
+
text-anchor: middle;
|
|
176
|
+
opacity: 0;
|
|
177
|
+
}
|
|
178
|
+
</style>
|
|
179
|
+
|
|
180
|
+
<script>
|
|
181
|
+
(function initChart() {
|
|
182
|
+
// Wait for DOM — the runtime may not have cloned the template content yet
|
|
183
|
+
const svg = document.querySelector(`[data-composition-id="nyt-chart"] .chart-svg`);
|
|
184
|
+
if (!svg) {
|
|
185
|
+
setTimeout(initChart, 50);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const tl = gsap.timeline({ paused: true });
|
|
189
|
+
|
|
190
|
+
// Data
|
|
191
|
+
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"];
|
|
192
|
+
const revenueData = [8, 12, 15, 11, 18, 22]; // in thousands
|
|
193
|
+
const conversionData = [2.1, 2.8, 3.2, 2.9, 3.8, 4.2]; // in percentage
|
|
194
|
+
|
|
195
|
+
// Chart Dimensions
|
|
196
|
+
const chartWidth = 1400;
|
|
197
|
+
const chartHeight = 500;
|
|
198
|
+
const startX = 100;
|
|
199
|
+
const startY = 600;
|
|
200
|
+
const barWidth = 80;
|
|
201
|
+
const spacing = (chartWidth - barWidth * months.length) / (months.length + 1);
|
|
202
|
+
|
|
203
|
+
// Scales
|
|
204
|
+
const maxRevenue = 25;
|
|
205
|
+
const maxConversion = 5;
|
|
206
|
+
|
|
207
|
+
const getBarY = (val) => startY - (val / maxRevenue) * chartHeight;
|
|
208
|
+
const getLineY = (val) => startY - (val / maxConversion) * chartHeight;
|
|
209
|
+
const getX = (i) => startX + spacing + i * (barWidth + spacing) + barWidth / 2;
|
|
210
|
+
|
|
211
|
+
// 1. Setup Elements (svg already found above)
|
|
212
|
+
const gridGroup = svg.querySelector(".gridlines");
|
|
213
|
+
const xAxisGroup = svg.querySelector(".x-axis-labels");
|
|
214
|
+
const barsGroup = svg.querySelector(".bars-group");
|
|
215
|
+
const barLabelsGroup = svg.querySelector(".bar-labels-group");
|
|
216
|
+
const lineLabelsGroup = svg.querySelector(".line-labels-group");
|
|
217
|
+
const conversionPath = svg.querySelector(".conversion-path");
|
|
218
|
+
const lineDot = svg.querySelector(".line-dot");
|
|
219
|
+
|
|
220
|
+
// Create Gridlines (5 lines)
|
|
221
|
+
for (let i = 1; i <= 5; i++) {
|
|
222
|
+
const y = startY - i * (chartHeight / 5);
|
|
223
|
+
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
224
|
+
line.setAttribute("x1", startX);
|
|
225
|
+
line.setAttribute("y1", y);
|
|
226
|
+
line.setAttribute("x2", startX + chartWidth);
|
|
227
|
+
line.setAttribute("y2", y);
|
|
228
|
+
line.setAttribute("class", "grid-line");
|
|
229
|
+
gridGroup.appendChild(line);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Create X-Axis Labels & Bars & Bar Labels
|
|
233
|
+
const linePoints = [];
|
|
234
|
+
months.forEach((month, i) => {
|
|
235
|
+
const x = getX(i);
|
|
236
|
+
|
|
237
|
+
// X-Axis Label
|
|
238
|
+
const label = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
239
|
+
label.setAttribute("x", x);
|
|
240
|
+
label.setAttribute("y", startY + 30);
|
|
241
|
+
label.setAttribute("class", "axis-label");
|
|
242
|
+
label.textContent = month;
|
|
243
|
+
xAxisGroup.appendChild(label);
|
|
244
|
+
|
|
245
|
+
// Bar
|
|
246
|
+
const barHeight = (revenueData[i] / maxRevenue) * chartHeight;
|
|
247
|
+
const bar = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
248
|
+
bar.setAttribute("x", x - barWidth / 2);
|
|
249
|
+
bar.setAttribute("y", startY);
|
|
250
|
+
bar.setAttribute("width", barWidth);
|
|
251
|
+
bar.setAttribute("height", 0);
|
|
252
|
+
bar.setAttribute("class", "bar");
|
|
253
|
+
barsGroup.appendChild(bar);
|
|
254
|
+
|
|
255
|
+
// Bar Label
|
|
256
|
+
const barLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
257
|
+
barLabel.setAttribute("x", x);
|
|
258
|
+
barLabel.setAttribute("y", getBarY(revenueData[i]) - 10);
|
|
259
|
+
barLabel.setAttribute("class", "bar-label");
|
|
260
|
+
barLabel.textContent = `$${revenueData[i]}K`;
|
|
261
|
+
barLabelsGroup.appendChild(barLabel);
|
|
262
|
+
|
|
263
|
+
// Line Point
|
|
264
|
+
linePoints.push(`${x},${getLineY(conversionData[i])}`);
|
|
265
|
+
|
|
266
|
+
// Line Label
|
|
267
|
+
const lineLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
268
|
+
lineLabel.setAttribute("x", x);
|
|
269
|
+
lineLabel.setAttribute("y", getLineY(conversionData[i]) - 15);
|
|
270
|
+
lineLabel.setAttribute("class", "line-label");
|
|
271
|
+
lineLabel.textContent = `${conversionData[i]}%`;
|
|
272
|
+
lineLabelsGroup.appendChild(lineLabel);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Set Path Data
|
|
276
|
+
conversionPath.setAttribute("d", `M ${linePoints.join(" L ")}`);
|
|
277
|
+
const pathLength = conversionPath.getTotalLength();
|
|
278
|
+
conversionPath.style.strokeDasharray = pathLength;
|
|
279
|
+
conversionPath.style.strokeDashoffset = pathLength;
|
|
280
|
+
|
|
281
|
+
// --- ANIMATION TIMELINE ---
|
|
282
|
+
|
|
283
|
+
// 2. Headline & Subtitle (Draw on left-to-right)
|
|
284
|
+
tl.to(
|
|
285
|
+
`[data-composition-id="nyt-chart"] .headline`,
|
|
286
|
+
{
|
|
287
|
+
clipPath: "inset(0 0% 0 0)",
|
|
288
|
+
duration: 1.2,
|
|
289
|
+
ease: "power1.inOut",
|
|
290
|
+
},
|
|
291
|
+
0,
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
tl.to(
|
|
295
|
+
`[data-composition-id="nyt-chart"] .subtitle`,
|
|
296
|
+
{
|
|
297
|
+
clipPath: "inset(0 0% 0 0)",
|
|
298
|
+
duration: 1.2,
|
|
299
|
+
ease: "power1.inOut",
|
|
300
|
+
},
|
|
301
|
+
0.2,
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
// 3. Inline Key
|
|
305
|
+
tl.to(
|
|
306
|
+
`[data-composition-id="nyt-chart"] .key`,
|
|
307
|
+
{
|
|
308
|
+
opacity: 1,
|
|
309
|
+
duration: 0.4,
|
|
310
|
+
ease: "power2.out",
|
|
311
|
+
},
|
|
312
|
+
1.0,
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
// 4. Gridlines (Stagger bottom to top)
|
|
316
|
+
tl.to(
|
|
317
|
+
`[data-composition-id="nyt-chart"] .grid-line`,
|
|
318
|
+
{
|
|
319
|
+
opacity: 1,
|
|
320
|
+
duration: 0.5,
|
|
321
|
+
stagger: 0.25,
|
|
322
|
+
ease: "power2.out",
|
|
323
|
+
},
|
|
324
|
+
0.5,
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
// 5. Bars (Revenue)
|
|
328
|
+
const bars = barsGroup.querySelectorAll(".bar");
|
|
329
|
+
const barLabels = barLabelsGroup.querySelectorAll(".bar-label");
|
|
330
|
+
|
|
331
|
+
bars.forEach((bar, i) => {
|
|
332
|
+
const barHeight = (revenueData[i] / maxRevenue) * chartHeight;
|
|
333
|
+
const startTime = 1.5 + i * 0.5; // 0.8s duration, 0.3s overlap (0.8 - 0.3 = 0.5 step)
|
|
334
|
+
|
|
335
|
+
tl.to(
|
|
336
|
+
bar,
|
|
337
|
+
{
|
|
338
|
+
attr: {
|
|
339
|
+
height: barHeight,
|
|
340
|
+
y: startY - barHeight,
|
|
341
|
+
},
|
|
342
|
+
duration: 0.8,
|
|
343
|
+
ease: "power2.out",
|
|
344
|
+
},
|
|
345
|
+
startTime,
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
// 6. Bar Labels
|
|
349
|
+
tl.to(
|
|
350
|
+
barLabels[i],
|
|
351
|
+
{
|
|
352
|
+
opacity: 1,
|
|
353
|
+
duration: 0.3,
|
|
354
|
+
ease: "power2.out",
|
|
355
|
+
},
|
|
356
|
+
startTime + 0.8,
|
|
357
|
+
);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// 7. Line (Conversion Rate)
|
|
361
|
+
// Starts 0.5s after the last bar begins
|
|
362
|
+
const lastBarStartTime = 1.5 + (months.length - 1) * 0.5;
|
|
363
|
+
const lineStartTime = lastBarStartTime + 0.5;
|
|
364
|
+
|
|
365
|
+
tl.to(
|
|
366
|
+
conversionPath,
|
|
367
|
+
{
|
|
368
|
+
strokeDashoffset: 0,
|
|
369
|
+
duration: 3,
|
|
370
|
+
ease: "none",
|
|
371
|
+
},
|
|
372
|
+
lineStartTime,
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
// 8. Line Dot & 9. Line Labels
|
|
376
|
+
// We need to sync the dot and labels with the path drawing
|
|
377
|
+
tl.set(
|
|
378
|
+
lineDot,
|
|
379
|
+
{ opacity: 1, attr: { cx: getX(0), cy: getLineY(conversionData[0]) } },
|
|
380
|
+
lineStartTime,
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const lineLabels = lineLabelsGroup.querySelectorAll(".line-label");
|
|
384
|
+
months.forEach((_, i) => {
|
|
385
|
+
if (i > 0) {
|
|
386
|
+
const x = getX(i);
|
|
387
|
+
const y = getLineY(conversionData[i]);
|
|
388
|
+
tl.to(
|
|
389
|
+
lineDot,
|
|
390
|
+
{
|
|
391
|
+
attr: {
|
|
392
|
+
cx: x,
|
|
393
|
+
cy: y,
|
|
394
|
+
},
|
|
395
|
+
duration: 3 / (months.length - 1),
|
|
396
|
+
ease: "none",
|
|
397
|
+
},
|
|
398
|
+
lineStartTime + ((i - 1) / (months.length - 1)) * 3,
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const labelTime = lineStartTime + (i / (months.length - 1)) * 3 + 0.2;
|
|
403
|
+
|
|
404
|
+
// Set initial text to 0.0%
|
|
405
|
+
lineLabels[i].textContent = "0.0%";
|
|
406
|
+
|
|
407
|
+
// Fade in
|
|
408
|
+
tl.to(
|
|
409
|
+
lineLabels[i],
|
|
410
|
+
{
|
|
411
|
+
opacity: 1,
|
|
412
|
+
duration: 0.1,
|
|
413
|
+
ease: "power2.out",
|
|
414
|
+
},
|
|
415
|
+
labelTime,
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
// Animate value
|
|
419
|
+
const dummy = { val: 0 };
|
|
420
|
+
tl.to(
|
|
421
|
+
dummy,
|
|
422
|
+
{
|
|
423
|
+
val: conversionData[i],
|
|
424
|
+
duration: 0.8,
|
|
425
|
+
ease: "power2.out",
|
|
426
|
+
onUpdate: () => {
|
|
427
|
+
lineLabels[i].textContent = dummy.val.toFixed(1) + "%";
|
|
428
|
+
},
|
|
429
|
+
},
|
|
430
|
+
labelTime,
|
|
431
|
+
);
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
// 11. Source Line
|
|
435
|
+
tl.to(
|
|
436
|
+
`[data-composition-id="nyt-chart"] .source`,
|
|
437
|
+
{
|
|
438
|
+
opacity: 1,
|
|
439
|
+
duration: 0.5,
|
|
440
|
+
ease: "power2.out",
|
|
441
|
+
},
|
|
442
|
+
">+0.5",
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
// Register timeline
|
|
446
|
+
window.__timelines["nyt-chart"] = tl;
|
|
447
|
+
})();
|
|
448
|
+
</script>
|
|
449
|
+
</div>
|
|
450
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=1920, height=1080" />
|
|
6
|
+
<title>NYT Graph</title>
|
|
7
|
+
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
* {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
html,
|
|
15
|
+
body {
|
|
16
|
+
margin: 0;
|
|
17
|
+
width: 1920px;
|
|
18
|
+
height: 1080px;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
background-color: #faf9f6;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<div
|
|
26
|
+
id="root"
|
|
27
|
+
data-composition-id="main"
|
|
28
|
+
data-start="0"
|
|
29
|
+
data-duration="15"
|
|
30
|
+
data-width="1920"
|
|
31
|
+
data-height="1080"
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
id="nyt-chart-comp"
|
|
35
|
+
data-composition-id="nyt-chart"
|
|
36
|
+
data-composition-src="compositions/nyt-chart.html"
|
|
37
|
+
data-start="0"
|
|
38
|
+
data-duration="15"
|
|
39
|
+
data-track-index="0"
|
|
40
|
+
data-width="1920"
|
|
41
|
+
data-height="1080"
|
|
42
|
+
></div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<script>
|
|
46
|
+
window.__timelines = window.__timelines || {};
|
|
47
|
+
const tl = gsap.timeline({ paused: true });
|
|
48
|
+
window.__timelines["main"] = tl;
|
|
49
|
+
</script>
|
|
50
|
+
</body>
|
|
51
|
+
</html>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080" width="1920" height="1080">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
4
|
+
<feDropShadow dx="0" dy="2" stdDeviation="2" flood-opacity="0.2"/>
|
|
5
|
+
</filter>
|
|
6
|
+
<g id="cursor-arrow">
|
|
7
|
+
<path d="M0 0 L 16 16 L 9.5 16 L 6.5 23 L 6.5 16 L 0 16 Z" fill="white" stroke="#000" stroke-width="1.5" stroke-linejoin="round" filter="url(#shadow)"/>
|
|
8
|
+
</g>
|
|
9
|
+
</defs>
|
|
10
|
+
|
|
11
|
+
<rect width="1920" height="1080" fill="#f0f0f0" />
|
|
12
|
+
|
|
13
|
+
<g id="cursor-designer" transform="translate(600, 500)">
|
|
14
|
+
<use href="#cursor-arrow" x="0" y="0"/>
|
|
15
|
+
<rect x="16" y="20" width="90" height="24" rx="4" fill="#A259FF"/>
|
|
16
|
+
<text x="61" y="36" font-family="Inter, sans-serif" font-size="12" fill="white" text-anchor="middle" font-weight="bold">Designer</text>
|
|
17
|
+
</g>
|
|
18
|
+
|
|
19
|
+
<g id="cursor-engineer" transform="translate(900, 400)">
|
|
20
|
+
<use href="#cursor-arrow" x="0" y="0"/>
|
|
21
|
+
<rect x="16" y="20" width="90" height="24" rx="4" fill="#1ABCFE"/>
|
|
22
|
+
<text x="61" y="36" font-family="Inter, sans-serif" font-size="12" fill="white" text-anchor="middle" font-weight="bold">Engineer</text>
|
|
23
|
+
</g>
|
|
24
|
+
|
|
25
|
+
<g id="cursor-pm" transform="translate(1200, 600)">
|
|
26
|
+
<use href="#cursor-arrow" x="0" y="0"/>
|
|
27
|
+
<rect x="16" y="20" width="50" height="24" rx="4" fill="#F24E1E"/>
|
|
28
|
+
<text x="41" y="36" font-family="Inter, sans-serif" font-size="12" fill="white" text-anchor="middle" font-weight="bold">PM</text>
|
|
29
|
+
</g>
|
|
30
|
+
</svg>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080" width="1920" height="1080">
|
|
2
|
+
<g transform="translate(880, 420)">
|
|
3
|
+
<!-- Top-left: rounded square -->
|
|
4
|
+
<path id="logo-tl" d="M 40 0 A 40 40 0 0 0 0 40 L 0 80 A 40 40 0 0 0 40 120 A 40 40 0 0 0 80 80 L 80 40 A 40 40 0 0 0 40 0 Z" fill="#F24E1E" />
|
|
5
|
+
|
|
6
|
+
<!-- Top-right: rounded square -->
|
|
7
|
+
<path id="logo-tr" d="M 120 0 A 40 40 0 0 0 80 40 L 80 80 A 40 40 0 0 0 120 120 A 40 40 0 0 0 160 80 L 160 40 A 40 40 0 0 0 120 0 Z" fill="#A259FF" />
|
|
8
|
+
|
|
9
|
+
<!-- Bottom-left: half-circle -->
|
|
10
|
+
<path id="logo-bl" d="M 0 120 A 40 120 0 0 0 80 120 Z" fill="#1ABCFE" />
|
|
11
|
+
|
|
12
|
+
<!-- Bottom-right: half-circle -->
|
|
13
|
+
<path id="logo-br" d="M 80 120 A 40 120 0 0 0 160 120 Z" fill="#0ACF83" />
|
|
14
|
+
</g>
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080" width="1920" height="1080">
|
|
2
|
+
<rect id="pill-tl" x="870" y="410" width="80" height="120" rx="40" fill="#F24E1E" />
|
|
3
|
+
<rect id="pill-tr" x="970" y="410" width="80" height="120" rx="40" fill="#A259FF" />
|
|
4
|
+
<rect id="pill-bl" x="870" y="550" width="80" height="120" rx="40" fill="#1ABCFE" />
|
|
5
|
+
<rect id="pill-br" x="970" y="550" width="80" height="120" rx="40" fill="#0ACF83" />
|
|
6
|
+
</svg>
|