|
50 | 50 | let phase = 'phase1'; |
51 | 51 | let cutsceneDone = false; |
52 | 52 | let cutsceneSkipBound = false; |
53 | | - let phase3ReadyToEnter = false; |
54 | | - |
55 | 53 | function playVideo(video) { |
56 | 54 | video.currentTime = 0; |
57 | 55 | const promise = video.play(); |
|
87 | 85 | }); |
88 | 86 | } |
89 | 87 |
|
90 | | - function holdPhase3EndFrame(from) { |
91 | | - phase = 'awaiting-entry'; |
92 | | - phase3ReadyToEnter = true; |
93 | | - hidePrompt(); |
94 | | - requestAnimationFrame(() => { |
95 | | - v3.style.opacity = '1'; |
96 | | - if (from) { |
97 | | - v3.addEventListener('transitionend', () => { |
98 | | - from.style.opacity = '0'; |
99 | | - }, { once: true }); |
100 | | - } |
101 | | - }); |
102 | | - |
103 | | - const seekToEndFrame = () => { |
104 | | - const safeDuration = Number.isFinite(v3.duration) ? v3.duration : 0; |
105 | | - const endFrameTime = safeDuration > 0.08 ? safeDuration - 0.05 : Math.max(safeDuration, 0); |
106 | | - v3.currentTime = endFrameTime; |
107 | | - v3.pause(); |
108 | | - }; |
109 | | - |
110 | | - if (v3.readyState >= HTMLMediaElement.HAVE_METADATA) { |
111 | | - seekToEndFrame(); |
112 | | - } else { |
113 | | - v3.addEventListener('loadedmetadata', seekToEndFrame, { once: true }); |
114 | | - v3.load(); |
115 | | - } |
116 | | - } |
117 | | - |
118 | 88 | function goToPhase3() { |
119 | | - if (phase === 'phase3' || phase === 'awaiting-entry' || phase === 'done') return; |
| 89 | + if (phase === 'phase3' || phase === 'done') return; |
120 | 90 | const from = phase === 'loop' ? v2 : v1; |
121 | | - phase3ReadyToEnter = false; |
| 91 | + phase = 'phase3'; |
122 | 92 | v2.loop = false; |
123 | 93 | v2.pause(); |
124 | | - holdPhase3EndFrame(from); |
| 94 | + hidePrompt(); |
| 95 | + show(v3, from); |
125 | 96 | } |
126 | 97 |
|
127 | 98 | function enterWebsite() { |
128 | 99 | if (cutsceneDone) return; |
129 | 100 | cutsceneDone = true; |
130 | 101 | phase = 'done'; |
131 | | - phase3ReadyToEnter = false; |
132 | 102 | unbindCutsceneSkip(); |
133 | 103 | hidePrompt(); |
134 | 104 |
|
|
181 | 151 | if (e.type === 'keydown' && e.code !== 'Space' && e.code !== 'Enter') return; |
182 | 152 | if (e.type !== 'keydown' && !isTouchDevice) return; |
183 | 153 | if (e.cancelable) e.preventDefault(); |
184 | | - if (phase === 'phase1' || phase === 'loop') { |
185 | | - goToPhase3(); |
186 | | - return; |
187 | | - } |
188 | | - if (phase === 'awaiting-entry' && phase3ReadyToEnter) { |
189 | | - enterWebsite(); |
190 | | - } |
| 154 | + if (phase === 'phase1' || phase === 'loop') goToPhase3(); |
191 | 155 | } |
192 | 156 |
|
193 | 157 | function bindCutsceneSkip() { |
|
209 | 173 | phase = 'loop'; |
210 | 174 | show(v2, v1); |
211 | 175 | setTimeout(() => { |
212 | | - setPrompt('PRESS SPACE / TAP TO SKIP'); |
| 176 | + if (phase === 'loop') { |
| 177 | + setPrompt('PRESS SPACE / TAP TO INSERT COIN'); |
| 178 | + } |
213 | 179 | }, 4000); |
214 | 180 | }, { once: true }); |
215 | 181 |
|
|
231 | 197 | v1.addEventListener('canplay', () => playVideo(v1), { once: true }); |
232 | 198 | } |
233 | 199 |
|
| 200 | + v3.addEventListener('ended', () => { |
| 201 | + enterWebsite(); |
| 202 | + }, { once: true }); |
| 203 | + |
234 | 204 | }); |
235 | 205 | })(); |
0 commit comments