body {
  margin: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
/*
* https://deck.gl/docs/api-reference/extensions/data-filter-extension
*/

const data = (function(pointCount) {
  const points = new Array(pointCount);
  for (let i = 0, a = 0, r = 1; i < pointCount; i++) {
    points[i] = {
      position: [Math.cos(a) * r, Math.sin(a) * r],
      color: [(Math.cos(a) + 1) / 2 * 255, (Math.sin(a) + 1) / 2 * 255, 128],
      time: i
    };
    a += Math.PI / r;
    r += 2 / r;
  }
  return points;
})(20000);

const {Deck, OrthographicView, DataFilterExtension, ScatterplotLayer} = deck;

let isPlaying = true;
let filterMin = 0;
const filterSpan = 1000;
const maxTime = data[data.length - 1].time;

const deckgl = new Deck({
  views: new OrthographicView(),
  initialViewState: {
    target: [0, 0, 0],
    zoom: 1,
    minZoom: 0
  },
  controller: true,
  onClick: () => {
    isPlaying = !isPlaying;
    isPlaying && redraw();
  }
});

redraw();

function redraw() {
  if (filterMin < maxTime) {
    filterMin += 10;
  } else {
    filterMin = -filterSpan;
  }
  
  deckgl.setProps({layers: [
    new ScatterplotLayer({
      id: 'filtered',
      data,
      getPosition: d => d.position,
      getRadius: 1.5,
      getFillColor: d => d.color,
      
      // props added by DataFilterExtension
      getFilterValue: d => d.time,
      filterRange: [filterMin, filterMin + filterSpan],
      filterSoftRange: [filterMin + filterSpan * 0.8, filterMin + filterSpan],
      // filterTransformSize: true,
      // filterTransformColor: true,
      // filterEnabled: true,

      extensions: [new DataFilterExtension({filterSize: 1})]
    }),
    new ScatterplotLayer({
      id: 'all',
      data,
      getPosition: d => d.position,
      getRadius: 0.5,
      getFillColor: [0, 0, 0],
      radiusMaxPixels: 1
    })
  ]});
  
  if (isPlaying) {
    requestAnimationFrame(redraw);
  }
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/deck.gl@^8.9.0/dist.min.js