@@ -111,6 +111,12 @@ export default function AnimationControl({
111111 } ,
112112 } ;
113113
114+ // Маска области видимости текста NOW PLAYING — совпадает с "окном" между полосами
115+ const maskVariants : { [ key : string ] : Variant } = {
116+ idle : { top : 0 , bottom : 0 } ,
117+ compress : { top : "50%" , bottom : "50%" } ,
118+ } ;
119+
114120 // Варианты для children
115121 const bezierEase = cubicBezier ( 0.25 , 0.46 , 0.45 , 0.94 ) ;
116122
@@ -181,61 +187,79 @@ export default function AnimationControl({
181187 transition = { { duration : 0.6 , ease : bezierEase } }
182188 />
183189
184- { /* NOW PLAYING текст */ }
185- < AnimatePresence
186- mode = "wait"
187- onExitComplete = { ( ) => {
188- if ( animationStage === "nowPlayingExit" ) {
189- handleAnimationComplete ( "nowPlayingExit" ) ;
190- }
190+ { /* NOW PLAYING текст с маской по окну между красными полосами */ }
191+ < motion . div
192+ style = { {
193+ position : "absolute" ,
194+ left : "2vw" ,
195+ right : "2vw" ,
196+ zIndex : 6 ,
197+ overflow : "hidden" ,
198+ pointerEvents : "none" ,
191199 } }
200+ variants = { maskVariants }
201+ initial = "idle"
202+ animate = {
203+ animationStage === "compressIn" || animationStage === "compressInFinal"
204+ ? "compress"
205+ : "idle"
206+ }
207+ transition = { { duration : 0.6 , ease : bezierEase } }
192208 >
193- { animationStage === "nowPlaying" && (
194- < motion . div
195- key = { `now-playing-${ nowPlayingCount } ` }
196- style = { {
197- position : "fixed" ,
198- top : 0 ,
199- left : 0 ,
200- right : 0 ,
201- bottom : 0 ,
202- display : "flex" ,
203- alignItems : "center" ,
204- justifyContent : "center" ,
205- zIndex : 5 ,
206- pointerEvents : "none" ,
207- } }
208- variants = { nowPlayingVariants }
209- initial = "hidden"
210- animate = "visible"
211- exit = "exit"
212- onAnimationComplete = { definition => {
213- if ( definition === "visible" ) {
214- if ( nowPlayingCount < 1 ) {
215- setTimeout ( ( ) => setNowPlayingCount ( prev => prev + 1 ) , 200 ) ;
216- } else {
217- // Запускаем выход NOW PLAYING, после onExitComplete начнётся второй цикл полос
218- setAnimationStage ( "nowPlayingExit" ) ;
219- }
220- }
221- } }
222- >
223- < motion . span
209+ < AnimatePresence
210+ mode = "wait"
211+ onExitComplete = { ( ) => {
212+ if ( animationStage === "nowPlayingExit" ) {
213+ handleAnimationComplete ( "nowPlayingExit" ) ;
214+ }
215+ } }
216+ >
217+ { animationStage === "nowPlaying" && (
218+ < motion . div
219+ key = { `now-playing-${ nowPlayingCount } ` }
224220 style = { {
225- fontSize : "clamp(2rem, 8vw, 12rem)" ,
226- fontWeight : "bold" ,
227- color : "#fff" ,
228- fontFamily : "Arial, sans-serif" ,
229- letterSpacing : "0.2em" ,
230- textAlign : "center" ,
231- padding : "0 20px" ,
221+ position : "absolute" ,
222+ top : 0 ,
223+ left : 0 ,
224+ right : 0 ,
225+ bottom : 0 ,
226+ display : "flex" ,
227+ alignItems : "center" ,
228+ justifyContent : "center" ,
229+ pointerEvents : "none" ,
230+ } }
231+ variants = { nowPlayingVariants }
232+ initial = "hidden"
233+ animate = "visible"
234+ exit = "exit"
235+ onAnimationComplete = { definition => {
236+ if ( definition === "visible" ) {
237+ if ( nowPlayingCount < 2 ) {
238+ setTimeout ( ( ) => setNowPlayingCount ( prev => prev + 1 ) , 200 ) ;
239+ } else {
240+ // Запускаем выход NOW PLAYING, после onExitComplete начнётся второй цикл полос
241+ setAnimationStage ( "nowPlayingExit" ) ;
242+ }
243+ }
232244 } }
233245 >
234- NOW PLAYING
235- </ motion . span >
236- </ motion . div >
237- ) }
238- </ AnimatePresence >
246+ < motion . span
247+ style = { {
248+ fontSize : "clamp(2rem, 8vw, 12rem)" ,
249+ fontWeight : "bold" ,
250+ color : "#fff" ,
251+ fontFamily : "Arial, sans-serif" ,
252+ letterSpacing : "0.2em" ,
253+ textAlign : "center" ,
254+ padding : "0 20px" ,
255+ } }
256+ >
257+ NOW PLAYING
258+ </ motion . span >
259+ </ motion . div >
260+ ) }
261+ </ AnimatePresence >
262+ </ motion . div >
239263
240264 { /* Контент между полосами */ }
241265 < motion . div
0 commit comments