HTML Canvas As Overlayview In Google Maps That Is Fixed Relative to the Map Canvas -


i'm trying create html5 canvas overlayview size of map, position top:0; left:0;, draw stuff on it, , add map. whenever map zooms or pans want remove old canvas map , create new canvas draw on position 0,0 , add map. map never reposition top:0; left:0. can help?

    function customlayer(map){ this.latlngs = new array(); this.map_ = map;  this.addmarker = function(position){ this.latlngs.push(position); }  this.drawcanvas = function(){ this.setmap(this.map_); //google.maps.event.addlistener(this.map_, 'bounds_changed',this.redraw()); }  }  function defineoverlay() {  customlayer.prototype = new google.maps.overlayview();  customlayer.prototype.onadd = function() {     console.log("onadd()");     if(this.canvas){         var panes = this.getpanes();     panes.overlaylayer.appendchild(this.canvas);     } }   customlayer.prototype.remove = function() {     console.log("onremove()");     if(this.canvas)     this.canvas.parentnode.removechild(this.canvas); }   customlayer.prototype.draw = function() {     console.log("draw()");         this.remove();             this.canvas = document.createelement("canvas");             this.canvas.setattribute('width', '800px');             this.canvas.setattribute('height', '480px');             this.canvas.setattribute('top', '30px');             this.canvas.setattribute('left', '30px');             this.canvas.setattribute('position', 'absolute');             this.canvas.setattribute('border', '1px solid red');             this.canvas.style.border = '1px solid red';              //using way reason scale images , mess positions of markers             /*this.canvas.style.position = 'absolute';             this.canvas.style.top = '0px';             this.canvas.style.left = '0px';             this.canvas.style.width = '800px';              this.canvas.style.height = '480px';             this.canvas.style.border = '1px solid red';*/              //get projection overlay             overlayprojection = this.getprojection();             //var mapproj = this.map_.getprojection();                  if(this.canvas.getcontext) {                     var context = this.canvas.getcontext('2d');                     context.clearrect(0,0,800,480);                      for(i=0; i<this.latlngs.length; i++){                          p = overlayprojection.fromlatlngtodivpixel(this.latlngs[i]);                         //p = mapproj.fromlatlngtopoint(this.latlngs[i]);                         img = new image();                         img.src = "standardtick.png";                             console.log(math.floor(p.x)+","+math.floor(p.y));                     context.drawimage(img,p.x,p.y);                     }                 }     this.onadd();                console.log("canvas width:"+this.canvas.width+" canvas height: "+this.canvas.height);     console.log("canvas top:"+this.canvas.getattribute("top")+" left: "+this.canvas.getattribute("left"));   } } 

in example - think important draw attention difference between projection.fromlatlngtodivpixel , projection.fromlatlngtocontainerpixel. in context, divpixel used keep position of canvas centered on map view - while containerpixel used find positions of shapes drawing canvas.

what follows complete working example worked out while playing around problem myself.

required css properties overlay:

  .gmaps_overlay   {     border-width: 0px;     border: none;     position:absolute;     padding:0px 0px 0px 0px;     margin:0px 0px 0px 0px;   } 

initialize map , create test based on google markers

  var mapsize    = { width: 500, height: 500 };   var mapelement = document.getelementbyid("map");    mapelement.style.height = mapsize.width + "px";   mapelement.style.width  = mapsize.width + "px";    var map = new google.maps.map(document.getelementbyid("map"), {     maptypeid: google.maps.maptypeid.terrain,     center:    new google.maps.latlng(0, 0),     zoom:      2   });    // render g-markers test proper canvas-grid alignment   (var lng = -180; lng < 180; lng += 10)   {     var marker = new google.maps.marker({       position: new google.maps.latlng(0, lng),       map: map     });   } 

define custom overlay

  var canvasoverlay = function(map) {     this.canvas           = document.createelement("canvas");     this.canvas.classname = "gmaps_overlay";     this.canvas.height    = mapsize.height;     this.canvas.width     = mapsize.width;     this.ctx              = null;     this.map              = map;      this.setmap(map);   };   canvasoverlay.prototype = new google.maps.overlayview();    canvasoverlay.prototype.onadd = function() {     this.getpanes().overlaylayer.appendchild(this.canvas);     this.ctx = this.canvas.getcontext("2d");     this.draw();   };    canvasoverlay.prototype.drawline = function(p1, p2) {     this.ctx.beginpath();     this.ctx.moveto( p1.x, p1.y );     this.ctx.lineto( p2.x, p2.y );     this.ctx.closepath();     this.ctx.stroke();   };    canvasoverlay.prototype.draw = function() {     var projection = this.getprojection();      // shift canvas     var centerpoint = projection.fromlatlngtodivpixel(this.map.getcenter());     this.canvas.style.left = (centerpoint.x - mapsize.width  / 2) + "px";     this.canvas.style.top  = (centerpoint.y - mapsize.height / 2) + "px";      // clear canvas     this.ctx.clearrect(0, 0, mapsize.width, mapsize.height);      // draw grid canvas     this.ctx.strokestyle = "#000000";     (var lng = -180; lng < 180; lng += 10)     {       this.drawline(         projection.fromlatlngtocontainerpixel(new google.maps.latlng(-90, lng)),         projection.fromlatlngtocontainerpixel(new google.maps.latlng( 90, lng))       );     }   }; 

initializing canvas

i find add additional call draw on "dragend" event - test out see think on needs.

  var custommapcanvas = new canvasoverlay(map);   google.maps.event.addlistener(map, "drawend", function() {     custommapcanvas.draw();   }; 

in cases canvas drawing slowing down map

on applications work with, find map framework calls 'draw' method far on canvas's drawing takes second or complete. in case define 'draw' prototype function empty function while naming real draw function 'canvasdraw' - add event listeners "zoomend" , "dragend". here canvas updates after user changes zoom level or @ end of map drag action.

  canvasoverlay.prototype.draw = function() { };          ...     google.maps.event.addlistener(map, "dragend", function() {     custommapcanvas.canvasdraw();   });    google.maps.event.addlistener(map, "zoom_changed", function() {     custommapcanvas.canvasdraw();   }); 

live demo: complete example - inline source


Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -