Cobe: 3D Globe With Dotted World Map Using WebGL

Category: Javascript , Recommended | September 19, 2026
Authorshuding
Last UpdateSeptember 19, 2026
LicenseMIT
Views10,941 views
Cobe: 3D Globe With Dotted World Map Using WebGL

COBE is a lightweight WebGL library for generating an animated 3D globe with a dotted world map on an HTML canvas.

It supports custom markers, curved arcs between locations, color and camera controls, runtime updates, and DOM labels anchored to globe positions with CSS Anchor Positioning.

Features

  • About 5KB with no runtime dependencies.
  • Dotted 3D world map rendered with WebGL.
  • Custom markers with configurable locations, sizes, and colors.
  • Curved arcs between geographic locations.
  • Configurable globe colors, opacity, scale, offset, rotation, and tilt.
  • Runtime state updates through the update() method.
  • DOM labels and tooltips anchored to markers and arcs with CSS Anchor Positioning.
  • Custom WebGL context attributes.

How to use it

Installation

Install COBE from npm.

npm install cobe

Basic usage

Add a canvas element for the globe:

<canvas
  id="cobe"
  style="width: 500px; height: 500px;"
></canvas>

Import createGlobe and pass the canvas with the globe configuration:

import createGlobe from 'cobe'
const canvas = document.getElementById('cobe')
const dpr = window.devicePixelRatio || 1
const globe = createGlobe(canvas, {
  devicePixelRatio: dpr,
  width: 500,
  height: 500,
  phi: 0,
  theta: 0.2,
  dark: 0,
  diffuse: 1.2,
  mapSamples: 16000,
  mapBrightness: 6,
  baseColor: [0.3, 0.3, 0.3],
  markerColor: [1, 0.5, 1],
  glowColor: [1, 1, 1],
  markers: [
    { location: [37.7595, -122.4367], size: 0.03 },
    { location: [40.7128, -74.006], size: 0.08, color: [1, 0, 0] },
  ],
})

Rotate and update the globe

The current public instance API uses update() for runtime state changes. A requestAnimationFrame() loop can update phi for continuous rotation:

let phi = 0
function animate() {
  phi += 0.005
  globe.update({ phi })
  requestAnimationFrame(animate)
}
animate()

You can update other runtime values after initialization:

globe.update({
  theta: 0.35,
  dark: 1,
  scale: 0.9,
})

Add arcs between locations

Use arcs to connect two latitude and longitude pairs. When changing arc geometry at runtime, set arcWidth and arcHeight before submitting the arc list.

globe.update({
  arcColor: [0.3, 0.6, 1],
  arcWidth: 0.5,
  arcHeight: 0.3,
})
globe.update({
  arcs: [
    {
      from: [37.7595, -122.4367],
      to: [35.6762, 139.6503],
      color: [1, 0.5, 0.5],
    },
  ],
})

Attach DOM labels to markers and arcs

Give a marker or arc an id to expose CSS anchors and visibility variables for labels, tooltips, and other DOM content.

globe.update({
  markers: [
    {
      location: [37.7595, -122.4367],
      size: 0.03,
      id: 'sf',
    },
  ],
  arcs: [
    {
      from: [37.7595, -122.4367],
      to: [35.6762, 139.6503],
      id: 'sf-tokyo',
    },
  ],
})

A marker ID such as sf exposes --cobe-sf and --cobe-visible-sf. An arc ID such as sf-tokyo exposes --cobe-arc-sf-tokyo and --cobe-visible-arc-sf-tokyo.

.marker-label {
  position: absolute;
  position-anchor: --cobe-sf;
  bottom: anchor(top);
  left: anchor(center);
  opacity: var(--cobe-visible-sf, 0);
  filter: blur(calc((1 - var(--cobe-visible-sf, 0)) * 8px));
  transition: opacity 0.3s, filter 0.3s;
}
.arc-label {
  position: absolute;
  position-anchor: --cobe-arc-sf-tokyo;
  bottom: anchor(top);
  left: anchor(center);
  opacity: var(--cobe-visible-arc-sf-tokyo, 0);
}

All Configuration Options

  • width (number, required): Sets the globe canvas width before device pixel ratio scaling.
  • height (number, required): Sets the globe canvas height before device pixel ratio scaling.
  • phi (number, required): Sets horizontal globe rotation in radians.
  • theta (number, required): Sets vertical globe rotation in radians.
  • mapSamples (number, required): Sets the number of samples used for the dotted map.
  • mapBrightness (number, required): Sets the brightness of the map dots.
  • mapBaseBrightness (number, default 0): Sets a minimum brightness value for the map texture.
  • baseColor ([number, number, number], required): Sets the RGB base color of the globe.
  • markerColor ([number, number, number], required): Sets the default RGB marker color.
  • glowColor ([number, number, number], required): Sets the RGB glow color around the globe.
  • markers (Marker[], default []): Sets the markers rendered on the globe.
  • diffuse (number, required): Controls diffuse lighting across the globe surface.
  • devicePixelRatio (number, required): Sets the pixel ratio used for the canvas drawing buffer.
  • dark (number, required): Controls the dark rendering factor.
  • opacity (number, default 1): Sets globe opacity.
  • offset ([number, number], default [0, 0]): Offsets the globe from the canvas center.
  • scale (number, default 1): Scales the rendered globe.
  • context (WebGLContextAttributes): Overrides the WebGL context attributes used during initialization.
  • arcs (Arc[], default []): Sets the arcs rendered between geographic locations.
  • arcColor ([number, number, number], default [0.3, 0.6, 1]): Sets the default RGB arc color.
  • arcWidth (number, default 1): Sets the global arc width.
  • arcHeight (number, default 0.2): Sets the global arc height above the globe.
  • markerElevation (number, default 0.05): Sets marker elevation above the globe surface.

Marker properties

  • location ([number, number], required): Latitude and longitude in degrees.
  • size (number, required): Marker size.
  • color ([number, number, number]): Overrides markerColor for this marker.
  • id (string): Creates CSS anchor and visibility variables for the marker.

Arc properties

  • from ([number, number], required): Starting latitude and longitude in degrees.
  • to ([number, number], required): Ending latitude and longitude in degrees.
  • color ([number, number, number]): Overrides arcColor for this arc.
  • id (string): Creates CSS anchor and visibility variables for the arc.

API Methods

  • update(state): Updates runtime state values handled by the instance and renders the globe again.
  • destroy(): Deletes the instance’s WebGL buffers and programs and removes generated anchor elements.

Related Resources

Changelog

v2 (09/19/2026)

  • Updated

You Might Be Interested In:


Leave a Reply