44import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
55import styled , { ThemeProvider , useTheme } from 'styled-components' ;
66
7- import { DEFAULT_MAPBOX_API_URL , NO_MAP_ID , EMPTY_MAPBOX_STYLE } from '@kepler.gl/constants' ;
7+ import { DEFAULT_MAPBOX_API_URL , NO_MAP_ID , EMPTY_MAPBOX_STYLE , MapSplitMode } from '@kepler.gl/constants' ;
88import { FormattedMessage } from '@kepler.gl/localization' ;
99import { Viewport , ExportVideo , Effect } from '@kepler.gl/types' ;
1010import {
@@ -30,6 +30,7 @@ import {
3030 getAnimatableFilters
3131} from './hubble-utils' ;
3232import { useFogHeightAnimation } from './fog-height-animation' ;
33+ import { SwipeExportVideoPanelContainer } from './swipe-export-video-container' ;
3334
3435type HubbleModule = {
3536 ExportVideoPanelContainer : React . ComponentType < any > ;
@@ -184,6 +185,9 @@ export type VideoConfiguration = {
184185 fileName ?: string ;
185186 resolution ?: string ;
186187 durationMs ?: number ;
188+ swipeStartPct ?: number ;
189+ swipeEndPct ?: number ;
190+ swipeEasing ?: 'linear' | 'ease-in-out' ;
187191} ;
188192
189193export interface ExportVideoModalProps {
@@ -311,8 +315,13 @@ const ExportVideoModalFactory = () => {
311315 ...exportVideo
312316 } ) ;
313317 const onUpdateVideoConfiguration = useCallback (
314- ( values : VideoConfiguration ) => setVideoConfiguration ( prev => ( { ...prev , ...values } ) ) ,
315- [ ]
318+ ( values : VideoConfiguration ) => {
319+ setVideoConfiguration ( prev => ( { ...prev , ...values } ) ) ;
320+ if ( values . swipeStartPct !== undefined || values . swipeEndPct !== undefined || values . swipeEasing !== undefined ) {
321+ uiStateActions . setExportVideoSetting ( values as any ) ;
322+ }
323+ } ,
324+ [ uiStateActions ]
316325 ) ;
317326
318327 const hubbleContainerRef = useRef < any > ( null ) ;
@@ -365,23 +374,11 @@ const ExportVideoModalFactory = () => {
365374 ) ;
366375
367376 useEffect ( ( ) => {
368- const trueDpr = trueDevicePixelRatio . current ;
369- const descriptor = Object . getOwnPropertyDescriptor ( window , 'devicePixelRatio' ) ;
370-
371- Object . defineProperty ( window , 'devicePixelRatio' , {
372- get : ( ) => trueDpr ,
373- set : ( ) => {
374- // no-op: prevent hubble.gl from changing DPR
375- } ,
376- configurable : true
377- } ) ;
378-
377+ // Allow hubble.gl to change DPR for resolution scaling during video export.
378+ // On unmount, restore the original DPR value so the rest of the app is unaffected.
379379 return ( ) => {
380- if ( descriptor ) {
381- Object . defineProperty ( window , 'devicePixelRatio' , descriptor ) ;
382- } else {
383- delete ( window as any ) . devicePixelRatio ;
384- }
380+ // @ts -ignore
381+ window . devicePixelRatio = trueDevicePixelRatio . current ;
385382 } ;
386383 } , [ ] ) ;
387384
@@ -429,27 +426,52 @@ const ExportVideoModalFactory = () => {
429426
430427 const { ExportVideoPanelContainer, KeplerUIContext} = hubble ;
431428
429+ const isSwipeMode = mapState . mapSplitMode === MapSplitMode . SWIPE_COMPARE && mapState . isSplit ;
430+
432431 return (
433432 < KeplerUIContext . Provider value = { KEPLER_UI } >
434433 < StyledExportVideoModalContent className = "export-video-modal" >
435- < ExportVideoPanelContainer
436- ref = { hubbleContainerRef }
437- initialState = { videoConfiguration }
438- mapData = { keplerState }
439- onSettingsChange = { onUpdateVideoConfiguration }
440- header = { false }
441- handleClose = { onClose }
442- exportVideoWidth = { exportVideoWidth }
443- onFilterFrameUpdate = { onFilterFrameUpdate }
444- onTripFrameUpdate = { onTripFrameUpdate }
445- deckProps = { deckPropsWithEffects }
446- mapProps = { staticMapProps }
447- disableBaseMap = { false }
448- mapboxLayerBeforeId = { topLayer ?. id }
449- defaultFileName = { DEFAULT_FILENAME }
450- animatableFilters = { animatableFilters }
451- getTimeRangeFilterKeyframes = { getTimeRangeFilterKeyframes }
452- />
434+ { isSwipeMode ? (
435+ < SwipeExportVideoPanelContainer
436+ initialState = { videoConfiguration }
437+ mapData = { keplerState }
438+ onSettingsChange = { onUpdateVideoConfiguration }
439+ header = { false }
440+ handleClose = { onClose }
441+ exportVideoWidth = { exportVideoWidth }
442+ onFilterFrameUpdate = { onFilterFrameUpdate }
443+ onTripFrameUpdate = { onTripFrameUpdate }
444+ deckProps = { deckPropsWithEffects }
445+ mapProps = { staticMapProps }
446+ disableBaseMap = { false }
447+ mapboxLayerBeforeId = { topLayer ?. id }
448+ defaultFileName = { DEFAULT_FILENAME }
449+ animatableFilters = { animatableFilters }
450+ getTimeRangeFilterKeyframes = { getTimeRangeFilterKeyframes }
451+ swipeStartPct = { exportVideo . swipeStartPct }
452+ swipeEndPct = { exportVideo . swipeEndPct }
453+ swipeEasing = { exportVideo . swipeEasing }
454+ />
455+ ) : (
456+ < ExportVideoPanelContainer
457+ ref = { hubbleContainerRef }
458+ initialState = { videoConfiguration }
459+ mapData = { keplerState }
460+ onSettingsChange = { onUpdateVideoConfiguration }
461+ header = { false }
462+ handleClose = { onClose }
463+ exportVideoWidth = { exportVideoWidth }
464+ onFilterFrameUpdate = { onFilterFrameUpdate }
465+ onTripFrameUpdate = { onTripFrameUpdate }
466+ deckProps = { deckPropsWithEffects }
467+ mapProps = { staticMapProps }
468+ disableBaseMap = { false }
469+ mapboxLayerBeforeId = { topLayer ?. id }
470+ defaultFileName = { DEFAULT_FILENAME }
471+ animatableFilters = { animatableFilters }
472+ getTimeRangeFilterKeyframes = { getTimeRangeFilterKeyframes }
473+ />
474+ ) }
453475 </ StyledExportVideoModalContent >
454476 </ KeplerUIContext . Provider >
455477 ) ;
0 commit comments