A high performance WebGL tile rendering library
Introduction
Lumo is a lightweight WebGL rendering library designed for highly scalable, customizable, and performant tile-based visualizations. Lumo is composed of simple and extensible interfaces for retrieving, managing, and viewing tile-based data.
While Lumo does provide some higher level data abstractions for WebGL, it assumes a degree of familiarity with the WebGL API and GLSL.
Installation
npm install lumo
Lumo is written in ES6 and requires a 6.x+ distribution of node. The lumo.js
and lumo.min.js
build files have been transpiled via babeljs using the es2015 preset and should be consumable by most modern browsers.
Example
The following is a simple application that creates a single lumo.Plot
and attaches two lumo.TileLayer
objects. The first layer base
retrieves CARTO Basemap tiles and renders them using the lumo.ImageTileRenderer
. The points
layer generates random points of varying radius and renders them with the lumo.PointTileRenderer
.
; // Plot const plot = '#plot' continuousZoom: true inertia: true wraparound: true zoom: 3; // WebGL CARTO Image Layer const base = renderer: ; base { const SUBDOMAINS = 'a' 'b' 'c' 'd' ; const s = SUBDOMAINScoordx + coordy + coordz % SUBDOMAINSlength; const url = `http:/.basemaps.cartocdn.com/dark_nolabels/.png`; lumo;}; plot; // WebGL Point Layer const points = renderer: color: 04 10 01 08 ; points { const NUM_POINTS = 256 * 32; const buffer = 3 * NUM_POINTS; for let i=0; i<NUM_POINTS; i++ bufferi*3 = Math * 256; // x bufferi*3+1 = Math * 256; // y bufferi*3+2 = Math * 4 + 2; // radius ;}; plot;
lumo-example repository.
For more usage examples please refer to theUsage
Plot
The central component tying all tile based visualizations together is a lumo.Plot
which is instantiated by providing a selector string for the containing DOM element, along with an optional configuration object.
const plot = '#plot' continuousZoom: true inertia: true wraparound: true zoom: 3;
TileLayer
A lumo.TileLayer
represents a single source of tile data and is only responsible for retrieving and storing tile data in it's transmission format.
const layer = ; layer { ;}; plot
TileRenderer
A lumo.TileRenderer
is attached to a lumo.TileLayer
and is responsible for efficiently transforming and storing the data, tile by tile, on the GPU and subsequently rendering any available data to the plot.
const renderer = ;layer;
The base lumo.TileRenderer
class provides a simple and unstructured class for rendering layer tile data. The lumo.WebGLTileRenderer
class provides higher level abstractions for efficiently storing and accessing tile data on the GPU in vertex and texture formats.
Below is an example of a minimalistic vertex-based renderer implemented by extending the lumo.WebGLTileRenderer
class:
{ superoptions; thisshader = null; thisatlas = null; } { super; // Instantiate the shader object providing the source for both the // vertex and fragment shaders. thisshader = this; // Create the vertex atlas to store the vertex data, in this case we // only have a single vertex attribute, the position. // This method registers handles to pipe the tile data and created // atlas to the `addTile` and `removeTile` methods. thisatlas = this; return this; } { // Clean up the vertex atlas and remove `addTile` and `removeTile` // handlers. this; thisatlas = null; thisshader = null; super; return this; } { const shader = thisshader; const atlas = thisatlas; const proj = this; const renderables = this; // use shader shader; // set projection shader; // binds the vertex atlas atlas; // for each renderable tile renderables; // unbind the vertex atlas atlas; return this; }
Overlay
An overlay represents a single source of data. The data is not tiled and is added and removed in a global sense. Overlays are typically used when a small amount of client-side static data needs to be displayed.
const overlay = ; overlay; plot
OverlayRenderer
A lumo.OverlayRenderer
is attached to a lumo.Overlay
and is responsible for spatially partitioning the data and efficiently rendering any available data to the plot.
const renderer = ;overlay;
Coordinates
There are three coordinate systems used by Lumo. Tile coordinates, plot coordinates and viewport coordinates. All coordinates have the origin [0, 0] as the bottom-left.
-
Tile Coordinates have three components and follow the TMS specification in the format of {z, x, y}. Each zoom level increases the number of tiles in each dimension by a power of two. These coordinates are used to request and store tiles.
-
Tile Pixel Coordinates have two components and are the pixel coordinates relative to the bottom-left corner of the respective tile. These coordinates are used to render the tile data.
-
Plot Coordinates have two components, [0, 0] at the bottom-left corner of the plot, and [1, 1] at the top-right.
Events
All lumo.Plot
, lumo.Layer
, and lumo.Renderer
classes extend the EventEmitter
class and are capable of emitting events.
The following events are emitted by Lumo:
Plot
- Mouse
- click: Emitted when the plot is clicked.
- dblclick: Emitted when the plot is double clicked.
- mousemove: Emitted when the mouse is moved over the plot.
- mousedown: Emitted when the mouse button is pressed over the plot.
- mouseup: Emitted when the mouse button is released over the plot.
- mouseover: Emitted when the mouse is moved over the plot.
- mouseout: Emitted when the mouse is moved outside of the plot.
- Pan / Zoom
- zoomstart: Emitted when a new zoom event is handled.
- zoom: Emitted during each frame of a zoom animation.
- zoomend: Emitted when a zoom event is complete.
- panstart: Emitted when a new pan event is handled.
- pan: Emitted during each frame of a pan animation.
- panend: Emitted when a pan event is complete.
- Resize
- resize: Emitted whenever the plot dimensions change.
- Frame
- frame: Emitted at the beginning of every render frame.
TileLayer
- Mouse
- click: Emitted when an element of the layer is clicked.
- dblclick: Emitted when an element of the layer is double clicked.
- mousemove: Emitted when the mouse is moved over an element of the layer.
- mousedown: Emitted when the mouse button is pressed over an element of the layer.
- mouseup: Emitted when the mouse button is released over an element of the layer.
- mouseover: Emitted when the mouse is moved over an element of the layer.
- mouseout: Emitted when the mouse is moved outside of an element of the layer.
- Tile
- tilerequest: Emitted when a tile is requested for the layer.
- tileadd: Emitted when a tile is received and added to the layer.
- tilefailure: Emitted when a tile request fails and the tile is rejected.
- tilediscard: Emitted when a tile is received but is deemed stale and discarded.
- tileremove: Emitted when a tile is evicted from the layer.
- load: Emitted when a all pending tiles have loaded for the layer.
- Pan / Zoom
- zoomstart: Emitted when a new zoom event is handled.
- zoom: Emitted during each frame of a zoom animation.
- zoomend: Emitted when a zoom event is complete.
- panstart: Emitted when a new pan event is handled.
- pan: Emitted during each frame of a pan animation.
- panend: Emitted when a pan event is complete.
- Refresh
- refresh: Emitted whenever the layer is refreshed, all data is flushed and any state is cleared.
Overlay
- Mouse
- click: Emitted when an element of the overlay is clicked.
- dblclick: Emitted when an element of the overlay is double clicked.
- mousemove: Emitted when the mouse is moved over an element of the overlay.
- mousedown: Emitted when the mouse button is pressed over an element of the overlay.
- mouseup: Emitted when the mouse button is released over an element of the overlay.
- mouseover: Emitted when the mouse is moved over an element of the overlay.
- mouseout: Emitted when the mouse is moved outside of an element of the overlay.
- Pan / Zoom
- zoomstart: Emitted when a new zoom event is handled.
- zoom: Emitted during each frame of a zoom animation.
- zoomend: Emitted when a zoom event is complete.
- panstart: Emitted when a new pan event is handled.
- pan: Emitted during each frame of a pan animation.
- panend: Emitted when a pan event is complete.
- Refresh
- refresh: Emitted whenever the layer is refreshed, all data is flushed and any state is cleared.