Pure THREE.JS template

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/107/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>

CSS

.hudLabel {

  position: absolute;
  top: 0;
  left: 0;
  color: #000;
  font-family: 'Trebuchet MS', sans-serif;
  font-size: 22px;
  font-weight: normal;
  line-height: 24px;
  text-align: left;
  padding: 3px;

  /* http://www.cssmatic.com/box-shadow */
  -webkit-box-shadow: 0px 4px 8px -3px rgba(0, 0, 0, 0.75);
  -moz-box-shadow: 0px 4px 8px -3px rgba(0, 0, 0, 0.75);
  box-shadow: 0px 4px 8px -5px rgba(0, 0, 0, 0.75);
  background: rgba(255, 255, 255, 0.8);

}

JavaScript

var scene, renderer, camera, controls, label;

function _convertLatLonToVec3(lat, lon) {
  lat = lat * Math.PI / 180.0;
  lon = -lon * Math.PI / 180.0;
  return new THREE.Vector3(
    Math.cos(lat) * Math.cos(lon),
    Math.sin(lat),
    Math.cos(lat) * Math.sin(lon));
}

function InfoBox(city, radius, domElement) {
  this._screenVector = new THREE.Vector3(0, 0, 0);

  this.position = _convertLatLonToVec3(city.lat, city.lng).multiplyScalar(radius);

  // create html overlay box
  this.box = document.createElement('div');
  this.box.innerHTML = city.name;
  this.box.className = "hudLabel";

  this.domElement = domElement;
  this.domElement.appendChild(this.box);

}

InfoBox.prototype.update = function() {
  this._screenVector.copy(this.position);
  this._screenVector.project(camera);

  var posx = Math.round((this._screenVector.x + 1) * this.domElement.offsetWidth / 2);
  var posy = Math.round((1 - this._screenVector.y) * this.domElement.offsetHeight / 2);

  var boundingRect = this.box.getBoundingClientRect();

  // update the box overlays position
  this.box.style.left = (posx - boundingRect.width) + 'px';
  this.box.style.top = posy + 'px';
};

function init() {
  // basic scene
  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  var width = window.innerWidth;
  var height = window.innerHeight;

  renderer.setSize(width, height);
  renderer.setClearColor(0xffaa00, 1);

  document.body.appendChild(renderer.domElement);

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
  camera.position.y = 16;
  camera.position.z = 50;

  controls = new THREE.OrbitControls(camera, renderer.domElement);

  var gridXZ = new THREE.GridHelper(100, 10);
  scene.add(gridXZ);

  // globe

  var radius = 10;

  var sphere = new THREE.Mesh(new THREE.SphereGeometry(radius, 16, 16));
  scene.add(sphere);

  var city = {
    "name": "Hello",
    "lat": 42,
    "lng": 250
  };

  label = new InfoBox(city, radius,...