When we’re rapidly iterating on creative map designs at Stamen, one source of friction is testing new map icons in a live map. Designers often have to resort to mock-ups of marker designs on a static map, which makes it hard to see how the icons really perform. Or we go through manual steps each iteration to test the designs for real. This adds time and effort to what should be an iterative design exercise, and anything we can do to make it easier for designers and technologists to easily collaborate is of great interest.
Many of our interactive web maps are based on Mapbox GL JS, a powerful and performant mapping platform. For marker and UI element designs, we’ve increasingly been relying on Figma for our projects, especially since the pandemic forced us all to work remotely.
To update those marker designs in a Mapbox map, however, the only obvious way is to export every image, upload them into Mapbox Studio, and redeploy the style sheet. But it’s clunky, and the cartographer working on the basemap design now has to synchronize with the designer’s marker iterations. This extra step makes it harder to work cooperatively, which is how we like to work at Stamen.
We’d like to share a tool we’re calling Figmasset — because it makes Figma the live source of our assets. Figmasset works like this:
- During design iteration, your marker designs live in Figma. FigmassetJS loads these assets as icons in your map when it loads.
- Once your designs stabilize, you use Figmasset-Export to export all the assets into your application, or as a Mapbox sprite sheet.
This process really helps when we work on fast-paced projects with multiple designers, cartographers and developers turning around new versions of maps and markers every few days for client demos. Designers can ship new marker designs straight into the demo without needing to sync with either developers or cartographers — which makes the whole process much more pleasant and collaborative.
How it works for designers
- Choose a Figma file and page to use as the home for “Live assets”. It’s good to label it accordingly, so everyone knows that changes here have immediate impact.
- Create a frame that holds the assets. Give it a name like “map-icons-base” or something.
- Put assets as top-level children inside this frame. Give them names that will be used as semantic identifiers, preferably lower case with no commas or spaces. “pin-selected” is a better name than “red pin”.
- Make a note of the file key. That’s the part of the URL straight after file/. So if your URL is https://www.figma.com/file/BEAGFwgYIJThhoIDT4tp1Y/Pins, the file key is BEAGFwgYIJThhoIDT4tp1Y.
- Create an API key, under “Settings” under your profile. Be aware that anyone who has access to this API key can access all your work, so only use this for internal development.
Your setup should look like this:
How it works for developers
Our NPM package figmasset connects to the Figma API, requests image versions of the appropriate assets and returns information about them.
For example, to load all the assets from the “pins” frame, with additional replacements from the “pins-alt-clustering” frame:
import { loadFigmassets } from ‘figmasset’;
// …
loadFigmassets({
map, // Mapbox GL JS or Maplibre GL JS object
frameNames = [‘pins’, ‘pins-alt-clustering’],
fileKey: ‘BEAGFwgYIJThhoIDT4tp1Y’,
personalAccessToken: ‘YOURFIGMATOKENHERE’,
});
Now your map contains icons “pin”, “pin-cluster”, “pin-selected” and “pin-cluster-selected”. See the package documentation for more details.
(Again, be careful about exposing the Figma token!)
Exporting
You can use figmasset-export to save all the assets into your web app once they are stable. For instance, let’s assume you have a public directory called “static”:
cd static
npx figmasset-export --file BEAGFwgYIJThhoIDT4tp1Y --token snt34h5sn24h5 --frame ‘pins,pins-alt-clustering --scales 2
You can now replace the “loadFigmaAssets()” call with this:
loadStoredFigmassets({ map, path: ‘static/assets@2x’ });
We’re committed at Stamen to making as well as using open source tools like this one. If you’ve found this at all useful, or if you’ve got any questions or suggestions for us, drop us a line, won’t you?