наложение изображения при рисовании в тайле ведет себя странно

#javascript #image #canvas #google-maps-api-3

#javascript #изображение #холст #google-maps-api-3

Вопрос:

Я пытаюсь нарисовать растровое изображение (png) в качестве наложения в Google Maps для каждой карты-плитки. Я хотел бы иметь возможность рисовать свое собственное растровое изображение в качестве наложения. После некоторой возни я понял, как рисовать на холсте. Рисование линий работает нормально, но рисование загруженного изображения ведет себя очень странно. Реакции на масштабирование и панорамирование неясны. Я пытался разобраться с функцией onload, но она не улучшается…

Мои вопросы: Что я делаю не так? Как нарисовать растровое изображение в виде наложения на плитку?

Спасибо.

смотрите также https://jsfiddle.net/rolandinoman/1twa0p74/8 / панорамирование и увеличение / уменьшение масштаба, чтобы увидеть эффекты.

Пример кода

 /**
 * sometimes the png is drawn, sometimes it is not .
 * don't get it.
 */

/** @constructor */
function CoordMapType(tileSize) {
  this.tileSize = tileSize;
}

CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
  var div = ownerDocument.createElement('div');

  var canvas = ownerDocument.createElement('canvas');
   canvas.id     = "canv";
   w = 256;
   h = 256;
   canvas.width = w;
   canvas.height = h;
   ctx = canvas.getContext('2d');
   cs = getComputedStyle(div);
   /// draw some lines on canvas
   ctx.lineWidth = 1;
   ctx.strokeStyle = "#FF0000";
   ctx.strokeRect(6, 6, w-6, h-6);
   // draw an image on the canvas:
   var image = new Image(256,256);
   image.onload = function(){ ctx.drawImage(image, 0, 0);}
   // picked a random bitmap 256X256:
   image.src = "http://files.softicons.com/download/application-icons/malware-icons-by-deleket/png/256x256/Malware.png"

   //ctx.drawImage(image, 0, 0);  // alternative to onload, behaves also erratic.
   div.appendChild(canvas)

   return div;
};

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {lat: 41.850, lng: -87.650}
  });

  // Insert this overlay map type as the first overlay map type at
  // position 0. Note that all overlay map types appear on top of
  // their parent base map.
  map.overlayMapTypes.insertAt(
      0, new CoordMapType(new google.maps.Size(256, 256)));
}
  

Ответ №1:

Я полагаю, что у вас проблема с событием onload; оно не сработает (по крайней мере, в некоторых случаях), если изображение уже находится в кэше.

Вы можете предварительно загрузить изображение, а затем не использовать событие onload.

фрагмент кода:

 /** @constructor */
function CoordMapType(tileSize) {
  this.tileSize = tileSize;
}

CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
  var div = ownerDocument.createElement('div');
  var canvas = ownerDocument.createElement('canvas');
  w = 256;
  h = 256;
  canvas.width = w;
  canvas.height = h;
  ctx = canvas.getContext('2d');
  cs = getComputedStyle(div);
  /// draw something on canvas
  ctx.lineWidth = 1;
  ctx.strokeStyle = "#FF0000";
  ctx.strokeRect(6, 6, w - 6, h - 6);
  var image = new Image(256, 256);
  image.src = "http://files.softicons.com/download/application-icons/malware-icons-by-deleket/png/256x256/Malware.png"
  ctx.drawImage(image, 0, 0);
  div.appendChild(canvas);
  return div;
};

function initMap() {
  document.getElementById('nodisp').style.display = "none";
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {
      lat: 41.850,
      lng: -87.650
    }
  });

  // Insert this overlay map type as the first overlay map type at
  // position 0. Note that all overlay map types appear on top of
  // their parent base map.
  map.overlayMapTypes.insertAt(
    0, new CoordMapType(new google.maps.Size(256, 256)));
}
google.maps.event.addDomListener(window, 'load', initMap);  
 html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map {
  height: 100%;
}  
 <div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js">
</script>
<img id="nodisp" src="http://files.softicons.com/download/application-icons/malware-icons-by-deleket/png/256x256/Malware.png" />  

Комментарии:

1. Спасибо @geocodezip . Я понимаю, что для этого особого случая я привел в качестве примера. Но в моем проекте у меня было бы другое изображение для каждого уровня масштабирования / плитки. Я не могу их предварительно загрузить… Без предварительной загрузки, тогда, ** иногда **, он не будет отображаться… Вам нужно выполнить некоторое увеличение и уменьшение масштаба, чтобы это произошло. Когда изображение не уникально, это происходит гораздо чаще… смотрите ссылку на fidlle: ссылка