hyperframes 0.1.1 → 0.1.2

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.
@@ -1,172 +1,223 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Swiss Grid - Hyperframes</title>
7
7
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
8
8
  <style>
9
- body, html {
10
- margin: 0;
11
- padding: 0;
12
- width: 1920px;
13
- height: 1080px;
14
- background-color: #F2F2F2;
15
- overflow: hidden;
16
- font-family: 'Helvetica', Arial, sans-serif;
17
- }
18
-
19
- #master-root {
20
- width: 1920px;
21
- height: 1080px;
22
- position: relative;
23
- }
24
-
25
- .background-grid {
26
- position: absolute;
27
- top: 0;
28
- left: 0;
29
- width: 100%;
30
- height: 100%;
31
- z-index: 0;
32
- }
33
-
34
- /* A-roll styling */
35
- #short_mag_cut_frame {
36
- position: absolute;
37
- border-radius: 8px; /* Required */
38
- z-index: 1;
39
- box-shadow: 0 20px 40px rgba(0,0,0,0.3);
40
- overflow: hidden;
41
- background: #000;
42
- }
43
-
44
- #short_mag_cut,
45
- #short_mag_cut_frame > img.__render_frame__,
46
- #short_mag_cut_frame > img.__preview_render_frame__ {
47
- position: absolute;
48
- inset: 0;
49
- width: 100%;
50
- height: 100%;
51
- object-fit: cover;
52
- object-position: center;
53
- display: block;
54
- }
55
-
56
- /* Overlay layers */
57
- .overlay-layer {
58
- position: absolute;
59
- top: 0;
60
- left: 0;
61
- width: 100%;
62
- height: 100%;
63
- pointer-events: none;
64
- }
65
-
66
- #intro-comp { z-index: 2; }
67
- #graphics-comp { z-index: 3; }
68
- #captions-comp { z-index: 4; }
9
+ body,
10
+ html {
11
+ margin: 0;
12
+ padding: 0;
13
+ width: 1920px;
14
+ height: 1080px;
15
+ background-color: #f2f2f2;
16
+ overflow: hidden;
17
+ font-family: "Helvetica", Arial, sans-serif;
18
+ }
19
+
20
+ #master-root {
21
+ width: 1920px;
22
+ height: 1080px;
23
+ position: relative;
24
+ }
25
+
26
+ .background-grid {
27
+ position: absolute;
28
+ top: 0;
29
+ left: 0;
30
+ width: 100%;
31
+ height: 100%;
32
+ z-index: 0;
33
+ }
34
+
35
+ /* A-roll styling */
36
+ #short_mag_cut_frame {
37
+ position: absolute;
38
+ border-radius: 8px; /* Required */
39
+ z-index: 1;
40
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
41
+ overflow: hidden;
42
+ background: #000;
43
+ }
44
+
45
+ #short_mag_cut,
46
+ #short_mag_cut_frame > img.__render_frame__,
47
+ #short_mag_cut_frame > img.__preview_render_frame__ {
48
+ position: absolute;
49
+ inset: 0;
50
+ width: 100%;
51
+ height: 100%;
52
+ object-fit: cover;
53
+ object-position: center;
54
+ display: block;
55
+ }
56
+
57
+ /* Overlay layers */
58
+ .overlay-layer {
59
+ position: absolute;
60
+ top: 0;
61
+ left: 0;
62
+ width: 100%;
63
+ height: 100%;
64
+ pointer-events: none;
65
+ }
66
+
67
+ #intro-comp {
68
+ z-index: 2;
69
+ }
70
+ #graphics-comp {
71
+ z-index: 3;
72
+ }
73
+ #captions-comp {
74
+ z-index: 4;
75
+ }
69
76
  </style>
70
- </head>
71
- <body>
72
- <div id="master-root" data-composition-id="master" data-width="1920" data-height="1080" data-duration="16.04">
73
-
74
- <!-- Background Grid -->
75
- <img id="bg-grid"
76
- class="background-grid"
77
- src="assets/swiss-grid.svg"
78
- alt="Grid"
79
- data-start="0"
80
- data-duration="16.04"
81
- data-track-index="0">
82
-
83
- <!-- A-roll Video -->
84
- <div id="short_mag_cut_frame">
85
- <video id="short_mag_cut"
86
- src="__VIDEO_SRC__"
87
- data-start="0"
88
- data-duration="16.04"
89
- data-track-index="1">
90
- </video>
91
- </div>
92
-
93
- <!-- Intro Sub-composition -->
94
- <div id="intro-comp"
95
- class="overlay-layer"
96
- data-composition-id="intro"
97
- data-composition-src="compositions/intro.html"
98
- data-start="0"
99
- data-duration="1.86"
100
- data-track-index="2">
101
- </div>
102
-
103
- <!-- Graphics Sub-composition -->
104
- <div id="graphics-comp"
105
- class="overlay-layer"
106
- data-composition-id="graphics"
107
- data-composition-src="compositions/graphics.html"
108
- data-start="0"
109
- data-duration="16.04"
110
- data-track-index="3">
111
- </div>
112
-
113
- <!-- Captions Sub-composition -->
114
- <div id="captions-comp"
115
- class="overlay-layer"
116
- data-composition-id="captions"
117
- data-composition-src="compositions/captions.html"
118
- data-start="0"
119
- data-duration="16.04"
120
- data-track-index="4">
121
- </div>
122
-
123
- <!-- Sound Effects -->
124
- <audio id="sfx-intro" data-start="0" data-track-index="5" data-duration="1" src=""></audio>
125
- <audio id="sfx-stat1" data-start="1.86" data-track-index="5" data-duration="1" src=""></audio>
126
- <audio id="sfx-stat2" data-start="4.68" data-track-index="5" data-duration="1" src=""></audio>
127
- <audio id="sfx-stat3" data-start="8.88" data-track-index="5" data-duration="1" src=""></audio>
128
-
129
- <script>
130
- window.__timelines = window.__timelines || {};
131
-
132
- const masterTL = gsap.timeline({ paused: true });
133
- const v = document.getElementById('short_mag_cut_frame');
134
-
135
- // --- A-ROLL MOVEMENT (Structured Swiss Layout) ---
136
-
137
- // 1. Entrance (0-1.86s): Slide in from left, settle centered for Intro
138
- masterTL.fromTo(v,
139
- { x: -1000, y: 120, width: 960, height: 840 },
140
- { x: 480, y: 120, width: 960, height: 840, duration: 0.8, ease: "power2.out" },
141
- 0
142
- );
143
-
144
- // 2. Stat 1 (1.86s - 4.68s): Move to right side (Graphic is on left)
145
- masterTL.to(v, {
146
- x: 1080, y: 120, width: 720, height: 720,
147
- duration: 0.25, ease: "expo.out"
148
- }, 1.86);
149
-
150
- // 3. Stat 2 (4.68s - 8.88s): Stay right, zoom in slightly
151
- masterTL.to(v, {
152
- x: 1080, y: 60, width: 780, height: 780,
153
- duration: 0.25, ease: "expo.out"
154
- }, 4.68);
155
-
156
- // 4. Stat 3 (8.88s - 14.2s): Move to left side (Graphic is on right)
157
- masterTL.to(v, {
158
- x: 120, y: 120, width: 720, height: 720,
159
- duration: 0.25, ease: "expo.out"
160
- }, 8.88);
161
-
162
- // 5. Conclusion (14.2s - 16.04s): Center large
163
- masterTL.to(v, {
164
- x: 240, y: 60, width: 1440, height: 810,
165
- duration: 0.5, ease: "expo.out"
166
- }, 14.2);
167
-
168
- window.__timelines["master"] = masterTL;
169
- </script>
77
+ </head>
78
+ <body>
79
+ <div
80
+ id="master-root"
81
+ data-composition-id="master"
82
+ data-width="1920"
83
+ data-height="1080"
84
+ data-duration="16.04"
85
+ >
86
+ <!-- Background Grid -->
87
+ <img
88
+ id="bg-grid"
89
+ class="background-grid"
90
+ src="assets/swiss-grid.svg"
91
+ alt="Grid"
92
+ data-start="0"
93
+ data-duration="16.04"
94
+ data-track-index="0"
95
+ />
96
+
97
+ <!-- A-roll Video -->
98
+ <div id="short_mag_cut_frame">
99
+ <video
100
+ id="short_mag_cut"
101
+ src="__VIDEO_SRC__"
102
+ data-start="0"
103
+ data-duration="16.04"
104
+ data-track-index="1"
105
+ ></video>
106
+ </div>
107
+
108
+ <!-- Intro Sub-composition -->
109
+ <div
110
+ id="intro-comp"
111
+ class="overlay-layer"
112
+ data-composition-id="intro"
113
+ data-composition-src="compositions/intro.html"
114
+ data-start="0"
115
+ data-duration="1.86"
116
+ data-track-index="2"
117
+ ></div>
118
+
119
+ <!-- Graphics Sub-composition -->
120
+ <div
121
+ id="graphics-comp"
122
+ class="overlay-layer"
123
+ data-composition-id="graphics"
124
+ data-composition-src="compositions/graphics.html"
125
+ data-start="0"
126
+ data-duration="16.04"
127
+ data-track-index="3"
128
+ ></div>
129
+
130
+ <!-- Captions Sub-composition -->
131
+ <div
132
+ id="captions-comp"
133
+ class="overlay-layer"
134
+ data-composition-id="captions"
135
+ data-composition-src="compositions/captions.html"
136
+ data-start="0"
137
+ data-duration="16.04"
138
+ data-track-index="4"
139
+ ></div>
140
+
141
+ <!-- Sound Effects -->
142
+ <audio id="sfx-intro" data-start="0" data-track-index="5" data-duration="1" src=""></audio>
143
+ <audio id="sfx-stat1" data-start="1.86" data-track-index="5" data-duration="1" src=""></audio>
144
+ <audio id="sfx-stat2" data-start="4.68" data-track-index="5" data-duration="1" src=""></audio>
145
+ <audio id="sfx-stat3" data-start="8.88" data-track-index="5" data-duration="1" src=""></audio>
146
+
147
+ <script>
148
+ window.__timelines = window.__timelines || {};
149
+
150
+ const masterTL = gsap.timeline({ paused: true });
151
+ const v = document.getElementById("short_mag_cut_frame");
152
+
153
+ // --- A-ROLL MOVEMENT (Structured Swiss Layout) ---
154
+
155
+ // 1. Entrance (0-1.86s): Slide in from left, settle centered for Intro
156
+ masterTL.fromTo(
157
+ v,
158
+ { x: -1000, y: 120, width: 960, height: 840 },
159
+ { x: 480, y: 120, width: 960, height: 840, duration: 0.8, ease: "power2.out" },
160
+ 0,
161
+ );
162
+
163
+ // 2. Stat 1 (1.86s - 4.68s): Move to right side (Graphic is on left)
164
+ masterTL.to(
165
+ v,
166
+ {
167
+ x: 1080,
168
+ y: 120,
169
+ width: 720,
170
+ height: 720,
171
+ duration: 0.25,
172
+ ease: "expo.out",
173
+ },
174
+ 1.86,
175
+ );
176
+
177
+ // 3. Stat 2 (4.68s - 8.88s): Stay right, zoom in slightly
178
+ masterTL.to(
179
+ v,
180
+ {
181
+ x: 1080,
182
+ y: 60,
183
+ width: 780,
184
+ height: 780,
185
+ duration: 0.25,
186
+ ease: "expo.out",
187
+ },
188
+ 4.68,
189
+ );
190
+
191
+ // 4. Stat 3 (8.88s - 14.2s): Move to left side (Graphic is on right)
192
+ masterTL.to(
193
+ v,
194
+ {
195
+ x: 120,
196
+ y: 120,
197
+ width: 720,
198
+ height: 720,
199
+ duration: 0.25,
200
+ ease: "expo.out",
201
+ },
202
+ 8.88,
203
+ );
204
+
205
+ // 5. Conclusion (14.2s - 16.04s): Center large
206
+ masterTL.to(
207
+ v,
208
+ {
209
+ x: 240,
210
+ y: 60,
211
+ width: 1440,
212
+ height: 810,
213
+ duration: 0.5,
214
+ ease: "expo.out",
215
+ },
216
+ 14.2,
217
+ );
218
+
219
+ window.__timelines["master"] = masterTL;
220
+ </script>
170
221
  </div>
171
- </body>
222
+ </body>
172
223
  </html>
@@ -39,9 +39,9 @@
39
39
  font-size: 64px;
40
40
  line-height: 1.1;
41
41
  color: #000000;
42
- background-color: #FFFFFF;
42
+ background-color: #ffffff;
43
43
  padding: 15px 30px;
44
- border-top: 8px solid #CC0000; /* Vignelli Red top border accent */
44
+ border-top: 8px solid #cc0000; /* Vignelli Red top border accent */
45
45
  display: inline-block;
46
46
  letter-spacing: -0.02em; /* Tight Helvetica spacing */
47
47
  white-space: nowrap; /* Prevent wrapping at the element level */
@@ -49,29 +49,77 @@
49
49
  </style>
50
50
 
51
51
  <script>
52
- (function() {
53
- const TRANSCRIPT = [{'text': 'We', 'start': 0.14, 'end': 0.239}, {'text': 'asked', 'start': 0.28, 'end': 0.459}, {'text': 'what', 'start': 0.5, 'end': 0.619}, {'text': 'you', 'start': 0.659, 'end': 0.779}, {'text': 'needed.', 'start': 0.8, 'end': 1.179}, {'text': 'Forty-seven', 'start': 1.199, 'end': 1.619}, {'text': 'percent', 'start': 1.699, 'end': 1.96}, {'text': 'of', 'start': 1.979, 'end': 2.059}, {'text': 'you', 'start': 2.099, 'end': 2.299}, {'text': 'said', 'start': 2.319, 'end': 2.499}, {'text': 'motion', 'start': 2.559, 'end': 2.839}, {'text': 'graphics,', 'start': 2.899, 'end': 3.759}, {'text': 'sixty-two', 'start': 3.799, 'end': 4.159}, {'text': 'percent', 'start': 4.239, 'end': 4.559}, {'text': 'said', 'start': 4.639, 'end': 4.799}, {'text': 'static', 'start': 4.859, 'end': 5.199}, {'text': 'content', 'start': 5.239, 'end': 5.639}, {'text': 'was', 'start': 5.679, 'end': 5.779}, {'text': 'costing', 'start': 5.859, 'end': 6.219}, {'text': 'you', 'start': 6.259, 'end': 6.339}, {'text': 'attention,', 'start': 6.379, 'end': 7.299}, {'text': 'and', 'start': 7.319, 'end': 7.439}, {'text': 'three', 'start': 7.48, 'end': 7.599}, {'text': 'out', 'start': 7.679, 'end': 7.779}, {'text': 'of', 'start': 7.799, 'end': 7.879}, {'text': 'four', 'start': 7.94, 'end': 8.139}, {'text': 'said', 'start': 8.279, 'end': 8.46}, {'text': 'you', 'start': 8.519, 'end': 8.6}, {'text': 'know', 'start': 8.619, 'end': 8.739}, {'text': 'the', 'start': 8.8, 'end': 8.88}, {'text': 'look', 'start': 8.92, 'end': 9.079}, {'text': 'you', 'start': 9.119, 'end': 9.259}, {'text': 'want', 'start': 9.279, 'end': 9.619}, {'text': 'but', 'start': 9.779, 'end': 9.88}, {'text': "don't", 'start': 9.92, 'end': 10.1}, {'text': 'have', 'start': 10.159, 'end': 10.3}, {'text': 'the', 'start': 10.3, 'end': 10.42}, {'text': 'editing', 'start': 10.5, 'end': 10.779}, {'text': 'skills', 'start': 10.86, 'end': 11.139}, {'text': 'to', 'start': 11.159, 'end': 11.239}, {'text': 'get', 'start': 11.279, 'end': 11.439}, {'text': 'there.', 'start': 11.46, 'end': 12.239}, {'text': 'So', 'start': 12.3, 'end': 12.38}, {'text': 'we', 'start': 12.399, 'end': 12.519}, {'text': 'built', 'start': 12.539, 'end': 12.759}, {'text': 'Hyperframes', 'start': 12.84, 'end': 13.119}];
52
+ (function () {
53
+ const TRANSCRIPT = [
54
+ { text: "We", start: 0.14, end: 0.239 },
55
+ { text: "asked", start: 0.28, end: 0.459 },
56
+ { text: "what", start: 0.5, end: 0.619 },
57
+ { text: "you", start: 0.659, end: 0.779 },
58
+ { text: "needed.", start: 0.8, end: 1.179 },
59
+ { text: "Forty-seven", start: 1.199, end: 1.619 },
60
+ { text: "percent", start: 1.699, end: 1.96 },
61
+ { text: "of", start: 1.979, end: 2.059 },
62
+ { text: "you", start: 2.099, end: 2.299 },
63
+ { text: "said", start: 2.319, end: 2.499 },
64
+ { text: "motion", start: 2.559, end: 2.839 },
65
+ { text: "graphics,", start: 2.899, end: 3.759 },
66
+ { text: "sixty-two", start: 3.799, end: 4.159 },
67
+ { text: "percent", start: 4.239, end: 4.559 },
68
+ { text: "said", start: 4.639, end: 4.799 },
69
+ { text: "static", start: 4.859, end: 5.199 },
70
+ { text: "content", start: 5.239, end: 5.639 },
71
+ { text: "was", start: 5.679, end: 5.779 },
72
+ { text: "costing", start: 5.859, end: 6.219 },
73
+ { text: "you", start: 6.259, end: 6.339 },
74
+ { text: "attention,", start: 6.379, end: 7.299 },
75
+ { text: "and", start: 7.319, end: 7.439 },
76
+ { text: "three", start: 7.48, end: 7.599 },
77
+ { text: "out", start: 7.679, end: 7.779 },
78
+ { text: "of", start: 7.799, end: 7.879 },
79
+ { text: "four", start: 7.94, end: 8.139 },
80
+ { text: "said", start: 8.279, end: 8.46 },
81
+ { text: "you", start: 8.519, end: 8.6 },
82
+ { text: "know", start: 8.619, end: 8.739 },
83
+ { text: "the", start: 8.8, end: 8.88 },
84
+ { text: "look", start: 8.92, end: 9.079 },
85
+ { text: "you", start: 9.119, end: 9.259 },
86
+ { text: "want", start: 9.279, end: 9.619 },
87
+ { text: "but", start: 9.779, end: 9.88 },
88
+ { text: "don't", start: 9.92, end: 10.1 },
89
+ { text: "have", start: 10.159, end: 10.3 },
90
+ { text: "the", start: 10.3, end: 10.42 },
91
+ { text: "editing", start: 10.5, end: 10.779 },
92
+ { text: "skills", start: 10.86, end: 11.139 },
93
+ { text: "to", start: 11.159, end: 11.239 },
94
+ { text: "get", start: 11.279, end: 11.439 },
95
+ { text: "there.", start: 11.46, end: 12.239 },
96
+ { text: "So", start: 12.3, end: 12.38 },
97
+ { text: "we", start: 12.399, end: 12.519 },
98
+ { text: "built", start: 12.539, end: 12.759 },
99
+ { text: "Hyperframes", start: 12.84, end: 13.119 },
100
+ ];
54
101
  const tl = gsap.timeline({ paused: true });
55
- const container = document.getElementById('captions-container');
102
+ const container = document.getElementById("captions-container");
56
103
 
57
104
  // Group words into single lines (max words or based on pauses/sentence ends)
58
105
  function groupTranscript(transcript, maxWords = 3) {
59
106
  const groups = [];
60
107
  let currentGroup = [];
61
-
108
+
62
109
  transcript.forEach((word, index) => {
63
110
  currentGroup.push(word);
64
-
111
+
65
112
  const nextWord = transcript[index + 1];
66
- const isPause = nextWord && (nextWord.start - word.end > 0.15);
67
- const isSentenceEnd = word.text.includes('.') || word.text.includes('?') || word.text.includes('!');
68
-
113
+ const isPause = nextWord && nextWord.start - word.end > 0.15;
114
+ const isSentenceEnd =
115
+ word.text.includes(".") || word.text.includes("?") || word.text.includes("!");
116
+
69
117
  if (currentGroup.length >= maxWords || isPause || isSentenceEnd || !nextWord) {
70
118
  groups.push({
71
119
  words: currentGroup,
72
120
  start: currentGroup[0].start,
73
121
  end: currentGroup[currentGroup.length - 1].end,
74
- text: currentGroup.map(w => w.text).join(' ')
122
+ text: currentGroup.map((w) => w.text).join(" "),
75
123
  });
76
124
  currentGroup = [];
77
125
  }
@@ -82,37 +130,42 @@
82
130
  const captionGroups = groupTranscript(TRANSCRIPT);
83
131
 
84
132
  captionGroups.forEach((group, index) => {
85
- const div = document.createElement('div');
86
- div.className = 'caption-group';
133
+ const div = document.createElement("div");
134
+ div.className = "caption-group";
87
135
  div.id = `group-${index}`;
88
-
89
- const textSpan = document.createElement('span');
90
- textSpan.className = 'caption-text';
136
+
137
+ const textSpan = document.createElement("span");
138
+ textSpan.className = "caption-text";
91
139
  textSpan.innerText = group.text;
92
-
140
+
93
141
  div.appendChild(textSpan);
94
142
  container.appendChild(div);
95
143
 
96
144
  // Animation: Modern "expo.out" transitions
97
145
  // Entrance
98
- tl.fromTo(div,
146
+ tl.fromTo(
147
+ div,
99
148
  { opacity: 0, y: 20 },
100
149
  {
101
150
  opacity: 1,
102
151
  y: 0,
103
152
  duration: 0.4,
104
- ease: "expo.out"
105
- },
106
- group.start
153
+ ease: "expo.out",
154
+ },
155
+ group.start,
107
156
  );
108
157
 
109
158
  // Exit
110
- tl.to(div, {
111
- opacity: 0,
112
- y: -10,
113
- duration: 0.3,
114
- ease: "expo.out"
115
- }, group.end - 0.3);
159
+ tl.to(
160
+ div,
161
+ {
162
+ opacity: 0,
163
+ y: -10,
164
+ duration: 0.3,
165
+ ease: "expo.out",
166
+ },
167
+ group.end - 0.3,
168
+ );
116
169
  });
117
170
 
118
171
  window.__timelines["captions"] = tl;