Add a custom MapsGL timeline control
This example demonstrates how to integrate a custom timeline control (built with the Timeline component) with the MapsGL Timeline (opens in a new tab). It shows how to sync the timeline state with MapsGL's animation controls and handle playback events.
Key Features
- Integration with MapsGL timeline events
- Automatic state synchronization
- Timeline controls and current date/time display
- Weather layer time-based animation
Implementation
- First, create the timeline structure:
import { Timeline, VStack, HStack } from '@xweather/maps-ui-sdk';
const Timeline = () => (
<Timeline.Container className="bg-black px-4 py-2 rounded-xl">
<Timeline.AnimationControl className="bg-white rounded-full size-8 mr-4" />
<VStack className="items-center h-full w-full">
<HStack className="justify-start w-full space-x-1 text-sm text-white mb-1">
<Timeline.DateText />,
<Timeline.TimeText className="lowercase" />
</HStack>
<HStack className="items-center space-x-2 w-full">
<Timeline.Track className="h-5 border border-[#484E54] bg-[#343A40] rounded-full mt-auto">
<Timeline.Scrubber className="cursor-pointer p-3 -m-3">
<Timeline.LineProgressIndicator />
</Timeline.Scrubber>
</Timeline.Track>
</HStack>
</VStack>
</Timeline.Container>
);
- Wrap the
Timeline
component inTimeline.Provider
and set up the MapsGL timeline integration handlers:
import { Timeline, useMapsGLMapControllerContext } from '@xweather/maps-ui-sdk';
const MapsGLTimelineControl = () => {
const { controller } = useMapsGLMapControllerContext();
const [currentDate, setCurrentDate] = useState<Date | null>(controller?.timeline?.currentDate);
useEffect(() => {
if (!controller?.timeline) return;
controller.timeline.on('advance', () => {
if (controller.timeline.currentDate) {
setCurrentDate(controller.timeline.currentDate);
}
});
}, [controller]);
const handlePlay = () => {
if (controller.timeline.isActive) {
controller.timeline.resume();
} else {
controller.timeline.play();
}
};
const handlePause = () => {
controller.timeline.pause();
};
const handlePositionChange = (position: number) => {
controller.timeline.goTo(position);
};
if (!controller?.timeline) return null;
return (
<Timeline.Provider
startDate={controller.timeline.startDate}
endDate={controller.timeline.endDate}
currentDate={currentDate}
position={controller.timeline.position}
onPlay={handlePlay}
onPause={handlePause}
onPositionChange={handlePositionChange}
>
<Timeline />
</Timeline.Provider>
);
};
- Wrap the timeline control in the
MapsGLMapControllerProvider
and add a weather layer that supports time-based animation:
import { MapsGLMapControllerProvider, Anchor } from '@xweather/maps-ui-sdk';
const controllerOptions = {
animation: {
duration: 6,
endDelay: 1,
},
};
<MapsGLMapControllerProvider
accessKeys={accessKeys}
strategy="mapbox"
map={map}
options={options}
onLoad={(event) => {
const controller = event.target;
controller.addWeatherLayer('air-quality-no2');
}}
>
<Anchor.Bottom offsetY={40} className="z-10">
<MapsGLTimelineControl />
</Anchor.Bottom>
</MapsGLMapControllerProvider>
You can configure the MapsGL timeline behavior through the options.animation
prop in the MapsGLMapControllerProvider
. For all available timeline options, see the MapsGL Timeline documentation (opens in a new tab).
For details on setting up the map and controller, see the Add a map controller with controls example. For more information about building custom timeline controls, see the Custom Timeline Control example.