Skip to main content

Overview

The LabelRenderer class manages 2D HTML labels that are rendered on top of the 3D scene using CSS2D rendering. Labels automatically position themselves relative to their parent 3D objects and can be toggled with layer visibility. Internally uses THREE.CSS2DRenderer to overlay HTML elements onto the map canvas.

Constructor

new LabelRenderer(map)
map
mapboxgl.Map
required
Mapbox GL JS map instance
The constructor automatically:
  • Creates a CSS2D renderer
  • Sets up a canvas overlay positioned absolutely over the map
  • Attaches resize handlers to maintain proper dimensions
  • Appends the label canvas to the map container

Properties

renderer

The THREE.CSS2DRenderer instance used for rendering labels.
labelRenderer.renderer

scene

The Three.js scene containing labeled objects.
labelRenderer.scene

camera

The Three.js camera used for label positioning.
labelRenderer.camera

Methods

render

Renders labels for the current scene and camera.
await labelRenderer.render(scene, camera)
scene
THREE.Scene
required
Three.js scene containing objects with labels
camera
THREE.Camera
required
Three.js camera for determining label positions
Returns: Promise<void> Example:
labelRenderer.render(tb.scene, tb.camera).then(() => {
  console.log('Labels rendered')
})

setSize

Updates the renderer dimensions.
labelRenderer.setSize(width, height)
width
number
required
Width in pixels
height
number
required
Height in pixels
Note: This is called automatically when the map resizes.

toggleLabels

Toggles visibility of labels for a specific layer.
await labelRenderer.toggleLabels(layerId, visible)
layerId
string
required
The Mapbox layer ID
visible
boolean
required
Whether labels should be visible
Returns: Promise<void> Example:
labelRenderer.toggleLabels('buildings-layer', false)

setVisibility

Internal method to set visibility of labels matching specific criteria.
labelRenderer.setVisibility(layerId, visible, scene, camera, renderer)
layerId
string
required
Layer ID to filter labels
visible
boolean
required
Target visibility state
scene
THREE.Scene
required
The scene containing labels
camera
THREE.Camera
required
The camera for rendering
renderer
THREE.CSS2DRenderer
required
The renderer instance
This method:
  • Iterates through the renderer’s cache list
  • Filters labels by layer ID
  • Respects alwaysVisible property on labels
  • Re-renders affected labels

dispose

Cleans up and removes the label renderer.
labelRenderer.dispose()
This method:
  • Removes the DOM element from the map container
  • Clears the renderer object
  • Should be called before removing the map or changing styles

Label Canvas Properties

The label canvas overlay has the following default properties:
{
  position: 'absolute',
  id: 'labelCanvas',
  top: 0,
  zIndex: 0
}

Usage Example

map.on('style.load', function () {
  // LabelRenderer is typically created internally by Threebox
  // but can be accessed via tb.labelRenderer
  
  map.addLayer({
    id: 'custom_layer',
    type: 'custom',
    renderingMode: '3d',
    onAdd: function (map, gl) {
      window.tb = new Threebox(map, gl, { 
        defaultLights: true,
        enableTooltips: true // Enables label tooltips
      })

      tb.loadObj({
        obj: '/models/building.glb',
        type: 'gltf',
        scale: 1,
        units: 'meters'
      }, (model) => {
        let building = model.setCoords([-122.4194, 37.7749, 0])
        building.addLabel('City Hall', true) // Add always-visible label
        tb.add(building)
      })
    },
    render: function (gl, matrix) {
      tb.update()
    }
  })

  // Toggle layer visibility including labels
  map.on('click', (e) => {
    const visible = map.getLayoutProperty('custom_layer', 'visibility') === 'visible'
    tb.toggleLayer('custom_layer', !visible)
  })
})

Integration with Threebox

The LabelRenderer is automatically integrated with Threebox when labels are used:
// Labels are rendered automatically in tb.update()
tb.update() // Renders both 3D scene and 2D labels

// Access the label renderer
if (tb.labelRenderer) {
  console.log('Label renderer available')
}

// Labels respect layer zoom visibility
tb.setLayerZoomRange('custom_layer', 10, 20)
// Labels will also hide/show based on zoom

Creating Labels on Objects

Objects can have labels added using the addLabel method:
obj.addLabel(text, alwaysVisible)
text
string
required
The label text content
alwaysVisible
boolean
default:"false"
If true, label shows even when layer is hidden (unless explicitly toggled)
Example:
building.addLabel('Empire State Building', true)
building.addTooltip('Built in 1931', false)

Automatic Resize Handling

The LabelRenderer automatically handles map resize events:
map.on('resize', function () {
  // LabelRenderer automatically updates dimensions
  // No manual intervention needed
})

Performance Considerations

  • Labels are rendered using CSS transforms for optimal performance
  • The renderer maintains a cache list to avoid redundant renders
  • Label visibility toggling uses the cache for efficient filtering
  • Large numbers of labels (>1000) may impact performance

Notes

  • Labels use CSS2D rendering, so they’re always rendered on top of the 3D scene
  • Label positions update automatically as objects move or camera changes
  • The label canvas has z-index: 0 by default (below Mapbox controls)
  • Labels are automatically disposed when their parent objects are removed
  • The alwaysVisible property on labels is respected during visibility toggling

Build docs developers (and LLMs) love