Framework-agnostic core
Plain TypeScript. The engine has zero runtime deps — bring Angular, React, or no framework at all.
A TypeScript-first interpolation engine that drops straight into your map. Smooth motion between position updates — WebSocket, polling, or anything else — without writing your own animation loop.
One position stream, 2.2 s apart. Left snaps; right runs the tick loop.
Plain TypeScript. The engine has zero runtime deps — bring Angular, React, or no framework at all.
Ring-slot buffers keep two points per object. Allocation-free hot path, bounded memory across a full day.
Reads the feed period per point and switches between snap, lerp and fade zones — no manual tuning.
Points flow through active → warning → stale → completed, with events at every transition.
Anomalous jumps and sharp turns are caught automatically — fade behavior and cubic fallback, no opt-out.
Adapter and interpolation failures surface as typed error events — the tick loop never dies.
The Angular wrapper accepts a Signal or Observable of positions and wires lifecycle to DestroyRef.
Move the tick loop off the main thread with one flag — keep map pan and zoom buttery under tens of thousands of points.
Pick an adapter, hand the tracker your position stream, and start the loop. Everything else has production-grade defaults.
Tip: set renderLagMs ≈ feed period so the engine always has two points to interpolate between. The default is 1000.
import { Tracker } from '@kinesisjs/core';
import { OpenLayersAdapter } from '@kinesisjs/openlayers';
const tracker = new Tracker({
adapter: new OpenLayersAdapter(map),
interpolation: 'adaptive',
});
tracker.start();
ws.onmessage = (e) => tracker.ingest(JSON.parse(e.data));Four curves, plus an adaptive mode that picks per point at runtime.
Straight-line lerp between the two latest points. The default — right for most feeds.
Smoothstep easing — softer acceleration into and out of each segment.
Great-circle arc across the globe. For ships, aircraft and long distances.
3-point centripetal Catmull-Rom. Rounds the path through turns once a third ping lands.
Reads feed period per point → snap, lerp, or fade. Zero manual tuning.
Reactive inputs (Signal / Observable / Hook) and lifecycle wired to the framework's teardown.
Create, update and remove features; styling, trails and viewport. One small adapter per map library.
Clock (rAF-synced), Interpolator, Sweeper lifecycle, typed EventBus and math utils. Zero deps.
A tiny core plus opt-in adapters and wrappers — ESM + CJS, fully typed.
The framework-agnostic interpolation engine: clock, modes, lifecycle, events.
OpenLayers adapter with marker styling, fading trails and gap visualization.
Standalone kinesisMap directive — Signals/RxJS in, auto-teardown out.
Leaflet adapter with heading-aware markers that co-exist with your own layers.
OSRM-backed road-snapping CustomInterpolator with an LRU cache.
Representative benchmarks — 1000 points, linear mode, desktop Chrome. Real-world figures shift with device, map, point count and browser; the ratios hold.
Read it all live with getStats() — tick p50/p95/p99, ingest rate, dropped ticks, memory. Need more? Web Worker mode (v0.2) moves the loop off-thread.
| Capability | Kinesis.jsThis library | leaflet-realtimeLeaflet GeoJSON live layer | MovingMarkerLeaflet marker tween plugin | raw setCoordshand-rolled setLatLng() |
|---|---|---|---|---|
| ~60fps interpolation | Kinesis.jsYes | leaflet-realtimepartial | MovingMarkerpartial | raw setCoordsNo |
| Map-library agnostic | Kinesis.jsYes | leaflet-realtimeLeaflet only | MovingMarkerLeaflet only | raw setCoordsYes |
| Adaptive period handling | Kinesis.jsYes | leaflet-realtimeNo | MovingMarkerNo | raw setCoordsNo |
| Bounded memory profile | Kinesis.jsYes | leaflet-realtimepartial | MovingMarkerNo | raw setCoordsNo |
| Multi-state lifecycle | Kinesis.jsYes | leaflet-realtimeNo | MovingMarkerNo | raw setCoordsNo |
| Error-as-event | Kinesis.jsYes | leaflet-realtimeNo | MovingMarkerNo | raw setCoordsNo |
| TypeScript-first | Kinesis.jsYes | leaflet-realtimetypes | MovingMarkerNo | raw setCoordsNo |
Drop in the tracker, hand it your stream, and watch the jumps turn into motion. Five kilobytes, zero dependencies.