Skip to main content
Object3D instances fire various events that can be listened to using addEventListener. All events include the object itself in the detail property of the event.

Selection Events

SelectedChange
event
Fired when the object’s selection state changes.Event Detail:
  • selected (boolean): Whether the object is now selected
  • detail (Object3D): The object that was selected/unselected
Trigger Conditions:
  • Object is clicked when tb.enableSelectingObjects is true
  • Object is programmatically selected/unselected via obj.selected = true/false
  • Another object is selected (implicitly unselects this object)
obj.addEventListener('SelectedChange', (e) => {
  console.log('Selected:', e.detail.selected);
  console.log('Object:', e.detail);
  
  if (e.detail.selected) {
    // Object was selected
    map.flyTo({
      center: e.detail.coordinates,
      zoom: 18
    });
  } else {
    // Object was unselected
  }
});

Mouse Events

ObjectMouseOver
event
Fired when the mouse cursor enters the object’s bounds.Event Detail:
  • detail (Object3D): The object being hovered
Trigger Conditions:
  • Mouse cursor moves over the object when raycasting is enabled
  • Bounding box becomes visible if configured
  • Label becomes visible if configured
obj.addEventListener('ObjectMouseOver', (e) => {
  console.log('Mouse over object:', e.detail);
  map.getCanvas().style.cursor = 'pointer';
});
ObjectMouseOut
event
Fired when the mouse cursor leaves the object’s bounds.Event Detail:
  • detail (Object3D): The object that was being hovered
Trigger Conditions:
  • Mouse cursor moves away from the object
  • Bounding box becomes hidden (if not selected)
  • Label becomes hidden (if not alwaysVisible and not selected)
obj.addEventListener('ObjectMouseOut', (e) => {
  console.log('Mouse left object:', e.detail);
  map.getCanvas().style.cursor = '';
});

Drag Events

ObjectDragged
event
Fired when the object is dragged and then released.Event Detail:
  • detail (Object3D): The object that was dragged
  • draggedAction (string): Type of drag action - 'translate', 'altitude', or 'rotate'
Trigger Conditions:
  • Object is selected and tb.enableDraggingObjects is true
  • User holds SHIFT and drags to translate horizontally (draggedAction = 'translate')
  • User holds CTRL and drags to change altitude (draggedAction = 'altitude')
  • Object is selected and tb.enableRotatingObjects is true
  • User holds ALT and drags to rotate (draggedAction = 'rotate')
obj.addEventListener('ObjectDragged', (e) => {
  const obj = e.detail;
  
  switch (obj.draggedAction) {
    case 'translate':
      console.log('Object moved to:', obj.coordinates);
      // Save new position to database
      break;
    case 'altitude':
      console.log('Object altitude changed to:', obj.coordinates[2]);
      break;
    case 'rotate':
      console.log('Object rotated to:', obj.rotation);
      break;
  }
  
  // Update feature coordinates if stored
  if (obj.userData.feature) {
    obj.userData.feature.geometry.coordinates = obj.coordinates;
  }
});

Visual State Events

Wireframed
event
Fired when the object’s wireframe mode is toggled.Event Detail:
  • detail (Object3D): The object whose wireframe state changed
Trigger Conditions:
  • obj.wireframe property is changed to true or false
obj.addEventListener('Wireframed', (e) => {
  console.log('Wireframe mode:', e.detail.wireframe);
  
  if (e.detail.wireframe) {
    console.log('Object is now in wireframe mode');
  } else {
    console.log('Object returned to normal rendering');
  }
});
ObjectChanged
event
Fired when the object undergoes significant changes that require scene updates.Event Detail:
  • detail (Object3D): The object that changed
Trigger Conditions:
  • Object properties are modified
  • Object is transformed (position, rotation, scale)
  • Object state changes requiring re-render
obj.addEventListener('ObjectChanged', (e) => {
  console.log('Object changed:', e.detail);
  tb.map.repaint = true;
});

Animation Events

IsPlayingChanged
event
Fired when the object’s animation playback state changes.Event Detail:
  • detail (Object3D): The object whose animation state changed
  • isPlaying (boolean): Whether animation is now playing
Trigger Conditions:
  • Animation is started or stopped on an object that contains animations
  • Only applicable to objects loaded with animations (GLTF/GLB models)
obj.addEventListener('IsPlayingChanged', (e) => {
  if (e.detail.isPlaying) {
    console.log('Animation started on:', e.detail);
  } else {
    console.log('Animation stopped on:', e.detail);
  }
});

Event Listener Examples

Complete Event Setup

tb.loadObj(options, function (model) {
  const soldier = model.setCoords([-122.4194, 37.7749, 0]);
  
  // Selection
  soldier.addEventListener('SelectedChange', (e) => {
    if (e.detail.selected) {
      console.log('Object selected');
      document.getElementById('deleteBtn').disabled = false;
    } else {
      console.log('Object unselected');
      document.getElementById('deleteBtn').disabled = true;
    }
  });
  
  // Mouse interaction
  soldier.addEventListener('ObjectMouseOver', (e) => {
    map.getCanvas().style.cursor = 'pointer';
  });
  
  soldier.addEventListener('ObjectMouseOut', (e) => {
    map.getCanvas().style.cursor = '';
  });
  
  // Drag and drop
  soldier.addEventListener('ObjectDragged', (e) => {
    const newCoords = e.detail.coordinates;
    console.log(`Object dragged (${e.detail.draggedAction}):`, newCoords);
    
    // Save to backend
    saveObjectPosition(e.detail.uuid, newCoords);
  });
  
  // Wireframe toggle
  soldier.addEventListener('Wireframed', (e) => {
    console.log('Wireframe:', e.detail.wireframe);
  });
  
  // Animation
  soldier.addEventListener('IsPlayingChanged', (e) => {
    updateAnimationControls(e.detail.isPlaying);
  });
  
  tb.add(soldier);
});

Removing Event Listeners

// Store reference to handler function
function onSelected(e) {
  console.log('Selected:', e.detail.selected);
}

// Add listener
obj.addEventListener('SelectedChange', onSelected);

// Remove listener when needed
obj.removeEventListener('SelectedChange', onSelected);

Build docs developers (and LLMs) love