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 🙏

© 2024 – Pkg Stats / Ryan Hefner

lumo

v0.20.17

Published

A high performance WebGL tile rendering library

Downloads

226

Readme

A high performance WebGL tile rendering library

npm version Build Status Dependency Status

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.


import lumo from 'lumo';

// Plot

const plot = new lumo.Plot('#plot', {
	continuousZoom: true,
	inertia: true,
	wraparound: true,
	zoom: 3
});

// WebGL CARTO Image Layer

const base = new lumo.TileLayer({
	renderer: new lumo.ImageTileRenderer()
});

base.requestTile = (coord, done) => {
	const SUBDOMAINS = [ 'a', 'b', 'c', 'd' ];
	const s = SUBDOMAINS[(coord.x + coord.y + coord.z) % SUBDOMAINS.length];
	const url = `http:/${s}.basemaps.cartocdn.com/dark_nolabels/${coord.xyz()}.png`;
	lumo.loadImage(url, done);
};

plot.add(base);

// WebGL Point Layer

const points = new lumo.TileLayer({
	renderer: new lumo.PointTileRenderer({
		color: [ 0.4, 1.0, 0.1, 0.8 ]
	})
});

points.requestTile = (coord, done) => {
	const NUM_POINTS = 256 * 32;
	const buffer = new Float32Array(3 * NUM_POINTS);
	for (let i=0; i<NUM_POINTS; i++) {
		buffer[i*3] = Math.random() * 256; // x
		buffer[i*3+1] = Math.random() * 256; // y
		buffer[i*3+2] = (Math.random() * 4) + 2; // radius
	}
	done(null, buffer);
};

plot.add(points);
For more usage examples please refer to the lumo-example repository.

Usage

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 = new lumo.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 = new lumo.TileLayer();

layer.requestTile = (coord, done) => {
	done(null, {});
};

plot.add(layer)

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 = new lumo.PointTileRenderer();
layer.setRenderer(renderer);

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:

class SampleRenderer extends WebGLVertexRenderer {
	constructor(options = {}) {
		super(options);
		this.shader = null;
		this.atlas = null;
	}
	onAdd(layer) {
		super.onAdd(layer);
		// Instantiate the shader object providing the source for both the
		// vertex and fragment shaders.
		this.shader = this.createShader({
			vert:
				`
				precision highp float;
				attribute vec2 aPosition;
				uniform vec2 uTileOffset;
				uniform float uScale;
				uniform mat4 uProjectionMatrix;
				void main() {
					vec2 wPosition = (aPosition * uScale) + uTileOffset;
					gl_PointSize = 4.0;
					gl_Position = uProjectionMatrix * vec4(wPosition, 0.0, 1.0);
				}
				`,
			frag:
				`
				precision highp float;
				void main() {
					gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
				}
				`
		});
		// 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.
		this.atlas = this.createVertexAtlas({
			attributePointers: {
				0: {
					size: 2,
					type: 'FLOAT'
				}
			}
		});
		return this;
	}
	onRemove(layer) {
		// Clean up the vertex atlas and remove `addTile` and `removeTile`
		// handlers.
		this.destroyVertexAtlas(this.atlas);
		this.atlas = null;
		this.shader = null;
		super.onRemove(layer);
		return this;
	}
	draw() {
		const shader = this.shader;
		const atlas = this.atlas;
		const proj = this.getOrthoMatrix();
		const renderables = this.getRenderables();
		// use shader
		shader.use();
		// set projection
		shader.setUniform('uProjectionMatrix', proj);
		// binds the vertex atlas
		atlas.bind();
		// for each renderable tile
		renderables.forEach(renderable => {
			// set tile uniforms
			shader.setUniform('uScale', renderable.scale);
			shader.setUniform('uTileOffset', renderable.tileOffset);
			// draw the points
			atlas.draw(renderable.hash, 'POINTS');
		});
		// unbind the vertex atlas
		atlas.unbind();
		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 = new lumo.PolylineOverlay();

overlay.addPolyline('line-id', [
	{ x: 0.2, y: 0.2 },
	{ x: 0.8, y: 0.8 },
	{ x: 0.2, y: 0.8 },
	{ x: 0.8, y: 0.2 },
	{ x: 0.2, y: 0.2 }
]);

plot.add(overlay)

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 = new lumo.PolylineOverlayRenderer();
overlay.setRenderer(renderer);

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.