hyperframes 0.1.0

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.
Files changed (34) hide show
  1. package/dist/cli.js +22905 -0
  2. package/dist/docs/compositions.md +26 -0
  3. package/dist/docs/data-attributes.md +22 -0
  4. package/dist/docs/gsap.md +23 -0
  5. package/dist/docs/rendering.md +23 -0
  6. package/dist/docs/templates.md +15 -0
  7. package/dist/docs/troubleshooting.md +22 -0
  8. package/dist/hyperframe-runtime.js +12 -0
  9. package/dist/studio/assets/index-B1830ANq.js +78 -0
  10. package/dist/studio/assets/index-KoBceNoU.css +1 -0
  11. package/dist/studio/icons/timeline/audio.svg +7 -0
  12. package/dist/studio/icons/timeline/captions.svg +5 -0
  13. package/dist/studio/icons/timeline/composition.svg +12 -0
  14. package/dist/studio/icons/timeline/image.svg +18 -0
  15. package/dist/studio/icons/timeline/music.svg +10 -0
  16. package/dist/studio/icons/timeline/text.svg +3 -0
  17. package/dist/studio/index.html +13 -0
  18. package/dist/templates/play-mode/compositions/captions.html +97 -0
  19. package/dist/templates/play-mode/compositions/intro.html +88 -0
  20. package/dist/templates/play-mode/compositions/stats.html +252 -0
  21. package/dist/templates/play-mode/index.html +173 -0
  22. package/dist/templates/swiss-grid/assets/swiss-grid.svg +116 -0
  23. package/dist/templates/swiss-grid/compositions/captions.html +95 -0
  24. package/dist/templates/swiss-grid/compositions/graphics.html +198 -0
  25. package/dist/templates/swiss-grid/compositions/intro.html +114 -0
  26. package/dist/templates/swiss-grid/index.html +172 -0
  27. package/dist/templates/vignelli/compositions/captions.html +122 -0
  28. package/dist/templates/vignelli/compositions/overlays.html +271 -0
  29. package/dist/templates/vignelli/index.html +171 -0
  30. package/dist/templates/warm-grain/compositions/captions.html +133 -0
  31. package/dist/templates/warm-grain/compositions/graphics.html +157 -0
  32. package/dist/templates/warm-grain/compositions/intro.html +77 -0
  33. package/dist/templates/warm-grain/index.html +195 -0
  34. package/package.json +54 -0
@@ -0,0 +1,173 @@
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>Hyperframes - Play Mode</title>
7
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
8
+ <style>
9
+ body, html {
10
+ margin: 0;
11
+ padding: 0;
12
+ width: 1920px;
13
+ height: 1080px;
14
+ overflow: hidden;
15
+ background-color: #FFFFFF;
16
+ font-family: 'Nunito', sans-serif;
17
+ }
18
+
19
+ #main-composition {
20
+ width: 1920px;
21
+ height: 1080px;
22
+ position: relative;
23
+ }
24
+
25
+ #bg-comp,
26
+ #aroll-comp,
27
+ #intro-comp,
28
+ #stats-comp,
29
+ #captions-comp {
30
+ position: absolute;
31
+ top: 0;
32
+ left: 0;
33
+ width: 100%;
34
+ height: 100%;
35
+ }
36
+
37
+ #bg-comp {
38
+ z-index: 1;
39
+ }
40
+
41
+ #aroll-comp {
42
+ z-index: 10;
43
+ }
44
+
45
+ #intro-comp {
46
+ z-index: 100;
47
+ }
48
+
49
+ #stats-comp {
50
+ z-index: 150;
51
+ }
52
+
53
+ #captions-comp {
54
+ z-index: 200;
55
+ }
56
+
57
+ #aroll-container {
58
+ position: absolute;
59
+ width: 100%;
60
+ height: 100%;
61
+ display: flex;
62
+ justify-content: center;
63
+ align-items: center;
64
+ z-index: 0;
65
+ }
66
+
67
+ #short_mag_cut {
68
+ border-radius: 16px;
69
+ box-shadow: 0 20px 60px rgba(0,0,0,0.4);
70
+ border: 8px solid #FFFFFF;
71
+ }
72
+
73
+ #background-layer {
74
+ position: absolute;
75
+ top: 0;
76
+ left: 0;
77
+ width: 100%;
78
+ height: 100%;
79
+ background-color: #FFFFFF;
80
+ z-index: 0;
81
+ }
82
+ </style>
83
+ <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap" rel="stylesheet">
84
+ </head>
85
+ <body>
86
+ <div id="main-composition" data-composition-id="main-video" data-start="0" data-duration="16.04" data-width="1920" data-height="1080">
87
+ <!-- Background Layer Composition -->
88
+ <div id="bg-comp" data-composition-id="background" data-start="0" data-duration="16.04" data-width="1920" data-height="1080" data-track-index="1">
89
+ <div id="background-layer"></div>
90
+ <style>
91
+ #background-layer {
92
+ position: absolute;
93
+ top: 0;
94
+ left: 0;
95
+ width: 100%;
96
+ height: 100%;
97
+ background-color: #FFFFFF;
98
+ }
99
+ </style>
100
+ <script>
101
+ (function() {
102
+ const tl = gsap.timeline({ paused: true });
103
+ const bg = document.getElementById('background-layer');
104
+ // Sync with A-roll framing 3 (4.659s)
105
+ tl.to(bg, { backgroundColor: "#0057FF", duration: 0.5 }, 4.659);
106
+ // Sync with A-roll framing 4 (8.88s)
107
+ tl.to(bg, { backgroundColor: "#FFFFFF", duration: 0.5 }, 8.88);
108
+ window.__timelines["background"] = tl;
109
+ })();
110
+ </script>
111
+ </div>
112
+
113
+ <!-- A-roll Layer Composition -->
114
+ <div id="aroll-comp" data-composition-id="aroll-layer" data-start="0" data-duration="16.04" data-width="1920" data-height="1080" data-track-index="10">
115
+ <div id="aroll-container">
116
+ <video id="short_mag_cut"
117
+ src="__VIDEO_SRC__"
118
+ data-start="0"
119
+ data-duration="16.04"
120
+ data-track-index="1"
121
+ style="width: 100%; height: auto;"></video>
122
+ </div>
123
+ <style>
124
+ #aroll-container {
125
+ position: absolute;
126
+ width: 100%;
127
+ height: 100%;
128
+ display: flex;
129
+ justify-content: center;
130
+ align-items: center;
131
+ }
132
+ #short_mag_cut {
133
+ border-radius: 16px;
134
+ box-shadow: 0 20px 60px rgba(0,0,0,0.4);
135
+ border: 8px solid #FFFFFF;
136
+ }
137
+ </style>
138
+ <script>
139
+ (function() {
140
+ const tl = gsap.timeline({ paused: true });
141
+ const container = document.getElementById('aroll-container');
142
+ gsap.set(container, { y: -1100, scale: 0.8 });
143
+ tl.to(container, { y: 0, duration: 1.2, ease: "elastic.out(1, 0.6)" }, 0);
144
+ tl.to(container, { scale: 1.4, x: -300, duration: 1, ease: "back.out(1.7)" }, 1.839);
145
+ tl.to(container, { scale: 0.7, x: 400, duration: 1, ease: "back.out(1.7)" }, 4.659);
146
+ tl.to(container, { scale: 0.9, x: 0, duration: 1, ease: "back.out(1.7)" }, 8.88);
147
+ window.__timelines["aroll-layer"] = tl;
148
+ })();
149
+ </script>
150
+ </div>
151
+
152
+ <!-- Compositions -->
153
+ <div id="intro-comp" data-composition-id="intro" data-composition-src="compositions/intro.html" data-start="0" data-duration="16.04" data-width="1920" data-height="1080" data-track-index="100"></div>
154
+ <div id="captions-comp" data-composition-id="captions" data-composition-src="compositions/captions.html" data-start="0" data-duration="16.04" data-width="1920" data-height="1080" data-track-index="200"></div>
155
+ <div id="stats-comp" data-composition-id="stats" data-composition-src="compositions/stats.html" data-start="0" data-duration="16.04" data-width="1920" data-height="1080" data-track-index="150"></div>
156
+
157
+ <!-- Audio Clips -->
158
+ <audio id="sfx-bounce-0" src="" data-start="0" data-track-index="5"></audio>
159
+ <audio id="sfx-whoosh-1" src="" data-start="1.839" data-track-index="6"></audio>
160
+ <audio id="sfx-pop-1" src="" data-start="2.039" data-track-index="7"></audio>
161
+ <audio id="sfx-whoosh-2" src="" data-start="4.659" data-track-index="6"></audio>
162
+ <audio id="sfx-pop-2" src="" data-start="4.859" data-track-index="7"></audio>
163
+ <audio id="sfx-whoosh-3" src="" data-start="8.88" data-track-index="6"></audio>
164
+ <audio id="sfx-pop-3" src="" data-start="9.08" data-track-index="7"></audio>
165
+
166
+ <script>
167
+ window.__timelines = window.__timelines || {};
168
+ const tl = gsap.timeline({ paused: true });
169
+ window.__timelines["main-video"] = tl;
170
+ </script>
171
+ </div>
172
+ </body>
173
+ </html>
@@ -0,0 +1,116 @@
1
+ <svg viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="1920" height="1080" fill="#F2F2F2" />
3
+
4
+ <g id="thin-grid-lines" stroke="#0A1E3D" stroke-width="1" opacity="0.1">
5
+ <line id="v-thin-1" x1="60" y1="0" x2="60" y2="1080" />
6
+ <line id="v-thin-2" x1="120" y1="0" x2="120" y2="1080" />
7
+ <line id="v-thin-3" x1="180" y1="0" x2="180" y2="1080" />
8
+ <line id="v-thin-5" x1="300" y1="0" x2="300" y2="1080" />
9
+ <line id="v-thin-6" x1="360" y1="0" x2="360" y2="1080" />
10
+ <line id="v-thin-7" x1="420" y1="0" x2="420" y2="1080" />
11
+ <line id="v-thin-9" x1="540" y1="0" x2="540" y2="1080" />
12
+ <line id="v-thin-10" x1="600" y1="0" x2="600" y2="1080" />
13
+ <line id="v-thin-11" x1="660" y1="0" x2="660" y2="1080" />
14
+ <line id="v-thin-13" x1="780" y1="0" x2="780" y2="1080" />
15
+ <line id="v-thin-14" x1="840" y1="0" x2="840" y2="1080" />
16
+ <line id="v-thin-15" x1="900" y1="0" x2="900" y2="1080" />
17
+ <line id="v-thin-17" x1="1020" y1="0" x2="1020" y2="1080" />
18
+ <line id="v-thin-18" x1="1080" y1="0" x2="1080" y2="1080" />
19
+ <line id="v-thin-19" x1="1140" y1="0" x2="1140" y2="1080" />
20
+ <line id="v-thin-21" x1="1260" y1="0" x2="1260" y2="1080" />
21
+ <line id="v-thin-22" x1="1320" y1="0" x2="1320" y2="1080" />
22
+ <line id="v-thin-23" x1="1380" y1="0" x2="1380" y2="1080" />
23
+ <line id="v-thin-25" x1="1500" y1="0" x2="1500" y2="1080" />
24
+ <line id="v-thin-26" x1="1560" y1="0" x2="1560" y2="1080" />
25
+ <line id="v-thin-27" x1="1620" y1="0" x2="1620" y2="1080" />
26
+ <line id="v-thin-29" x1="1740" y1="0" x2="1740" y2="1080" />
27
+ <line id="v-thin-30" x1="1800" y1="0" x2="1800" y2="1080" />
28
+ <line id="v-thin-31" x1="1860" y1="0" x2="1860" y2="1080" />
29
+ <line id="h-thin-1" x1="0" y1="60" x2="1920" y2="60" />
30
+ <line id="h-thin-2" x1="0" y1="120" x2="1920" y2="120" />
31
+ <line id="h-thin-3" x1="0" y1="180" x2="1920" y2="180" />
32
+ <line id="h-thin-5" x1="0" y1="300" x2="1920" y2="300" />
33
+ <line id="h-thin-6" x1="0" y1="360" x2="1920" y2="360" />
34
+ <line id="h-thin-7" x1="0" y1="420" x2="1920" y2="420" />
35
+ <line id="h-thin-9" x1="0" y1="540" x2="1920" y2="540" />
36
+ <line id="h-thin-10" x1="0" y1="600" x2="1920" y2="600" />
37
+ <line id="h-thin-11" x1="0" y1="660" x2="1920" y2="660" />
38
+ <line id="h-thin-13" x1="0" y1="780" x2="1920" y2="780" />
39
+ <line id="h-thin-14" x1="0" y1="840" x2="1920" y2="840" />
40
+ <line id="h-thin-15" x1="0" y1="900" x2="1920" y2="900" />
41
+ <line id="h-thin-17" x1="0" y1="1020" x2="1920" y2="1020" />
42
+ </g>
43
+
44
+ <g id="thick-grid-lines" stroke="#0A1E3D" stroke-width="3" opacity="0.2">
45
+ <line id="v-thick-1" x1="240" y1="0" x2="240" y2="1080" />
46
+ <line id="v-thick-2" x1="480" y1="0" x2="480" y2="1080" />
47
+ <line id="v-thick-3" x1="720" y1="0" x2="720" y2="1080" />
48
+ <line id="v-thick-4" x1="960" y1="0" x2="960" y2="1080" />
49
+ <line id="v-thick-5" x1="1200" y1="0" x2="1200" y2="1080" />
50
+ <line id="v-thick-6" x1="1440" y1="0" x2="1440" y2="1080" />
51
+ <line id="v-thick-7" x1="1680" y1="0" x2="1680" y2="1080" />
52
+ <line id="h-thick-1" x1="0" y1="240" x2="1920" y2="240" />
53
+ <line id="h-thick-2" x1="0" y1="480" x2="1920" y2="480" />
54
+ <line id="h-thick-3" x1="0" y1="720" x2="1920" y2="720" />
55
+ <line id="h-thick-4" x1="0" y1="960" x2="1920" y2="960" />
56
+ </g>
57
+
58
+ <g id="intersections" stroke="#0A1E3D" stroke-width="2" opacity="0.3">
59
+ <line x1="230" y1="240" x2="250" y2="240" />
60
+ <line x1="240" y1="230" x2="240" y2="250" />
61
+ <line x1="230" y1="480" x2="250" y2="480" />
62
+ <line x1="240" y1="470" x2="240" y2="490" />
63
+ <line x1="230" y1="720" x2="250" y2="720" />
64
+ <line x1="240" y1="710" x2="240" y2="730" />
65
+ <line x1="230" y1="960" x2="250" y2="960" />
66
+ <line x1="240" y1="950" x2="240" y2="970" />
67
+ <line x1="470" y1="240" x2="490" y2="240" />
68
+ <line x1="480" y1="230" x2="480" y2="250" />
69
+ <line x1="470" y1="480" x2="490" y2="480" />
70
+ <line x1="480" y1="470" x2="480" y2="490" />
71
+ <line x1="470" y1="720" x2="490" y2="720" />
72
+ <line x1="480" y1="710" x2="480" y2="730" />
73
+ <line x1="470" y1="960" x2="490" y2="960" />
74
+ <line x1="480" y1="950" x2="480" y2="970" />
75
+ <line x1="710" y1="240" x2="730" y2="240" />
76
+ <line x1="720" y1="230" x2="720" y2="250" />
77
+ <line x1="710" y1="480" x2="730" y2="480" />
78
+ <line x1="720" y1="470" x2="720" y2="490" />
79
+ <line x1="710" y1="720" x2="730" y2="720" />
80
+ <line x1="720" y1="710" x2="720" y2="730" />
81
+ <line x1="710" y1="960" x2="730" y2="960" />
82
+ <line x1="720" y1="950" x2="720" y2="970" />
83
+ <line x1="950" y1="240" x2="970" y2="240" />
84
+ <line x1="960" y1="230" x2="960" y2="250" />
85
+ <line x1="950" y1="480" x2="970" y2="480" />
86
+ <line x1="960" y1="470" x2="960" y2="490" />
87
+ <line x1="950" y1="720" x2="970" y2="720" />
88
+ <line x1="960" y1="710" x2="960" y2="730" />
89
+ <line x1="950" y1="960" x2="970" y2="960" />
90
+ <line x1="960" y1="950" x2="960" y2="970" />
91
+ <line x1="1190" y1="240" x2="1210" y2="240" />
92
+ <line x1="1200" y1="230" x2="1200" y2="250" />
93
+ <line x1="1190" y1="480" x2="1210" y2="480" />
94
+ <line x1="1200" y1="470" x2="1200" y2="490" />
95
+ <line x1="1190" y1="720" x2="1210" y2="720" />
96
+ <line x1="1200" y1="710" x2="1200" y2="730" />
97
+ <line x1="1190" y1="960" x2="1210" y2="960" />
98
+ <line x1="1200" y1="950" x2="1200" y2="970" />
99
+ <line x1="1430" y1="240" x2="1450" y2="240" />
100
+ <line x1="1440" y1="230" x2="1440" y2="250" />
101
+ <line x1="1430" y1="480" x2="1450" y2="480" />
102
+ <line x1="1440" y1="470" x2="1440" y2="490" />
103
+ <line x1="1430" y1="720" x2="1450" y2="720" />
104
+ <line x1="1440" y1="710" x2="1440" y2="730" />
105
+ <line x1="1430" y1="960" x2="1450" y2="960" />
106
+ <line x1="1440" y1="950" x2="1440" y2="970" />
107
+ <line x1="1670" y1="240" x2="1690" y2="240" />
108
+ <line x1="1680" y1="230" x2="1680" y2="250" />
109
+ <line x1="1670" y1="480" x2="1690" y2="480" />
110
+ <line x1="1680" y1="470" x2="1680" y2="490" />
111
+ <line x1="1670" y1="720" x2="1690" y2="720" />
112
+ <line x1="1680" y1="710" x2="1680" y2="730" />
113
+ <line x1="1670" y1="960" x2="1690" y2="960" />
114
+ <line x1="1680" y1="950" x2="1680" y2="970" />
115
+ </g>
116
+ </svg>
@@ -0,0 +1,95 @@
1
+ <template id="captions-template">
2
+ <div data-composition-id="captions" data-width="1920" data-height="1080" data-duration="16.04">
3
+ <div id="caption-container"></div>
4
+
5
+ <style>
6
+ [data-composition-id="captions"] {
7
+ width: 1920px;
8
+ height: 1080px;
9
+ position: relative;
10
+ font-family: 'Helvetica', 'Arial', sans-serif;
11
+ font-weight: bold;
12
+ overflow: hidden;
13
+ }
14
+
15
+ [data-composition-id="captions"] #caption-container {
16
+ position: absolute;
17
+ bottom: 120px; /* Consistent bottom positioning */
18
+ left: 50%;
19
+ transform: translateX(-50%);
20
+ display: flex;
21
+ justify-content: center;
22
+ align-items: center;
23
+ width: 100%;
24
+ }
25
+
26
+ [data-composition-id="captions"] .caption-box {
27
+ background-color: #0A1E3D; /* Solid navy */
28
+ padding: 20px 40px;
29
+ display: none; /* Hidden by default, shown via GSAP */
30
+ justify-content: center;
31
+ align-items: center;
32
+ /* Swiss Grid: sharp corners, solid block */
33
+ }
34
+
35
+ [data-composition-id="captions"] .caption-text {
36
+ color: #F2F2F2; /* Off-white */
37
+ font-size: 72px;
38
+ text-transform: uppercase; /* Swiss style often uses uppercase for impact */
39
+ letter-spacing: -2px;
40
+ line-height: 1;
41
+ white-space: nowrap;
42
+ text-align: center;
43
+ }
44
+ </style>
45
+
46
+ <script>
47
+ (function() {
48
+ const TRANSCRIPT = [{'text': 'We', 'start': 0.119, 'end': 0.259}, {'text': 'asked', 'start': 0.319, 'end': 0.479}, {'text': 'what', 'start': 0.519, 'end': 0.659}, {'text': 'you', 'start': 0.699, 'end': 0.819}, {'text': 'needed.', 'start': 0.859, 'end': 1.819}, {'text': 'Forty-seven', 'start': 1.86, 'end': 2.299}, {'text': 'percent', 'start': 2.399, 'end': 2.679}, {'text': 'of', 'start': 2.7, 'end': 2.799}, {'text': 'you', 'start': 2.839, 'end': 2.939}, {'text': 'said', 'start': 3.039, 'end': 3.179}, {'text': 'motion', 'start': 3.24, 'end': 3.559}, {'text': 'graphics,', 'start': 3.579, 'end': 4.599}, {'text': 'sixty-two', 'start': 4.679, 'end': 5.179}, {'text': 'percent', 'start': 5.299, 'end': 5.759}, {'text': 'said', 'start': 5.859, 'end': 5.98}, {'text': 'static', 'start': 6.079, 'end': 6.399}, {'text': 'content', 'start': 6.46, 'end': 6.879}, {'text': 'was', 'start': 6.92, 'end': 7.079}, {'text': 'costing', 'start': 7.099, 'end': 7.48}, {'text': 'you', 'start': 7.5, 'end': 7.579}, {'text': 'attention,', 'start': 7.679, 'end': 8.659}, {'text': 'and', 'start': 8.699, 'end': 8.86}, {'text': 'three', 'start': 8.88, 'end': 9.06}, {'text': 'out', 'start': 9.079, 'end': 9.18}, {'text': 'of', 'start': 9.199, 'end': 9.34}, {'text': 'four', 'start': 9.38, 'end': 9.799}, {'text': 'said', 'start': 9.84, 'end': 10.0}, {'text': 'you', 'start': 10.019, 'end': 10.159}, {'text': 'know', 'start': 10.179, 'end': 10.36}, {'text': 'the', 'start': 10.38, 'end': 10.42}, {'text': 'look', 'start': 10.519, 'end': 10.699}, {'text': 'you', 'start': 10.739, 'end': 10.859}, {'text': 'want', 'start': 10.98, 'end': 11.34}, {'text': 'but', 'start': 11.359, 'end': 11.52}, {'text': "don't", 'start': 11.56, 'end': 11.779}, {'text': 'have', 'start': 11.819, 'end': 11.94}, {'text': 'the', 'start': 11.96, 'end': 12.06}, {'text': 'editing', 'start': 12.079, 'end': 12.4}, {'text': 'skills', 'start': 12.52, 'end': 12.86}, {'text': 'to', 'start': 12.88, 'end': 13.0}, {'text': 'get', 'start': 13.019, 'end': 13.18}, {'text': 'there.', 'start': 13.22, 'end': 14.22}, {'text': 'So', 'start': 14.239, 'end': 14.399}, {'text': 'we', 'start': 14.42, 'end': 14.52}, {'text': 'built', 'start': 14.619, 'end': 14.88}, {'text': 'Hyperframes', 'start': 15.079, 'end': 15.42}];
49
+ const container = document.getElementById('caption-container');
50
+ const tl = gsap.timeline({ paused: true });
51
+
52
+ if (!TRANSCRIPT || TRANSCRIPT.length === 0) {
53
+ window.__timelines["captions"] = tl;
54
+ return;
55
+ }
56
+
57
+ // Group transcript into max 5 words per group
58
+ const groups = [];
59
+ let currentGroup = [];
60
+
61
+ TRANSCRIPT.forEach((word, index) => {
62
+ currentGroup.push(word);
63
+ // Group by 5 words OR if it's the last word
64
+ if (currentGroup.length === 5 || index === TRANSCRIPT.length - 1) {
65
+ groups.push([...currentGroup]);
66
+ currentGroup = [];
67
+ }
68
+ });
69
+
70
+ // Create DOM elements and timeline for each group
71
+ groups.forEach((group, i) => {
72
+ const box = document.createElement('div');
73
+ box.className = 'caption-box';
74
+ box.id = `group-${i}`;
75
+
76
+ const text = document.createElement('div');
77
+ text.className = 'caption-text';
78
+ text.textContent = group.map(w => w.text).join(' ');
79
+
80
+ box.appendChild(text);
81
+ container.appendChild(box);
82
+
83
+ const startTime = group[0].start;
84
+ const endTime = group[group.length - 1].end;
85
+
86
+ // Hard cut animation (no fades) as requested
87
+ tl.set(box, { display: 'flex' }, startTime);
88
+ tl.set(box, { display: 'none' }, endTime);
89
+ });
90
+
91
+ window.__timelines["captions"] = tl;
92
+ })();
93
+ </script>
94
+ </div>
95
+ </template>
@@ -0,0 +1,198 @@
1
+ <template id="graphics-template">
2
+ <div data-composition-id="graphics" data-width="1920" data-height="1080" data-duration="15">
3
+ <div class="grid-container">
4
+ <!-- Stat 1: 47% -->
5
+ <div id="stat1" class="stat-group">
6
+ <div class="stat-value">47%</div>
7
+ <div class="stat-label">NEED MOTION GRAPHICS</div>
8
+ </div>
9
+
10
+ <!-- Stat 2: 62% -->
11
+ <div id="stat2" class="stat-group">
12
+ <div class="stat-value">62%</div>
13
+ <div class="stat-label">LOSING ATTENTION</div>
14
+ <div class="progress-container">
15
+ <div class="progress-bar"></div>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- Stat 3: 3 OF 4 -->
20
+ <div id="stat3" class="stat-group">
21
+ <div class="stat-value">3 OF 4</div>
22
+ <div class="stat-label">LACK EDITING SKILLS</div>
23
+ <div class="grid-blocks">
24
+ <div class="block gold"></div>
25
+ <div class="block gold"></div>
26
+ <div class="block gold"></div>
27
+ <div class="block navy"></div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+
32
+ <style>
33
+ [data-composition-id="graphics"] {
34
+ font-family: 'Helvetica', Arial, sans-serif;
35
+ color: #0A1E3D;
36
+ background: transparent;
37
+ width: 1920px;
38
+ height: 1080px;
39
+ position: relative;
40
+ overflow: hidden;
41
+ }
42
+
43
+ [data-composition-id="graphics"] .grid-container {
44
+ display: grid;
45
+ grid-template-columns: repeat(12, 1fr);
46
+ grid-template-rows: repeat(12, 1fr);
47
+ width: 100%;
48
+ height: 100%;
49
+ padding: 80px;
50
+ gap: 20px;
51
+ }
52
+
53
+ [data-composition-id="graphics"] .stat-group {
54
+ opacity: 0;
55
+ display: flex;
56
+ flex-direction: column;
57
+ justify-content: flex-start;
58
+ align-items: flex-start;
59
+ background: #F2F2F2;
60
+ padding: 40px;
61
+ border-left: 10px solid #D4A017;
62
+ box-shadow: 20px 20px 0px rgba(10, 30, 61, 0.1);
63
+ }
64
+
65
+ /* Positioning Stats on Grid - Adjusted for A-roll structure */
66
+ [data-composition-id="graphics"] #stat1 {
67
+ grid-column: 2 / 6;
68
+ grid-row: 3 / 7;
69
+ }
70
+
71
+ [data-composition-id="graphics"] #stat2 {
72
+ grid-column: 2 / 6;
73
+ grid-row: 3 / 7;
74
+ }
75
+
76
+ [data-composition-id="graphics"] #stat3 {
77
+ grid-column: 7 / 12;
78
+ grid-row: 3 / 7;
79
+ }
80
+
81
+ [data-composition-id="graphics"] .stat-value {
82
+ font-size: 140px;
83
+ font-weight: 900;
84
+ color: #D4A017;
85
+ line-height: 0.8;
86
+ margin-bottom: 15px;
87
+ }
88
+
89
+ [data-composition-id="graphics"] .stat-label {
90
+ font-size: 24px;
91
+ font-weight: 300; /* Lighter weight */
92
+ color: #0A1E3D;
93
+ letter-spacing: 2px;
94
+ text-transform: uppercase;
95
+ }
96
+
97
+ /* Progress Bar for Stat 2 */
98
+ [data-composition-id="graphics"] .progress-container {
99
+ width: 100%;
100
+ height: 24px;
101
+ background: #E0E0E0;
102
+ margin-top: 30px;
103
+ border: 2px solid #0A1E3D;
104
+ position: relative;
105
+ }
106
+
107
+ [data-composition-id="graphics"] .progress-bar {
108
+ width: 0%;
109
+ height: 100%;
110
+ background: #D4A017;
111
+ }
112
+
113
+ /* Grid Blocks for Stat 3 */
114
+ [data-composition-id="graphics"] .grid-blocks {
115
+ display: flex;
116
+ gap: 20px;
117
+ margin-top: 30px;
118
+ }
119
+
120
+ [data-composition-id="graphics"] .block {
121
+ width: 80px;
122
+ height: 80px;
123
+ border: 3px solid #0A1E3D;
124
+ }
125
+
126
+ [data-composition-id="graphics"] .block.gold {
127
+ background: #D4A017;
128
+ }
129
+
130
+ [data-composition-id="graphics"] .block.navy {
131
+ background: #0A1E3D;
132
+ }
133
+ </style>
134
+
135
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
136
+ <script>
137
+ (function() {
138
+ const tl = gsap.timeline({ paused: true });
139
+
140
+ // Timing Constants
141
+ const S1_START = 1.86;
142
+ const S1_END = 4.5;
143
+ const S2_START = 4.68;
144
+ const S2_END = 8.6;
145
+ const S3_START = 8.88;
146
+ const S3_END = 14.2;
147
+
148
+ const SLIDE_DUR = 0.25; // 250ms
149
+ const SHARP_EASE = "power2.out";
150
+
151
+ // Stat 1 Animation
152
+ tl.fromTo('#stat1',
153
+ { x: -200, opacity: 0 },
154
+ { x: 0, opacity: 1, duration: SLIDE_DUR, ease: SHARP_EASE },
155
+ S1_START
156
+ );
157
+ tl.to('#stat1',
158
+ { x: 200, opacity: 0, duration: SLIDE_DUR, ease: "power2.in" },
159
+ S1_END - SLIDE_DUR
160
+ );
161
+
162
+ // Stat 2 Animation
163
+ tl.fromTo('#stat2',
164
+ { y: 200, opacity: 0 },
165
+ { y: 0, opacity: 1, duration: SLIDE_DUR, ease: SHARP_EASE },
166
+ S2_START
167
+ );
168
+ // Progress bar fill
169
+ tl.to('#stat2 .progress-bar',
170
+ { width: '62%', duration: S2_END - S2_START - (SLIDE_DUR * 2), ease: "none" },
171
+ S2_START + SLIDE_DUR
172
+ );
173
+ tl.to('#stat2',
174
+ { y: -200, opacity: 0, duration: SLIDE_DUR, ease: "power2.in" },
175
+ S2_END - SLIDE_DUR
176
+ );
177
+
178
+ // Stat 3 Animation
179
+ tl.fromTo('#stat3',
180
+ { x: 200, opacity: 0 },
181
+ { x: 0, opacity: 1, duration: SLIDE_DUR, ease: SHARP_EASE },
182
+ S3_START
183
+ );
184
+ // Stagger blocks
185
+ tl.from('#stat3 .block',
186
+ { scale: 0, duration: 0.3, stagger: 0.1, ease: "back.out(1.7)" },
187
+ S3_START + SLIDE_DUR
188
+ );
189
+ tl.to('#stat3',
190
+ { x: -200, opacity: 0, duration: SLIDE_DUR, ease: "power2.in" },
191
+ S3_END - SLIDE_DUR
192
+ );
193
+
194
+ window.__timelines["graphics"] = tl;
195
+ })();
196
+ </script>
197
+ </div>
198
+ </template>