DEV Community

Cover image for Three.js text scenes on Google Maps are so-good-it-hurts πŸ™πŸ” πŸ˜Ž
Orhun Γ–zer
Orhun Γ–zer

Posted on • Edited on

Three.js text scenes on Google Maps are so-good-it-hurts πŸ™πŸ” πŸ˜Ž

I genuinely love 3D text tracking titles in movies like the example below. We are going to put the name of the city near a historic location in a similar way for this example. Only on a map.

Text tracking

Let me show you how I did something similar on google maps. Source code at the end πŸ‘‡

3d Text on the map

First you need to install dependencies

yarn add @googlemaps/js-api-loader @googlemaps/three three

Enter fullscreen mode Exit fullscreen mode

Import the libraries

import { ThreeJSOverlayView, latLngToVector3 } from '@googlemaps/three';

import { Loader } from '@googlemaps/js-api-loader';
Enter fullscreen mode Exit fullscreen mode

Before loading data make sure you have vector maps enabled from google console.

google vector maps


export const LOADER_OPTIONS = {
  apiKey: 'YOUR_API_KEY_HERE',
  version: 'beta', // to use beta features 
  libraries: [],
};

const mapOptions = {
  // location of Galata Tower at Istanbul
  center: {
    lat: 41.025615,
    lng: 28.974133,
  },
  zoom: 17,
  heading: 60,
  tilt: 50,
  mapId: 'OPTIONALLY_MAP_ID_HERE',
};

new Loader(LOADER_OPTIONS).load().then(() => {

... threejs stuff goes here 

})

Enter fullscreen mode Exit fullscreen mode

A three.js scene inside google maps is not much different than you would see in an ordinary Three.js scene. Therefor you have light and objects.

  // installing map here
  const map = new google.maps.Map(document.getElementById('map'), mapOptions);

  // creating new scene
  const scene = new THREE.Scene();

  const ambientLight = new THREE.AmbientLight(0xffffff, 0.75);
  scene.add(ambientLight);

  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.25);

  // default light comes from above
  directionalLight.position.set(0,1,0)
  directionalLight.intensity = 1
  scene.add(directionalLight);
  scene.add(directionalLightHelper);
Enter fullscreen mode Exit fullscreen mode

To render fonts within Three we will use FontLoader. I am using Helvetiker Regular font for this example. You can find it in the source code as well.

import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';

  const fontLoader = new FontLoader();

  fontLoader.load('./font.json', function (font) {

   ... font stuff here

  }
Enter fullscreen mode Exit fullscreen mode

We are going add Geometry and Material combined as a Mesh. You can't use pixel coordinates because you are rendering on a map. latLngToVector3 is going to do the transformation for us.

    const title = 'ISTANBUL';

    const titleGeom = new TextGeometry(title, {
      font: font,
      size: 80,
      ...
    });

    const textMaterial = new THREE.MeshPhongMaterial({
      color: 0xff2d00,
      specular: 0xffffff,
    });

    const titleMesh = new THREE.Mesh(titleGeom, textMaterial);
    // set position behind the tower
    titleMesh.position.copy(
      latLngToVector3({
        lat: 41.024615,
        lng: 28.974533,
      })
    );

    ...

    scene.add(titleMesh);

Enter fullscreen mode Exit fullscreen mode

Then we are going add the scene to the map. Here we are also enriching the experience with nice camera movement to get closer to the scene.

 // instantiate the ThreeJS Overlay with the scene and map
  const overlay = new ThreeJSOverlayView({
    scene,
    map,
    THREE,
  });
Enter fullscreen mode Exit fullscreen mode

Animation using requestAnimationFrame

const animate = () => {

    ...

    if (mapOptions.tilt < 67.5) {
      mapOptions.tilt += 0.5;
      mapOptions.heading += 1;
      mapOptions.zoom += 0.005;
    } else if (mapOptions.heading <= 210) {
      mapOptions.heading += 0.4;
      mapOptions.zoom += 0.007;
    } else {
      // exit animation loop
      return;
    }

    const { tilt, heading, zoom } = mapOptions;
    map.moveCamera({ tilt, heading, zoom });

    requestAnimationFrame(animate);
  };

  requestAnimationFrame(animate);
Enter fullscreen mode Exit fullscreen mode

Source code -> https://github.com/orabazu/threejs-text-googlemaps

Top comments (0)