@@ -142,12 +142,15 @@ export function EffectPreview({
142142 // Получаем текущее видео для использования в превью
143143 const currentVideo = getCurrentVideo ( )
144144
145- // Ленивая загрузка видео при наведении
145+ // Загрузка видео сразу (не ждем наведения)
146146 useEffect ( ( ) => {
147- if ( isHovering && ! videoSrc ) {
148- setVideoSrc ( getPreviewPath ( effect , currentVideo ) )
147+ if ( ! videoSrc ) {
148+ const path = getPreviewPath ( effect , currentVideo )
149+ if ( path ) {
150+ setVideoSrc ( path )
151+ }
149152 }
150- } , [ isHovering , effect , videoSrc , currentVideo ] )
153+ } , [ effect , videoSrc , currentVideo ] )
151154
152155 /**
153156 * Эффект для управления воспроизведением видео и применением эффектов
@@ -158,83 +161,54 @@ export function EffectPreview({
158161 if ( ! videoSrc || ! videoRef . current ) return
159162 const videoElement = videoRef . current
160163
161- /**
162- * Применяет эффект к видео и запускает его воспроизведение
163- * Устанавливает таймер для повторного воспроизведения
164- */
165- const applyEffect = ( ) => {
166- videoElement . currentTime = 0 // Сбрасываем время видео на начало
167- videoElement . style . filter = "" // Сбрасываем предыдущие фильтры
168- videoElement . style . boxShadow = "" // Сбрасываем дополнительные эффекты
169- videoElement . playbackRate = 1 // Сбрасываем скорость воспроизведения
170-
171- // Применяем CSS-фильтр на основе параметров эффекта
172- // Собираем параметры для CSS фильтра
173- const effectParams : Record < string , any > = { }
174- if ( processedEffect ?. parameters ) {
175- processedEffect . parameters . forEach ( ( param ) => {
176- effectParams [ param . id ] = param . currentValue ?? param . defaultValue
177- } )
178- }
179-
180- // Добавляем пользовательские параметры
181- Object . assign ( effectParams , customParams )
182-
183- const cssFilter = generateCSSFilterForEffect ( processedEffect || effect , effectParams )
184- if ( cssFilter ) {
185- videoElement . style . filter = cssFilter
186- }
187-
188- // Специальные эффекты, требующие дополнительных CSS-стилей
189- if (
190- processedEffect ?. id === "vignette" ||
191- ( processedEffect ?. category === "lighting" && processedEffect ?. id . includes ( "vignette" ) )
192- ) {
193- // Создаем эффект виньетки через box-shadow
194- const intensity = customParams ?. intensity ?? effectParams ?. intensity ?? 0.3
195- const radius = customParams ?. radius ?? effectParams ?. radius ?? 0.8
196- const shadowSize = Math . round ( Math . min ( width , height ) * ( 1 - radius ) * 0.5 )
197- const shadowBlur = Math . round ( shadowSize * intensity * 2 )
198- videoElement . style . boxShadow = `inset 0 0 ${ shadowBlur } px ${ shadowSize } px rgba(0,0,0,${ intensity } )`
199- } else {
200- videoElement . style . boxShadow = ""
201- }
202-
203- // Устанавливаем скорость воспроизведения
204- const playbackRate = getPlaybackRate ( processedEffect )
205- videoElement . playbackRate = playbackRate
206-
207- // Запускаем воспроизведение видео
208- videoElement . play ( ) . catch ( ( err : unknown ) => {
209- void logger . info ( "Autoplay prevented" , { error : err } )
164+ // Применяем CSS-фильтр на основе параметров эффекта
165+ const effectParams : Record < string , any > = { }
166+ if ( processedEffect ?. parameters ) {
167+ processedEffect . parameters . forEach ( ( param ) => {
168+ effectParams [ param . id ] = param . currentValue ?? param . defaultValue
210169 } )
170+ }
171+
172+ // Добавляем пользовательские параметры
173+ Object . assign ( effectParams , customParams )
211174
212- // Устанавливаем таймер для повторного воспроизведения через 2 секунды
213- timeoutRef . current = setTimeout ( ( ) => {
214- if ( isHovering ) {
215- applyEffect ( )
216- }
217- } , 2000 )
175+ const cssFilter = generateCSSFilterForEffect ( processedEffect || effect , effectParams )
176+ if ( cssFilter ) {
177+ videoElement . style . filter = cssFilter
218178 }
219179
220- // Если курсор наведен на превью - применяем эффект и запускаем видео
221- if ( isHovering ) {
222- applyEffect ( )
180+ // Специальные эффекты, требующие дополнительных CSS-стилей
181+ if (
182+ processedEffect ?. id === "vignette" ||
183+ ( processedEffect ?. category === "lighting" && processedEffect ?. id . includes ( "vignette" ) )
184+ ) {
185+ // Создаем эффект виньетки через box-shadow
186+ const intensity = customParams ?. intensity ?? effectParams ?. intensity ?? 0.3
187+ const radius = customParams ?. radius ?? effectParams ?. radius ?? 0.8
188+ const shadowSize = Math . round ( Math . min ( width , height ) * ( 1 - radius ) * 0.5 )
189+ const shadowBlur = Math . round ( shadowSize * intensity * 2 )
190+ videoElement . style . boxShadow = `inset 0 0 ${ shadowBlur } px ${ shadowSize } px rgba(0,0,0,${ intensity } )`
223191 } else {
224- // Если курсор не наведен - останавливаем видео и сбрасываем эффекты
225- videoElement . pause ( )
226- videoElement . currentTime = 0
227- videoElement . style . filter = ""
228192 videoElement . style . boxShadow = ""
229- videoElement . playbackRate = 1
230- if ( timeoutRef . current ) clearTimeout ( timeoutRef . current )
231193 }
232194
233- // Очищаем таймер при размонтировании компонента
195+ // Устанавливаем скорость воспроизведения
196+ const playbackRate = getPlaybackRate ( processedEffect )
197+ videoElement . playbackRate = playbackRate
198+
199+ // Запускаем воспроизведение в цикле
200+ videoElement . loop = true
201+ videoElement . play ( ) . catch ( ( err : unknown ) => {
202+ void logger . info ( "Autoplay prevented" , { error : err } )
203+ } )
204+
205+ // Cleanup при размонтировании
234206 return ( ) => {
235- if ( timeoutRef . current ) clearTimeout ( timeoutRef . current )
207+ videoElement . pause ( )
208+ videoElement . style . filter = ""
209+ videoElement . style . boxShadow = ""
236210 }
237- } , [ isHovering , processedEffect , width , height , customParams , videoSrc ] )
211+ } , [ processedEffect , width , height , customParams , videoSrc , effect ] )
238212
239213 return (
240214 < div className = "flex flex-col items-center" >
0 commit comments