<img id='i' /><img id='i2' />
// Closures including constants and other precalculated values.
// SphericalMercator constructor: precaches calculations
// for fast tile lookups.
function SphericalMercator(options) {
this.size = options.size || 256;
var c = cache[this.size] = {};
for (var d = 0; d < 30; d++) {
c.Cc.push(size / (2 * Math.PI));
this.Bc = cache[this.size].Bc;
this.Cc = cache[this.size].Cc;
this.zc = cache[this.size].zc;
this.Ac = cache[this.size].Ac;
// Convert lon lat to screen pixel value
// - `ll` {Array} `[lon, lat]` array of geographic coordinates.
// - `zoom` {Number} zoom level.
SphericalMercator.prototype.px = function(ll, zoom) {
var f = Math.min(Math.max(Math.sin(D2R * ll[1]), -0.9999), 0.9999);
var x = Math.round(d + ll[0] * this.Bc[zoom]);
var y = Math.round(d + 0.5 * Math.log((1 + f) / (1 - f)) * (-this.Cc[zoom]));
(x > this.Ac[zoom]) && (x = this.Ac[zoom]);
(y > this.Ac[zoom]) && (y = this.Ac[zoom]);
// Convert screen pixel value to lon lat
// - `px` {Array} `[x, y]` array of geographic coordinates.
// - `zoom` {Number} zoom level.
SphericalMercator.prototype.ll = function(px, zoom) {
var g = (px[1] - this.zc[zoom]) / (-this.Cc[zoom]);
var lon = (px[0] - this.zc[zoom]) / this.Bc[zoom];
var lat = R2D * (2 * Math.atan(Math.exp(g)) - 0.5 * Math.PI);
var sph = new SphericalMercator();
var i = document.getElementById('i');
var i2 = document.getElementById('i2');
var loc = [-77.04,38.89];
i.src = 'https://api.tiles.mapbox.com/v3/mapbox.mapbox-light/' + loc + ',13/640x640.png';
var px = sph.px(loc, 13);
var loc2 = sph.ll(px, 13);
i2.src = 'https://api.tiles.mapbox.com/v3/mapbox.mapbox-light/' + loc2 + ',13/640x640.png';