Introducing react-map-interaction for zooming & panning in React

A typical scientist will describe a protocol as a series of steps, like:

  1. Prepare opaque-walled multi-well plates with mammalian cells in culture medium, 100µl per well for 96-well plates or 25µl per well for 384-well plates.
  2. Prepare control wells containing medium without cells to obtain a value for background luminescence.
  3. Add the test compound to experimental wells, and incubate according to culture protocol.
  4. Equilibrate the plate and its contents at room temperature for approximately 30 minutes.
  5. ...

One big issue with writing the steps as a list is that you cannot see what steps can be run in parallel. Strateos uses Autoprotocol to represent scientific protocols, which is a machine readable format that clearly shows the dependencies between these steps. This allows us to render the experiment as a "Task Graph" – a directed acyclic graph of steps in the experiment (below).

Task graphs can tend to get very large with sometimes 100s of tasks within a graph. We wanted to make it more intuitive to explore these task graphs no matter what the size. The goal became to add zooming and panning, on both desktop and mobile, similar to the experience you would have on Google maps. Our frontend is built with React, and unfortunately we didn't find any out of the box solution that met all of these criteria.

One thing that very few libraries did was to translate the zoom/pan action in such a way that the point under your cursor (or between your pinched fingers) wouldn't drift away as you zoomed in and out. This requires some tricky state management and a bit of geometry to do well without introducing any janky movements. It's also difficult to respond properly to all possible UX interactions (like zooming in the middle of a drag, or multiple fingers coming and going during a zoom).

react-map-interaction

To solve this, we built a React component called react-map-interaction. This component adds map-like zooming and panning to any React element. It works on both touch devices (pinch to zoom, drag to pan) as well as with a mouse or trackpad (wheel scroll to zoom, mouse drag to pan).

A GIF demonstrating the panning and zooming capability added to a react component.
transcriptic/react-map-interaction
Add map like zooming and dragging to any element. Contribute to transcriptic/react-map-interaction development by creating an account on GitHub.

How to use react-map-interaction

Install

npm install --save react-map-interaction

Examples

We use storybook in development, and you can pull the repo from Github and run storybook with npm run storybook. See files with *.stories.* for examples.

Basic

import { MapInteractionCSS } from 'react-map-interaction';

// This component uses CSS to scale your content.
// Just pass in content as children and it will take care of the rest.
const ThingMap = () => {
  return (
    <MapInteractionCSS>
      <img src="path/to/thing.png" />
    </MapInteractionCSS>
  );
}

Usage without CSS

import { MapInteraction } from 'react-map-interaction';

// Use MapInteraction if you want to determine how to use the resulting translation.
const NotUsingCSS = () => {
  return (
    <MapInteraction>
      {
        ({ translation, scale }) => { /* Use the passed values to scale content on your own. */ }
      }
    </MapInteraction>
  );
}

Development

We're really pleased to make this tool open source and available for use in your React projects. Please feel free to file issues or put up a PR on the github repository.

If you enjoy using React and want to help scientists make their next big discoveries, we're hiring!

Careers at Strateos | Strateos
At Strateos, individuals are empowered to think creatively to solve problems and answer hard questions with well researched data. We work in an collaborative environment where everyone is encouraged to do their best work supported by a team of peers.

Cover Art

Illustration by Icons8