TNS
VOXPOP
Terraform or Bust?
Has your organization used or evaluated a Terraform alternative since new restrictions were placed on its licensing?
We have used Terraform, but are now piloting or using an open source alternative like OpenTofu.
0%
We never used Terraform, but have recently piloted or used alternatives.
0%
We don't use Terraform and don't plan to use or evaluate alternatives.
0%
We use Terraform and are satisfied with the results
0%
We are waiting to see what IBM will do with Terraform.
0%
Frontend Development / JavaScript

Recreating Shopify’s BFCM Globe Using react-globe.gl

Developer Paul Scanlon shows how to recreate Shopify's 3D Thanksgiving globe, using a React component for globe data visualization.
Dec 15th, 2023 7:23am by
Featued image for: Recreating Shopify’s BFCM Globe Using react-globe.gl

Did you see this year’s BFCM (Black Friday Cyber Monday) Globe from Shopify? I did, and loved it. Every year the Shopify team knocks it out of the park and this year was no exception! However, unless you possess NASA level WebGL engineering skills, creating a 3D globe is hard. Fortunately react-globe.gl by Vasco Asturiano is here to help. I’ve used this library on a number of occasions, but this time I wanted to see how close I could get to Shopify’s BFCM ‘23 globe.

You can see a preview and all the code referenced in this post on the links below.

But before I explain how I created the Globe, I’ll talk you through the fundamentals of using react-globe-gl.

Installation

To use react-globe.gl, you’ll first need to install it.


Once the package has been installed, you’ll need to import it.

Basic Image
3D Globe basic earth image

In this example, I’ll cover the basics of creating the Globe, adding an image so the globe looks like earth, and how you can plot points around the globe.

globeImageUrl

Using this prop you can pass a real earth image to be rendered on the globe. To ensure real latitude and longitude points line up with the countries, the earth image needs to be prepared correctly. At the following link, you’ll find a number of variations to choose from; all will work with react-globe.gl: https://unpkg.com/browse/world-atlas@2.0.2/

pointsData

This array of data holds four key value pairs. Each should be self explanatory enough and when passed on to the globe using pointsData prop, will appear in their correction geographical locations.

pointAltitude

This prop allows you to set the “size” of each of the points. The higher the number, the “taller” the point. The string passed to this prop is a key name from the data array.

pointColor

This prop allows you to set the color for each of the points. The string passed to this prop is a key name from the data array.

GeoJson Hexagon

3D Globe Hexagons

In this example, I use geojson data to display the countries of the world as hexagons, instead of using an image of earth.

hexPolygonsData

Using this prop you can pass real world geojson data to be rendered on the globe, instead of an image. On the following link you’ll find a number of data sets that can be used: https://unpkg.com/browse/world-atlas@2.0.2/

hexPolygonColor

This prop can be used to change the color of each country. To determine which color from the first array to use, I use JavaScript’s Remainder, or modulo operator to create an index based on the length of the countries’ abbreviation codes that are returned from the geometry parameter.

Geojson Polygon

3D Globe Polygons

In this example, I use geojson data to display the countries of the world as polygons, instead of using an image of Earth.

polygonsData

Using this prop you can pass real world geojson data to be rendered on the globe, instead of an image. On the following link you’ll find a number of data sets that can be used: https://unpkg.com/browse/world-atlas@2.0.2/

polygonCapColor

This prop can be used to change the color of each country. To determine which color from the first array to use I use JavaScript’s Remainder, or modulo operator to create an index based on the length of the countries’ abbreviation codes that are returned from the geometry parameter.

polygonSideColor

Similar to above, this prop controls the color of the “edges” of each country.

polygonAltitude

This prop raises the level of the polygons (you’ll notice the “edge” colors more when using this prop).

Arcs
3D Globe Arcs Data

In this example, I connect the points to one another using arcs. There are a few more configuration options for using arcs, but the same method I mentioned earlier about providing a key name from the data object still applies.

arcsData

This is the data array used to position the arcs.

arcColor

A key identifier from the data array is used to change the color of the arcs. The color values can be an array, meaning you can create a “gradient” effect where the arc starts and finishes using different colors.

arcStroke

This is the thickness of the arc.

arcDashGap

This is the gap between each “dash” on the stroke.

arcDashLength

This is the size of the “dash” on the stroke.

arcAltitudeAutoScale

This prop determines how far from the globe surface the arc should be positioned.

arcDashAnimateTime

This is the speed of the arc animation.

Rings

3D Globe rings data

In this example, I add pulsating rings to the globe. There are a few more configuration options for using rings, but the same method I mentioned earlier about providing a key name from the data object still applies.

ringsData

This is the data array used to position the rings.

ringMaxRadius

This determines how large each ring should be.

ringColor

This is slightly different than before with the arcs color as I curry the time parameter and use it as the alpha value of an rgba color reference. This allows the ring to fade out as it grows.

ringPropagationSpeed

The speed the rings animate.

ringRepeatPeriod

The speed the rings are generated.

HTML Marker

3D Globe HTML Marker

In this example, I use a Svg icon to act as a “marker” for each of the positions in the data array. You can use any HTML element(s) you like to create a marker and any of the values from the data array can be abstracted from the data prop.

htmlElementsData

The data used to position the points/marker.

htmlAltitude

This is the distance above the globe’s surface where the marker should be positioned.

htmlElement

The HTML Element is to be displayed as a marker. The data prop can be used to access any of the data from the data array.

Custom Layer
3D Globe Custom Layer

This example is slightly different as it’s not used to add elements to the globe itself but rather, to add elements to the atmosphere that surrounds the globe; or in this case, suns/stars in the universe.

customLayerData

The key value pairs I’ve used here are similar to the values used in all the other example data arrays, but this time I’m creating 500 new “points” and randomly setting their lat/lng positions, altitude, color and size.

customThreeObject

This is the three.js geometry and material used to create a new three.js “shape”. I can access the size and color by destructuring their values from the data parameter.

customThreeObjectUpdate

In order for the custom layer to move with the globe when it’s rotated or zoomed, I grab a reference to the globe using a React ref and set the position of each of the “points” so they are relative to the globe’s current rotation or position.

… that’s the basics done and I’ve used some of the above methods to create the finished globe.

Finished

3D Globe Finished

Now for a couple of things I’ve not already covered in this example; namely, how to auto-rotate the globe and the use of a texture.

onGlobeReady

This prop can be used to call a function when the globe has fully loaded. The globeReady function can then access the globe via the React ref and there are a number of functions that can be used to control the globe. To make the globe rotate, you can use the autoRotate function.

polygonsData

This method uses a slightly different approach. To ensure the countries were flat (with no depth) I’ve used a different geojson file. To translate the geojson into data that react-globe.gl can use, I’ve used topojson-client.

polygonCapMaterial

This is where I apply a texture to each of the countries, instead of the method I explained earlier which simply sets each country to a different color.

And that’s it. It’s far from a “recreation” of the Shopify team’s impressive work, but it’s close enough for me.

If you have any questions about the methods I’ve used in this post, feel free to come and find me on Twitter/X: PaulieScanlon.

Group Created with Sketch.
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.