hyperframes 0.1.0 → 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,88 +1,106 @@
1
1
  <template id="intro-template">
2
- <div id="intro-comp" data-composition-id="intro" data-start="0" data-duration="16.04" data-width="1920" data-height="1080">
3
- <div class="intro-container">
4
- <h1 class="title">HYPERFRAMES</h1>
5
- </div>
2
+ <div
3
+ id="intro-comp"
4
+ data-composition-id="intro"
5
+ data-start="0"
6
+ data-duration="16.04"
7
+ data-width="1920"
8
+ data-height="1080"
9
+ >
10
+ <div class="intro-container">
11
+ <h1 class="title">HYPERFRAMES</h1>
12
+ </div>
6
13
 
7
- <style>
8
- @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap');
14
+ <style>
15
+ @import url("https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap");
9
16
 
10
- [data-composition-id="intro"] .intro-container {
11
- width: 100%;
12
- height: 100%;
13
- display: flex;
14
- justify-content: center;
15
- align-items: center;
16
- pointer-events: none;
17
- }
17
+ [data-composition-id="intro"] .intro-container {
18
+ width: 100%;
19
+ height: 100%;
20
+ display: flex;
21
+ justify-content: center;
22
+ align-items: center;
23
+ pointer-events: none;
24
+ }
18
25
 
19
- [data-composition-id="intro"] .title {
20
- font-family: 'Nunito', sans-serif;
21
- font-weight: 900;
22
- font-size: 180px;
23
- color: #FF2D8A; /* Hot Pink */
24
- text-transform: uppercase;
25
- transform: rotate(-5deg); /* Tilted 5 degrees */
26
- margin: 0;
27
- padding: 20px;
28
- /* Layered offset shadow for depth without suffocating letterforms */
29
- filter: drop-shadow(8px 8px 0 #FFFFFF) drop-shadow(15px 15px 0 rgba(0,0,0,0.1));
30
- opacity: 0;
31
- scale: 0;
32
- }
33
- </style>
26
+ [data-composition-id="intro"] .title {
27
+ font-family: "Nunito", sans-serif;
28
+ font-weight: 900;
29
+ font-size: 180px;
30
+ color: #ff2d8a; /* Hot Pink */
31
+ text-transform: uppercase;
32
+ transform: rotate(-5deg); /* Tilted 5 degrees */
33
+ margin: 0;
34
+ padding: 20px;
35
+ /* Layered offset shadow for depth without suffocating letterforms */
36
+ filter: drop-shadow(8px 8px 0 #ffffff) drop-shadow(15px 15px 0 rgba(0, 0, 0, 0.1));
37
+ opacity: 0;
38
+ scale: 0;
39
+ }
40
+ </style>
34
41
 
35
- <script>
36
- (function() {
37
- const tl = gsap.timeline({ paused: true });
38
-
39
- // --- INTRO SEQUENCE ---
40
- // Animation: Scale-up bounce (0% to 110% to 100%) with elastic overshoot
41
- // Starts at 0.5s, lasts until 3s
42
- tl.to('[data-composition-id="intro"] .title', {
43
- opacity: 1,
44
- scale: 1.1,
45
- duration: 0.6,
46
- ease: "back.out(1.7)",
47
- delay: 0.5
48
- })
42
+ <script>
43
+ (function () {
44
+ const tl = gsap.timeline({ paused: true });
45
+
46
+ // --- INTRO SEQUENCE ---
47
+ // Animation: Scale-up bounce (0% to 110% to 100%) with elastic overshoot
48
+ // Starts at 0.5s, lasts until 3s
49
+ tl.to('[data-composition-id="intro"] .title', {
50
+ opacity: 1,
51
+ scale: 1.1,
52
+ duration: 0.6,
53
+ ease: "back.out(1.7)",
54
+ delay: 0.5,
55
+ })
49
56
  .to('[data-composition-id="intro"] .title', {
50
57
  scale: 1,
51
58
  duration: 0.4,
52
- ease: "elastic.out(1, 0.3)"
59
+ ease: "elastic.out(1, 0.3)",
53
60
  })
54
61
  // Ambient motion
55
- .to('[data-composition-id="intro"] .title', {
56
- rotation: "-3deg",
57
- duration: 1,
58
- repeat: 1,
59
- yoyo: true,
60
- ease: "sine.inOut"
61
- }, "-=0.5")
62
+ .to(
63
+ '[data-composition-id="intro"] .title',
64
+ {
65
+ rotation: "-3deg",
66
+ duration: 1,
67
+ repeat: 1,
68
+ yoyo: true,
69
+ ease: "sine.inOut",
70
+ },
71
+ "-=0.5",
72
+ )
62
73
  // Exit intro
63
- .to('[data-composition-id="intro"] .title', {
64
- opacity: 0,
65
- scale: 0.5,
66
- duration: 0.3,
67
- ease: "power2.in"
68
- }, 1.4);
74
+ .to(
75
+ '[data-composition-id="intro"] .title',
76
+ {
77
+ opacity: 0,
78
+ scale: 0.5,
79
+ duration: 0.3,
80
+ ease: "power2.in",
81
+ },
82
+ 1.4,
83
+ );
69
84
 
70
- // --- END CARD SEQUENCE ---
71
- // Appears at 14.619s (after Moment 3 finishes exiting at 14.239 + 0.3)
72
- tl.to('[data-composition-id="intro"] .title', {
85
+ // --- END CARD SEQUENCE ---
86
+ // Appears at 14.619s (after Moment 3 finishes exiting at 14.239 + 0.3)
87
+ tl.to(
88
+ '[data-composition-id="intro"] .title',
89
+ {
73
90
  opacity: 1,
74
91
  scale: 1.1,
75
92
  duration: 0.6,
76
- ease: "back.out(1.7)"
77
- }, 14.619)
78
- .to('[data-composition-id="intro"] .title', {
79
- scale: 1,
80
- duration: 0.4,
81
- ease: "elastic.out(1, 0.3)"
82
- });
93
+ ease: "back.out(1.7)",
94
+ },
95
+ 14.619,
96
+ ).to('[data-composition-id="intro"] .title', {
97
+ scale: 1,
98
+ duration: 0.4,
99
+ ease: "elastic.out(1, 0.3)",
100
+ });
83
101
 
84
- window.__timelines["intro"] = tl;
85
- })();
86
- </script>
87
- </div>
102
+ window.__timelines["intro"] = tl;
103
+ })();
104
+ </script>
105
+ </div>
88
106
  </template>
@@ -2,7 +2,7 @@
2
2
  <div data-composition-id="stats" data-width="1920" data-height="1080" data-duration="16.04">
3
3
  <div id="stats-container">
4
4
  <!-- Moment 1: 47% NEED MOTION GRAPHICS -->
5
- <div id="moment-1" class="moment" style="opacity: 0; transform: scale(0) rotate(8deg);">
5
+ <div id="moment-1" class="moment" style="opacity: 0; transform: scale(0) rotate(8deg)">
6
6
  <div class="sticker-stack">
7
7
  <div class="sticker-bg blue-bg"></div>
8
8
  <div class="sticker-content white-bg blue-border">
@@ -11,12 +11,18 @@
11
11
  </div>
12
12
  </div>
13
13
  <!-- Decorative shapes -->
14
- <div class="shape circle pink-bg" style="top: -40px; left: -40px; width: 80px; height: 80px;"></div>
15
- <div class="shape pill lime-bg" style="bottom: -30px; right: -50px; width: 120px; height: 40px; transform: rotate(-15deg);"></div>
14
+ <div
15
+ class="shape circle pink-bg"
16
+ style="top: -40px; left: -40px; width: 80px; height: 80px"
17
+ ></div>
18
+ <div
19
+ class="shape pill lime-bg"
20
+ style="bottom: -30px; right: -50px; width: 120px; height: 40px; transform: rotate(-15deg)"
21
+ ></div>
16
22
  </div>
17
23
 
18
24
  <!-- Moment 2: 62% STRUGGLE WITH STATIC CONTENT -->
19
- <div id="moment-2" class="moment" style="opacity: 0; transform: scale(0) rotate(-5deg);">
25
+ <div id="moment-2" class="moment" style="opacity: 0; transform: scale(0) rotate(-5deg)">
20
26
  <div class="sticker-stack">
21
27
  <div class="sticker-bg white-bg"></div>
22
28
  <div class="sticker-content blue-bg white-border">
@@ -25,12 +31,24 @@
25
31
  </div>
26
32
  </div>
27
33
  <!-- Decorative shapes -->
28
- <div class="shape blob yellow-bg" style="top: -50px; right: -30px; width: 100px; height: 100px; border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%;"></div>
29
- <div class="shape circle pink-bg" style="bottom: -20px; left: -40px; width: 60px; height: 60px;"></div>
34
+ <div
35
+ class="shape blob yellow-bg"
36
+ style="
37
+ top: -50px;
38
+ right: -30px;
39
+ width: 100px;
40
+ height: 100px;
41
+ border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%;
42
+ "
43
+ ></div>
44
+ <div
45
+ class="shape circle pink-bg"
46
+ style="bottom: -20px; left: -40px; width: 60px; height: 60px"
47
+ ></div>
30
48
  </div>
31
49
 
32
50
  <!-- Moment 3: 75% LACK EDITING SKILLS -->
33
- <div id="moment-3" class="moment" style="opacity: 0; transform: scale(0) rotate(3deg);">
51
+ <div id="moment-3" class="moment" style="opacity: 0; transform: scale(0) rotate(3deg)">
34
52
  <div class="sticker-stack">
35
53
  <div class="sticker-bg pink-bg"></div>
36
54
  <div class="sticker-content white-bg pink-border">
@@ -39,8 +57,20 @@
39
57
  </div>
40
58
  </div>
41
59
  <!-- Decorative shapes -->
42
- <div class="shape pill blue-bg" style="top: -30px; left: 50%; transform: translateX(-50%) rotate(5deg); width: 150px; height: 45px;"></div>
43
- <div class="shape circle yellow-bg" style="bottom: -40px; right: -20px; width: 90px; height: 90px;"></div>
60
+ <div
61
+ class="shape pill blue-bg"
62
+ style="
63
+ top: -30px;
64
+ left: 50%;
65
+ transform: translateX(-50%) rotate(5deg);
66
+ width: 150px;
67
+ height: 45px;
68
+ "
69
+ ></div>
70
+ <div
71
+ class="shape circle yellow-bg"
72
+ style="bottom: -40px; right: -20px; width: 90px; height: 90px"
73
+ ></div>
44
74
  </div>
45
75
  </div>
46
76
 
@@ -49,7 +79,7 @@
49
79
  width: 1920px;
50
80
  height: 1080px;
51
81
  position: relative;
52
- font-family: 'Nunito', sans-serif;
82
+ font-family: "Nunito", sans-serif;
53
83
  overflow: hidden;
54
84
  }
55
85
 
@@ -120,19 +150,41 @@
120
150
  }
121
151
 
122
152
  /* Colors */
123
- [data-composition-id="stats"] .blue-bg { background-color: #0057FF; }
124
- [data-composition-id="stats"] .pink-bg { background-color: #FF2D8A; }
125
- [data-composition-id="stats"] .lime-bg { background-color: #7FFF00; }
126
- [data-composition-id="stats"] .yellow-bg { background-color: #FFE500; }
127
- [data-composition-id="stats"] .white-bg { background-color: #FFFFFF; }
153
+ [data-composition-id="stats"] .blue-bg {
154
+ background-color: #0057ff;
155
+ }
156
+ [data-composition-id="stats"] .pink-bg {
157
+ background-color: #ff2d8a;
158
+ }
159
+ [data-composition-id="stats"] .lime-bg {
160
+ background-color: #7fff00;
161
+ }
162
+ [data-composition-id="stats"] .yellow-bg {
163
+ background-color: #ffe500;
164
+ }
165
+ [data-composition-id="stats"] .white-bg {
166
+ background-color: #ffffff;
167
+ }
128
168
 
129
- [data-composition-id="stats"] .blue-text { color: #0057FF; }
130
- [data-composition-id="stats"] .white-text { color: #FFFFFF; }
131
- [data-composition-id="stats"] .pink-text { color: #FF2D8A; }
169
+ [data-composition-id="stats"] .blue-text {
170
+ color: #0057ff;
171
+ }
172
+ [data-composition-id="stats"] .white-text {
173
+ color: #ffffff;
174
+ }
175
+ [data-composition-id="stats"] .pink-text {
176
+ color: #ff2d8a;
177
+ }
132
178
 
133
- [data-composition-id="stats"] .blue-border { border-color: #0057FF; }
134
- [data-composition-id="stats"] .white-border { border-color: #FFFFFF; }
135
- [data-composition-id="stats"] .pink-border { border-color: #FF2D8A; }
179
+ [data-composition-id="stats"] .blue-border {
180
+ border-color: #0057ff;
181
+ }
182
+ [data-composition-id="stats"] .white-border {
183
+ border-color: #ffffff;
184
+ }
185
+ [data-composition-id="stats"] .pink-border {
186
+ border-color: #ff2d8a;
187
+ }
136
188
 
137
189
  /* Typography */
138
190
  [data-composition-id="stats"] .stat-number {
@@ -161,14 +213,64 @@
161
213
  </style>
162
214
 
163
215
  <script>
164
- (function() {
165
- 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.839, '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.639}, {'text': 'Sixty-two', 'start': 4.659, 'end': 5.179}, {'text': 'percent', 'start': 5.299, 'end': 5.759}, {'text': 'said', 'start': 5.859, 'end': 5.98}, {'text': 'static', 'start': 6.099, '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.479}, {'text': 'look', 'start': 10.52, '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}];
216
+ (function () {
217
+ const TRANSCRIPT = [
218
+ { text: "We", start: 0.119, end: 0.259 },
219
+ { text: "asked", start: 0.319, end: 0.479 },
220
+ { text: "what", start: 0.519, end: 0.659 },
221
+ { text: "you", start: 0.699, end: 0.819 },
222
+ { text: "needed.", start: 0.859, end: 1.819 },
223
+ { text: "Forty-seven", start: 1.839, end: 2.299 },
224
+ { text: "percent", start: 2.399, end: 2.679 },
225
+ { text: "of", start: 2.7, end: 2.799 },
226
+ { text: "you", start: 2.839, end: 2.939 },
227
+ { text: "said", start: 3.039, end: 3.179 },
228
+ { text: "motion", start: 3.24, end: 3.559 },
229
+ { text: "graphics.", start: 3.579, end: 4.639 },
230
+ { text: "Sixty-two", start: 4.659, end: 5.179 },
231
+ { text: "percent", start: 5.299, end: 5.759 },
232
+ { text: "said", start: 5.859, end: 5.98 },
233
+ { text: "static", start: 6.099, end: 6.399 },
234
+ { text: "content", start: 6.46, end: 6.879 },
235
+ { text: "was", start: 6.92, end: 7.079 },
236
+ { text: "costing", start: 7.099, end: 7.48 },
237
+ { text: "you", start: 7.5, end: 7.579 },
238
+ { text: "attention,", start: 7.679, end: 8.659 },
239
+ { text: "and", start: 8.699, end: 8.86 },
240
+ { text: "three", start: 8.88, end: 9.06 },
241
+ { text: "out", start: 9.079, end: 9.18 },
242
+ { text: "of", start: 9.199, end: 9.34 },
243
+ { text: "four", start: 9.38, end: 9.799 },
244
+ { text: "said", start: 9.84, end: 10.0 },
245
+ { text: "you", start: 10.019, end: 10.159 },
246
+ { text: "know", start: 10.179, end: 10.36 },
247
+ { text: "the", start: 10.38, end: 10.479 },
248
+ { text: "look", start: 10.52, end: 10.699 },
249
+ { text: "you", start: 10.739, end: 10.859 },
250
+ { text: "want", start: 10.98, end: 11.34 },
251
+ { text: "but", start: 11.359, end: 11.52 },
252
+ { text: "don't", start: 11.56, end: 11.779 },
253
+ { text: "have", start: 11.819, end: 11.94 },
254
+ { text: "the", start: 11.96, end: 12.06 },
255
+ { text: "editing", start: 12.079, end: 12.4 },
256
+ { text: "skills", start: 12.52, end: 12.86 },
257
+ { text: "to", start: 12.88, end: 13.0 },
258
+ { text: "get", start: 13.019, end: 13.18 },
259
+ { text: "there.", start: 13.22, end: 14.22 },
260
+ { text: "So", start: 14.239, end: 14.399 },
261
+ { text: "we", start: 14.42, end: 14.52 },
262
+ { text: "built", start: 14.619, end: 14.88 },
263
+ { text: "Hyperframes", start: 15.079, end: 15.42 },
264
+ ];
166
265
  const tl = gsap.timeline({ paused: true });
167
266
 
168
267
  // Helper to find word timing
169
268
  function getWordTime(wordText) {
170
- const word = TRANSCRIPT.find(w =>
171
- w.text.toLowerCase().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").startsWith(wordText.toLowerCase())
269
+ const word = TRANSCRIPT.find((w) =>
270
+ w.text
271
+ .toLowerCase()
272
+ .replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "")
273
+ .startsWith(wordText.toLowerCase()),
172
274
  );
173
275
  return word ? word.start : null;
174
276
  }
@@ -179,69 +281,97 @@
179
281
  const t3 = getWordTime("three") || 8.88;
180
282
 
181
283
  // Moment 1 Animation (approx 5s)
182
- tl.to('#moment-1', {
183
- opacity: 1,
184
- scale: 1,
185
- duration: 0.8,
186
- ease: "elastic.out(1, 0.6)",
187
- onStart: () => gsap.set('#moment-1', { transformOrigin: "center center" })
188
- }, t1);
284
+ tl.to(
285
+ "#moment-1",
286
+ {
287
+ opacity: 1,
288
+ scale: 1,
289
+ duration: 0.8,
290
+ ease: "elastic.out(1, 0.6)",
291
+ onStart: () => gsap.set("#moment-1", { transformOrigin: "center center" }),
292
+ },
293
+ t1,
294
+ );
189
295
 
190
296
  // Moment 1 Exit (before Moment 2)
191
- tl.to('#moment-1', {
192
- opacity: 0,
193
- scale: 0.5,
194
- duration: 0.3,
195
- ease: "back.in(1.7)"
196
- }, t2 - 0.4);
297
+ tl.to(
298
+ "#moment-1",
299
+ {
300
+ opacity: 0,
301
+ scale: 0.5,
302
+ duration: 0.3,
303
+ ease: "back.in(1.7)",
304
+ },
305
+ t2 - 0.4,
306
+ );
197
307
 
198
308
  // Moment 2 Animation (approx 9s)
199
- tl.to('#moment-2', {
200
- opacity: 1,
201
- scale: 1,
202
- duration: 0.8,
203
- ease: "elastic.out(1, 0.6)",
204
- onStart: () => gsap.set('#moment-2', { transformOrigin: "center center" })
205
- }, t2);
309
+ tl.to(
310
+ "#moment-2",
311
+ {
312
+ opacity: 1,
313
+ scale: 1,
314
+ duration: 0.8,
315
+ ease: "elastic.out(1, 0.6)",
316
+ onStart: () => gsap.set("#moment-2", { transformOrigin: "center center" }),
317
+ },
318
+ t2,
319
+ );
206
320
 
207
321
  // Moment 2 Exit (before Moment 3)
208
- tl.to('#moment-2', {
209
- opacity: 0,
210
- scale: 0.5,
211
- duration: 0.3,
212
- ease: "back.in(1.7)"
213
- }, t3 - 0.4);
322
+ tl.to(
323
+ "#moment-2",
324
+ {
325
+ opacity: 0,
326
+ scale: 0.5,
327
+ duration: 0.3,
328
+ ease: "back.in(1.7)",
329
+ },
330
+ t3 - 0.4,
331
+ );
214
332
 
215
333
  // Moment 3 Animation (approx 13s)
216
- tl.to('#moment-3', {
217
- opacity: 1,
218
- scale: 1,
219
- duration: 0.8,
220
- ease: "elastic.out(1, 0.6)",
221
- onStart: () => gsap.set('#moment-3', { transformOrigin: "center center" })
222
- }, t3);
334
+ tl.to(
335
+ "#moment-3",
336
+ {
337
+ opacity: 1,
338
+ scale: 1,
339
+ duration: 0.8,
340
+ ease: "elastic.out(1, 0.6)",
341
+ onStart: () => gsap.set("#moment-3", { transformOrigin: "center center" }),
342
+ },
343
+ t3,
344
+ );
223
345
 
224
346
  // Moment 3 Exit: 3 words before 'Hyperframes'
225
347
  // 'Editor' is at 15.079. 3 words before is 'So' at 14.239.
226
- tl.to('#moment-3', {
227
- opacity: 0,
228
- scale: 0.5,
229
- duration: 0.3,
230
- ease: "back.in(1.7)"
231
- }, 14.239);
348
+ tl.to(
349
+ "#moment-3",
350
+ {
351
+ opacity: 0,
352
+ scale: 0.5,
353
+ duration: 0.3,
354
+ ease: "back.in(1.7)",
355
+ },
356
+ 14.239,
357
+ );
232
358
 
233
359
  // Ambient Motion (Finite)
234
360
  const totalDuration = 16.04;
235
- gsap.utils.toArray('.shape').forEach((shape, i) => {
236
- const stepDuration = 2 + (i * 0.2);
361
+ gsap.utils.toArray(".shape").forEach((shape, i) => {
362
+ const stepDuration = 2 + i * 0.2;
237
363
  const steps = Math.ceil(totalDuration / stepDuration);
238
- for(let s = 0; s < steps; s++) {
239
- tl.to(shape, {
240
- y: (s % 2 === 0 ? 15 : -15),
241
- rotation: (s % 2 === 0 ? 5 : -5),
242
- duration: stepDuration,
243
- ease: "sine.inOut"
244
- }, s * stepDuration);
364
+ for (let s = 0; s < steps; s++) {
365
+ tl.to(
366
+ shape,
367
+ {
368
+ y: s % 2 === 0 ? 15 : -15,
369
+ rotation: s % 2 === 0 ? 5 : -5,
370
+ duration: stepDuration,
371
+ ease: "sine.inOut",
372
+ },
373
+ s * stepDuration,
374
+ );
245
375
  }
246
376
  });
247
377