npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

maplibre-gl-time-slider

v0.2.1

Published

A MapLibre GL JS plugin for visualizing time series vector and raster data with an interactive time slider control

Readme

maplibre-gl-time-slider

A MapLibre GL JS plugin for visualizing time series vector and raster data with an interactive time slider control.

npm version License: MIT

Features

  • Interactive time slider with play/pause controls
  • Support for both vector and raster time series data
  • Built-in TiTiler integration for Cloud Optimized GeoTIFFs (COGs)
  • Customizable playback speed and loop settings
  • React component and hooks support
  • TypeScript support with full type definitions
  • Lightweight and easy to integrate

Installation

npm install maplibre-gl-time-slider

Quick Start

Basic Usage (Vanilla JavaScript/TypeScript)

import maplibregl from 'maplibre-gl';
import { TimeSliderControl } from 'maplibre-gl-time-slider';
import 'maplibre-gl-time-slider/style.css';

const map = new maplibregl.Map({
  container: 'map',
  style: 'https://demotiles.maplibre.org/style.json',
  center: [0, 0],
  zoom: 2,
});

map.on('load', () => {
  const timeSlider = new TimeSliderControl({
    title: 'Time Slider',
    labels: ['2024-01', '2024-02', '2024-03', '2024-04'],
    speed: 1000,
    loop: true,
    onChange: (index, label) => {
      console.log(`Current: ${label} (index: ${index})`);
      // Update your map layers here
    },
  });

  map.addControl(timeSlider, 'top-right');
});

React Usage

import { useState, useEffect, useRef } from 'react';
import maplibregl from 'maplibre-gl';
import { TimeSliderControlReact } from 'maplibre-gl-time-slider/react';
import 'maplibre-gl-time-slider/style.css';

function MyMap() {
  const mapContainer = useRef<HTMLDivElement>(null);
  const [map, setMap] = useState<maplibregl.Map | null>(null);

  useEffect(() => {
    if (!mapContainer.current) return;

    const mapInstance = new maplibregl.Map({
      container: mapContainer.current,
      style: 'https://demotiles.maplibre.org/style.json',
      center: [0, 0],
      zoom: 2,
    });

    mapInstance.on('load', () => setMap(mapInstance));

    return () => mapInstance.remove();
  }, []);

  return (
    <>
      <div ref={mapContainer} style={{ width: '100%', height: '100vh' }} />
      {map && (
        <TimeSliderControlReact
          map={map}
          title="Time Slider"
          labels={['2024-01', '2024-02', '2024-03']}
          onChange={(index, label) => {
            // Update map layers
          }}
        />
      )}
    </>
  );
}

Examples

Vector Data (Filtering by Time)

Filter vector features by a time property:

const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

const timeSlider = new TimeSliderControl({
  labels: months,
  onChange: (index, label) => {
    // Filter vector layer by month
    map.setFilter('my-layer', ['==', ['get', 'month'], index]);
  },
});

Raster Data (TiTiler Integration)

Display time series raster data using TiTiler:

import { TimeSliderControl, buildTiTilerTileUrl } from 'maplibre-gl-time-slider';

const rasterData = {
  '2024-01': 'https://example.com/cog_2024_01.tif',
  '2024-02': 'https://example.com/cog_2024_02.tif',
  '2024-03': 'https://example.com/cog_2024_03.tif',
};

const labels = Object.keys(rasterData);
const urls = Object.values(rasterData);

// Add initial raster source
map.addSource('raster-data', {
  type: 'raster',
  tiles: [
    buildTiTilerTileUrl({
      url: urls[0],
      colormap: 'viridis',
    }),
  ],
  tileSize: 256,
});

map.addLayer({
  id: 'raster-layer',
  type: 'raster',
  source: 'raster-data',
});

// Create time slider
const timeSlider = new TimeSliderControl({
  labels: labels,
  onChange: (index, label) => {
    const source = map.getSource('raster-data');
    source.setTiles([
      buildTiTilerTileUrl({
        url: urls[index],
        colormap: 'viridis',
      }),
    ]);
  },
});

API Reference

TimeSliderControl

Main control class that implements MapLibre's IControl interface.

Constructor Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | labels | string[] | [] | Array of labels to display (required) | | title | string | 'Time Slider' | Title displayed in the panel header | | collapsed | boolean | true | Whether to start with panel collapsed | | position | string | 'top-right' | Control position on the map | | panelWidth | number | 300 | Width of the panel in pixels | | initialIndex | number | 0 | Initial index to start at | | speed | number | 1000 | Playback speed in milliseconds | | loop | boolean | true | Whether to loop playback | | className | string | '' | Custom CSS class name | | onChange | function | - | Callback when index changes: (index: number, label: string) => void |

Methods

| Method | Description | |--------|-------------| | play() | Start playback | | pause() | Pause playback | | togglePlayback() | Toggle play/pause state | | next() | Move to next label | | prev() | Move to previous label | | goTo(index) | Navigate to specific index | | setSpeed(ms) | Set playback speed | | setLoop(enabled) | Set loop state | | setLabels(labels, resetIndex?) | Update labels | | getCurrentIndex() | Get current index | | getCurrentLabel() | Get current label | | getLabels() | Get all labels | | getState() | Get full state object | | toggle() | Toggle panel collapsed state | | expand() | Expand panel | | collapse() | Collapse panel | | on(event, handler) | Register event listener | | off(event, handler) | Remove event listener |

Events

| Event | Description | |-------|-------------| | change | Fired when the current index changes | | play | Fired when playback starts | | pause | Fired when playback pauses | | collapse | Fired when panel collapses | | expand | Fired when panel expands | | statechange | Fired on any state change |

TiTiler Utilities

buildTiTilerTileUrl(options)

Builds a TiTiler XYZ tile URL for MapLibre raster sources.

const tileUrl = buildTiTilerTileUrl({
  url: 'https://example.com/my-cog.tif',
  endpoint: 'https://giswqs-titiler-endpoint.hf.space',  // optional, default
  colormap: 'viridis',              // optional, default
  rescale: [-10, 10],               // optional
  bidx: [1],                        // optional, band indexes
});

getTiTilerBounds(url, endpoint?)

Fetches the bounds of a COG file.

const bounds = await getTiTilerBounds('https://example.com/my-cog.tif');
map.fitBounds(bounds);

getTiTilerInfo(url, endpoint?)

Fetches metadata about a COG file.

getTiTilerStatistics(url, endpoint?)

Fetches statistics (min, max, mean, std) for each band.

Development

# Install dependencies
npm install

# Start development server
npm run dev

# Build library
npm run build

# Build examples
npm run build:examples

# Run tests
npm test

# Lint code
npm run lint

# Format code
npm run format

Docker

The examples can be run using Docker. The image is automatically built and published to GitHub Container Registry.

Pull and Run

# Pull the latest image
docker pull ghcr.io/opengeos/maplibre-gl-time-slider:latest

# Run the container
docker run -p 8080:80 ghcr.io/opengeos/maplibre-gl-time-slider:latest

Then open http://localhost:8080/maplibre-gl-time-slider/ in your browser to view the examples.

Build Locally

# Build the image
docker build -t maplibre-gl-time-slider .

# Run the container
docker run -p 8080:80 maplibre-gl-time-slider

Available Tags

| Tag | Description | |-----|-------------| | latest | Latest release | | x.y.z | Specific version (e.g., 1.0.0) | | x.y | Minor version (e.g., 1.0) |

License

MIT License - see LICENSE for details.