Edit in JSFiddle

      // create a canvas element to draw dynamic tiles
      // interesting tidbit: it's inefficient to create a new canvas for each tile
      // however, JavaScript is single threaded so we can use the same canvas to draw each tile
      var canvas = document.createElement( "canvas" );

      // the size of the canvas element matches the size of a tile
      canvas.width = 256;
      canvas.height = 256;

      // grab a 2d context to draw onto the canvas element
      var context = canvas.getContext( "2d" );

      // a link to the jsFiddle logo :)
      // drawn on every tile
      var logoUrl = "/favicon.ico";

      // create a map
      var map = $( "#map" ).geomap( {
        center: [ -71.0595678, 42.3604823 ],
        zoom: 8,
        services: [ {
          type: "tiled",
          src: function( view ) {
            // create a new Defer object for this tile request
            var defer = new jQuery.Deferred();

            // for this example, every tile will also contain the jQuery Geo logo :)

            // interesting tidbit:
            // you might /want/ to build a URL to an OpenStreetMap tile here
            // however, that is a cross domain security error when we call toDataURL below
            // http://stackoverflow.com/questions/2390232/why-does-canvas-todataurl-throw-a-security-exception

            // if you really want to get OSM map tiles and draw on them,
            // you will have to proxy them from your own website/domain

            // create a new img element where we will download an image
            var img = new Image( );
            
            // hook into the load event
            img.onload = function( ) {
              // this callback is triggered when the tile is done being downloaded to the img element

              // at this point, we have already returned the Deferred object
              // to jQuery Geo for the current tile so it can calculate other tiles; neat!

              // clear the canvas to draw a new tile
              context.clearRect( 0, 0, 256, 256 );

              // draw a small version of our logo on the top-right corner of the tile
              context.drawImage( img, 208, 16, 32, 32 );

              // draw a border for the tile
              context.strokeRect( 0, 0, 255, 255 );

              // use $.geo.proj to convert the bbox to lon, lat
              var geodeticBbox = $.geo.proj.toGeodetic( view.bbox );

              // however, make it look nicer by rounding the numbers
              geodeticBbox[ 0 ] = geodeticBbox[ 0 ].toFixed( 2 );
              geodeticBbox[ 1 ] = geodeticBbox[ 1 ].toFixed( 2 );
              geodeticBbox[ 2 ] = geodeticBbox[ 2 ].toFixed( 2 );
              geodeticBbox[ 3 ] = geodeticBbox[ 3 ].toFixed( 2 );

              // draw the tile dimensions to the tile
              context.strokeText( "[ " + geodeticBbox.join( ", " ) + " ]", 32, 96 );

              // we are done, resolve the deferred object and complete this tile
              // the image is returned to jQuery Geo as a data URL thanks to canvas
              defer.resolve( canvas.toDataURL( "image/png" ) );
            };

            // now that we've hooked up our load handler,
            // we have to set the image's src attribute to get things going
            img.src = logoUrl;

            // return the Deferred object so the map widget can wait for done to be triggered
            return defer;
          }
        } ]
      } );
    <div id="map">
    </div>
    #map
    {
      position: fixed;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
    }

External resources loaded into this fiddle: