or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

application-management.mdattribute-management.mdcontrollers.mdcoordinate-systems.mdeffects-and-lighting.mdindex.mdlayer-system.mdtransitions-and-animation.mdutilities-and-helpers.mdviews-and-viewports.md
tile.json

transitions-and-animation.mddocs/

Transitions and Animation

Smooth animation system with interpolation support for view state transitions and layer property changes, enabling fluid user experiences and dynamic data visualization.

Capabilities

TransitionInterpolator Base Class

Abstract base class defining interface for view state interpolation during transitions.

/**
 * Abstract base class for transition interpolators
 * Defines interface for smooth transitions between view states
 */
abstract class TransitionInterpolator {
  /** Compare transition properties for equality */
  arePropsEqual(props1: any, props2: any): boolean;
  
  /** Initialize transition properties */
  initializeProps(startProps: any, endProps: any): {start: any; end: any};
  
  /** Interpolate properties at given time t [0-1] */
  interpolateProps(startProps: any, endProps: any, t: number): any;
  
  /** Get transition duration in milliseconds */
  getDuration?(startProps: any, endProps: any): number;
}

LinearInterpolator

Linear interpolation between view states for simple transitions.

/**
 * Linear interpolation between view states
 * Provides smooth linear transitions for specified properties
 */
class LinearInterpolator extends TransitionInterpolator {
  /** Initialize linear interpolator */
  constructor(transitionProps?: string[]);
  
  /** Properties to interpolate */
  readonly transitionProps: string[];
  
  /** Compare properties for changes */
  arePropsEqual(props1: any, props2: any): boolean;
  
  /** Initialize interpolation */
  initializeProps(startProps: any, endProps: any): {start: any; end: any};
  
  /** Linear interpolation at time t */
  interpolateProps(startProps: any, endProps: any, t: number): any;
}

Usage Examples:

import { LinearInterpolator } from "@deck.gl/core";

// Simple zoom transition
const zoomInterpolator = new LinearInterpolator(['zoom']);

// Smooth transition to new zoom level
deck.setProps({
  viewState: {
    ...currentViewState,
    zoom: 15,
    transitionDuration: 1000,
    transitionInterpolator: zoomInterpolator
  }
});

// Multi-property transition
const positionInterpolator = new LinearInterpolator([
  'longitude', 
  'latitude', 
  'zoom', 
  'pitch', 
  'bearing'
]);

deck.setProps({
  viewState: {
    longitude: -74.006,
    latitude: 40.7128,
    zoom: 14,
    pitch: 45,
    bearing: 30,
    transitionDuration: 2000,
    transitionInterpolator: positionInterpolator,
    transitionEasing: t => t * t // Quadratic easing
  }
});

FlyToInterpolator

Smooth camera flight transitions with easing for natural map navigation.

/**
 * Smooth camera flight interpolator
 * Provides natural arc-based transitions between geographic locations
 */
class FlyToInterpolator extends TransitionInterpolator {
  /** Initialize fly-to interpolator */
  constructor(opts?: FlyToInterpolatorOptions);
  
  /** Compare properties for fly-to transition */
  arePropsEqual(props1: any, props2: any): boolean;
  
  /** Initialize fly-to transition */
  initializeProps(startProps: any, endProps: any): {start: any; end: any};
  
  /** Fly-to interpolation with arc movement */
  interpolateProps(startProps: any, endProps: any, t: number): any;
  
  /** Calculate optimal duration based on distance */
  getDuration(startProps: any, endProps: any): number;
  
  /** Flight speed constant */
  readonly speed: number;
  
  /** Flight curve parameter */
  readonly curve: number;
  
  /** Screen space speed factor */
  readonly screenSpeedFactor: number;
  
  /** Maximum duration limit */
  readonly maxDuration: number;
}

interface FlyToInterpolatorOptions {
  /** Flight speed (higher = faster) */
  speed?: number;
  
  /** Flight curve (1 = linear, >1 = curved) */
  curve?: number;
  
  /** Screen space speed adjustment */
  screenSpeedFactor?: number;
  
  /** Maximum transition duration */
  maxDuration?: number;
}

Usage Examples:

import { FlyToInterpolator } from "@deck.gl/core";

// Natural flight between cities
const flyToNewYork = () => {
  deck.setProps({
    viewState: {
      longitude: -74.006,
      latitude: 40.7128,
      zoom: 14,
      pitch: 45,
      bearing: 0,
      transitionInterpolator: new FlyToInterpolator({
        speed: 1.5,
        curve: 1.414
      }),
      onTransitionStart: () => {
        console.log('Flying to New York...');
      },
      onTransitionEnd: () => {
        console.log('Arrived in New York!');
      }
    }
  });
};

// Long-distance flight with custom settings
const flyToTokyo = () => {
  deck.setProps({
    viewState: {
      longitude: 139.6917,
      latitude: 35.6895,
      zoom: 12,
      pitch: 30,
      bearing: 90,
      transitionInterpolator: new FlyToInterpolator({
        speed: 2.0,        // Faster flight
        curve: 2.0,        // More curved path
        maxDuration: 8000  // Max 8 seconds
      })
    }
  });
};

// Fly to bounds
const flyToBounds = (bounds) => {
  const viewport = new WebMercatorViewport({
    width: deck.width,
    height: deck.height,
    ...deck.viewState
  });
  
  const fittedViewState = viewport.fitBounds(bounds, {
    padding: 50
  });
  
  deck.setProps({
    viewState: {
      ...fittedViewState,
      transitionInterpolator: new FlyToInterpolator(),
      transitionDuration: 3000
    }
  });
};

View State Transitions

Transition Configuration

Comprehensive transition configuration options for view states.

interface ViewStateTransition {
  /** Target view state */
  viewState: any;
  
  /** Transition duration in milliseconds */
  transitionDuration?: number;
  
  /** Transition interpolator */
  transitionInterpolator?: TransitionInterpolator;
  
  /** Easing function [0-1] -> [0-1] */
  transitionEasing?: (t: number) => number;
  
  /** Interruption behavior */
  transitionInterruption?: 'break' | 'snap-to-end' | 'ignore';
  
  /** Called when transition starts */
  onTransitionStart?: () => void;
  
  /** Called during transition with current state */
  onTransitionUpdate?: (viewState: any) => void;
  
  /** Called when transition completes */
  onTransitionEnd?: () => void;
  
  /** Called when transition is interrupted */
  onTransitionInterrupt?: () => void;
}

// Transition event constants
const TRANSITION_EVENTS: {
  readonly BREAK: "transitionBreak";
  readonly SNAP_TO_END: "transitionSnapToEnd";
  readonly UPDATE: "transitionUpdate";
  readonly END: "transitionEnd";
};

Usage Examples:

// Advanced transition with callbacks
const smoothTransition = {
  longitude: -122.4,
  latitude: 37.8,
  zoom: 16,
  pitch: 60,
  bearing: 45,
  
  transitionDuration: 3000,
  transitionInterpolator: new FlyToInterpolator({
    speed: 1.2,
    curve: 1.6
  }),
  
  // Custom easing function
  transitionEasing: t => {
    // Ease-in-out cubic
    return t < 0.5 
      ? 4 * t * t * t 
      : 1 - Math.pow(-2 * t + 2, 3) / 2;
  },
  
  transitionInterruption: 'break',
  
  onTransitionStart: () => {
    console.log('Transition started');
    showLoadingIndicator();
  },
  
  onTransitionUpdate: (viewState) => {
    updateProgressBar(viewState.transitionProgress);
  },
  
  onTransitionEnd: () => {
    console.log('Transition completed');
    hideLoadingIndicator();
  },
  
  onTransitionInterrupt: () => {
    console.log('Transition interrupted');
    hideLoadingIndicator();
  }
};

deck.setProps({ viewState: smoothTransition });

Layer Property Transitions

Layer Animation System

Built-in animation system for layer properties.

interface LayerTransitionSettings {
  /** Animation type */
  type?: 'interpolation' | 'spring' | 'gpu';
  
  /** Duration in milliseconds */
  duration?: number;
  
  /** Easing function */
  easing?: (t: number) => number;
  
  /** Called when animation starts */
  onStart?: () => void;
  
  /** Called during animation */
  onUpdate?: (t: number) => void;
  
  /** Called when animation ends */
  onEnd?: () => void;
  
  /** Enable GPU-based transitions */
  useGPU?: boolean;
  
  /** Spring animation settings */
  stiffness?: number;
  damping?: number;
  mass?: number;
}

interface LayerTransitions {
  /** Transitions for each accessor property */
  [accessorName: string]: LayerTransitionSettings | number;
}

Usage Examples:

import { ScatterplotLayer } from "@deck.gl/layers";

// Layer with animated properties
const animatedLayer = new ScatterplotLayer({
  id: 'animated-points',
  data: data,
  getPosition: d => d.coordinates,
  getRadius: d => d.radius,
  getColor: d => d.color,
  
  // Configure transitions
  transitions: {
    // Smooth radius changes
    getRadius: {
      type: 'interpolation',
      duration: 1000,
      easing: t => 1 - Math.pow(1 - t, 3), // Ease-out cubic
      onStart: () => console.log('Radius animation started'),
      onEnd: () => console.log('Radius animation ended')
    },
    
    // Spring animation for colors
    getColor: {
      type: 'spring',
      stiffness: 0.1,
      damping: 0.8,
      mass: 1
    },
    
    // Quick position updates
    getPosition: 500 // Shorthand for 500ms linear interpolation
  }
});

// Update data with transitions
const updateWithAnimation = (newData) => {
  animatedLayer.setProps({
    data: newData,
    updateTriggers: {
      getRadius: Math.random(),
      getColor: Math.random(),
      getPosition: Math.random()
    }
  });
};

// Animate data changes over time
const animateData = () => {
  const animatedData = data.map(d => ({
    ...d,
    radius: d.radius * (0.5 + Math.random()),
    color: [
      Math.floor(Math.random() * 255),
      Math.floor(Math.random() * 255),
      Math.floor(Math.random() * 255),
      255
    ]
  }));
  
  updateWithAnimation(animatedData);
};

setInterval(animateData, 2000);

GPU-Accelerated Transitions

GPU Transition System

High-performance GPU-based transitions for large datasets.

interface GPUTransitionSettings extends LayerTransitionSettings {
  /** Force GPU implementation */
  useGPU: true;
  
  /** Buffer size for GPU computation */
  bufferSize?: number;
  
  /** Shader-based interpolation function */
  interpolationShader?: string;
  
  /** GPU memory optimization */
  memoryOptimized?: boolean;
}

Usage Examples:

// Large dataset with GPU transitions
const largeDataLayer = new ScatterplotLayer({
  id: 'million-points',
  data: millionPointsData,
  getPosition: d => d.coordinates,
  getRadius: d => d.radius,
  getColor: d => d.color,
  
  transitions: {
    getRadius: {
      type: 'gpu',
      useGPU: true,
      duration: 2000,
      memoryOptimized: true,
      bufferSize: 1024 * 1024 // 1MB buffer
    },
    
    getColor: {
      type: 'gpu', 
      useGPU: true,
      duration: 1500,
      interpolationShader: `
        vec4 interpolateColor(vec4 from, vec4 to, float t) {
          // Custom GPU interpolation
          return mix(from, to, smoothstep(0.0, 1.0, t));
        }
      `
    }
  }
});

Animation Utilities

Easing Functions

Built-in easing functions for smooth animations.

// Common easing functions
const EASING_FUNCTIONS = {
  linear: (t: number) => t,
  
  // Ease-in functions
  easeInQuad: (t: number) => t * t,
  easeInCubic: (t: number) => t * t * t,
  easeInQuart: (t: number) => t * t * t * t,
  easeInQuint: (t: number) => t * t * t * t * t,
  easeInSine: (t: number) => 1 - Math.cos(t * Math.PI / 2),
  easeInExpo: (t: number) => t === 0 ? 0 : Math.pow(2, 10 * (t - 1)),
  easeInCirc: (t: number) => 1 - Math.sqrt(1 - t * t),
  
  // Ease-out functions  
  easeOutQuad: (t: number) => t * (2 - t),
  easeOutCubic: (t: number) => 1 - Math.pow(1 - t, 3),
  easeOutQuart: (t: number) => 1 - Math.pow(1 - t, 4),
  easeOutQuint: (t: number) => 1 - Math.pow(1 - t, 5),
  easeOutSine: (t: number) => Math.sin(t * Math.PI / 2),
  easeOutExpo: (t: number) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t),
  easeOutCirc: (t: number) => Math.sqrt(1 - Math.pow(t - 1, 2)),
  
  // Ease-in-out functions
  easeInOutQuad: (t: number) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
  easeInOutCubic: (t: number) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
  easeInOutQuart: (t: number) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * Math.pow(t - 1, 4),
  easeInOutQuint: (t: number) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * Math.pow(t - 1, 5),
  easeInOutSine: (t: number) => -(Math.cos(Math.PI * t) - 1) / 2,
  easeInOutExpo: (t: number) => t === 0 ? 0 : t === 1 ? 1 : t < 0.5 ? Math.pow(2, 20 * t - 10) / 2 : (2 - Math.pow(2, -20 * t + 10)) / 2,
  easeInOutCirc: (t: number) => t < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2,
  
  // Bounce and elastic
  easeOutBounce: (t: number) => {
    if (t < 1 / 2.75) return 7.5625 * t * t;
    if (t < 2 / 2.75) return 7.5625 * (t -= 1.5 / 2.75) * t + 0.75;
    if (t < 2.5 / 2.75) return 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375;
    return 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375;
  },
  
  easeOutElastic: (t: number) => {
    const c4 = (2 * Math.PI) / 3;
    return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
  }
};

Timeline Animation

Advanced timeline-based animation system.

interface AnimationTimeline {
  /** Add animation to timeline */
  add(opts: {
    target: any;
    property: string;
    from: any;
    to: any;
    duration: number;
    delay?: number;
    easing?: (t: number) => number;
  }): void;
  
  /** Play timeline */
  play(): void;
  
  /** Pause timeline */
  pause(): void;
  
  /** Stop and reset timeline */
  stop(): void;
  
  /** Seek to specific time */
  seek(time: number): void;
  
  /** Timeline duration */
  readonly duration: number;
  
  /** Current playback time */
  readonly currentTime: number;
  
  /** Whether timeline is playing */
  readonly isPlaying: boolean;
}

Usage Examples:

// Complex animation sequence
const createAnimationSequence = () => {
  const timeline = new AnimationTimeline();
  
  // Animate camera to overview position
  timeline.add({
    target: deck,
    property: 'viewState',
    from: currentViewState,
    to: {
      longitude: -100,
      latitude: 40,
      zoom: 4,
      pitch: 45,
      bearing: 0
    },
    duration: 2000,
    easing: EASING_FUNCTIONS.easeInOutCubic
  });
  
  // Animate layer opacity
  timeline.add({
    target: layer,
    property: 'opacity',
    from: 0,
    to: 1,
    duration: 1000,
    delay: 1000,
    easing: EASING_FUNCTIONS.easeOutQuad
  });
  
  // Animate data reveal
  timeline.add({
    target: layer,
    property: 'radiusScale',
    from: 0,
    to: 1,
    duration: 1500,
    delay: 2000,
    easing: EASING_FUNCTIONS.easeOutElastic
  });
  
  return timeline;
};

// Orchestrate complex visualization intro
const introSequence = createAnimationSequence();
introSequence.play();

// Custom transition with progress tracking
const customTransition = (fromState, toState, onProgress) => {
  const interpolator = new FlyToInterpolator({
    speed: 1.5,
    curve: 1.414
  });
  
  deck.setProps({
    viewState: {
      ...toState,
      transitionInterpolator: interpolator,
      transitionDuration: 3000,
      transitionEasing: EASING_FUNCTIONS.easeInOutCubic,
      onTransitionUpdate: (viewState) => {
        const progress = viewState.transitionProgress || 0;
        onProgress(progress);
      }
    }
  });
};