An opacity control / transparency slider inspired by Klokan Petr Přidal's original Opacity Control for Google Maps (v2) Overlay. Borrowing from the original design but completely re-coded to work with the radically different Google Maps API v3.

Originally developed for use on NZ Topo Map, the essential components have been cleaned up and extracted for easy re-use in your own web sites.

Download source code: OpacityControl.zip

GitHub: gavinharriss/google-maps-v3-opacity-control

Slider Styles

The following sliders can be used to maintain a compatible look with different versions of Google Maps:

Google Maps v2 slider (Klokan Petr Přidal's original)
Google Maps v2 slider

Google Maps v3 - v3.6 slider
Google Maps v3 slider

Google Maps v3.7 - v3.13 slider
Google Maps v3.7 slider

Google Maps v3.14 slider
Google Maps v3.14 slider

Custom Tile Overlay Code Highlights

There's some useful techniques used in the custom tile overlay (CustomTileOverlay.js) that can be used in isolation:

Deleting Tiles Outside the Visible Bounds

If tiles are allowed to accumulate they can cause memory issues, especially on devices such as the iPhone. The solution is to delete them when they are no longer within the visible bounds of the map.

Code to delete tiles outside of the visible map bounds:

CustomTileOverlay.prototype.deleteHiddenTiles = function (zoom) {
    var bounds = this.map.getBounds();
    var tileNE = this.getTileUrlCoordFromLatLng(bounds.getNorthEast(), zoom);
    var tileSW = this.getTileUrlCoordFromLatLng(bounds.getSouthWest(), zoom);
    var minX = tileSW.x - 1;
    var maxX = tileNE.x + 1;
    var minY = tileSW.y - 1;
    var maxY = tileNE.y + 1;
    var tilesToKeep = [];
    var tilesLength = this.tiles.length;
    for (var i = 0; i < tilesLength; i++) {
        
		// Get the x, y and zoom components from the tile url
		var idParts = this.tiles[i].id.split("_");
		var tileX = Number(idParts[1]);
        var tileY = Number(idParts[2]);
        var tileZ = Number(idParts[3]);
        
		if ((
                (minX < maxX && (tileX >= minX && tileX <= maxX))
                || (minX > maxX && ((tileX >= minX && tileX <= (Math.pow(2, zoom) - 1)) || (tileX >= 0 && tileX <= maxX))) // Lapped the earth!
            )
            && (tileY >= minY && tileY <= maxY)
            && tileZ == zoom) {
            tilesToKeep.push(this.tiles[i]);
        }
        else {
            delete this.tiles[i];
        }
    }
    
    this.tiles = tilesToKeep;
}

Hooking it up to the map tiles loaded event:

google.maps.event.addListener(map, 'tilesloaded', function () {
    overlay.deleteHiddenTiles(map.getZoom());
});

Consuming Tiles Generated using MapTiler / GDAL2Tiles

The example code provided serves tiles up from a single location but MapTiler and GDAL2Tiles generate a hierarchical set of tiles by default. It's very easy to adapt the code simply swap the - chars in the tile file name for / chars, reconstructing the original hierarchy structure.

Original example code:

CustomTileOverlay.prototype.getTileUrl = function (coord, zoom) {
    // Restricting tiles to the small tile set we have in the example
	if (zoom == 13 && coord.x >= 8004 && coord.x <= 8006 && coord.y >= 3013 && coord.y <= 3015) {
        return "/tiles/" + zoom + "-" + coord.x + "-" + coord.y + ".png";
    }
    else {
        return "/tiles/blanktile.png";
    }
}

Needs changing to this:

CustomTileOverlay.prototype.getTileUrl = function (coord, zoom) {
    // Restricting tiles to the small tile set we have in the example
	if (zoom == 13 && coord.x >= 8004 && coord.x <= 8006 && coord.y >= 3013 && coord.y <= 3015) {
        return "/tiles/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
    }
    else {
        return "/tiles/blanktile.png";
    }
}

Updates

Nov 13th 2013: Google Maps API v3.14 visual refresh.

Apr 13th 2012: Fixed issue in Firefox where opacity control wasn't working if slid all the way to the left.



All code is licensed under a Creative Commons Attribution 3.0 New Zealand License.