【问题标题】:JS - canvas.toDataURL FailsJS - canvas.toDataURL 失败
【发布时间】:2016-02-22 04:31:07
【问题描述】:

我最近一直在使用一些谷歌地图,我需要旋转地图标记的图标。我做了一些研究,发现了This Answer

很遗憾,它无法正常工作。它不会渲染我需要的图像。 canvas.toDataURL 生成的 URL 是空白图片(大小正确)。

代码如下:

var latlong0=new google.maps.LatLng(44.422036688671, -73.857908744819);    function initialize() {
  var mapOptions = {
    center: { lat: 44.422036688671, lng: -73.857908744819},
    zoom: 0
  };
  var map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);
  var airplane = 'img/airplane_icon.png';

  var infowindow0=new google.maps.InfoWindow({
      content: `
      <div>
        <p class='spectxt'>&lt;Flight #&gt;</p>
    <div style='font-size:10px;'>
          <p class='gentxtl'>Airline: <span class='acptxt'>Aero Test Ltd</span></p>
      <p class='gentxtl'>Aircraft: <span class='acptxt'>Boeing 717-200 HGW</span></p>
      <p class='gentxtl'>From: <span class='acptxt'>YYZ</span></p>
      <p class='gentxtl'>To: <span class='acptxt'>YHZ</span></p>
        </div>
      </div>
      `
    });

  var mark0=new google.maps.Marker({
    position: latlong0,
    map: map,
    title:'Aircraft',
    icon: {
            url: RotateIcon
                .makeIcon(
                    '/img/airplane_icon.png')
                .setRotation({deg: 78})
                .getUrl()
        }
  });
  mark0.setMap(map);mark0.addListener('click', function() {
      infowindow0.open(map, mark0);
    });    }
google.maps.event.addDomListener(window, 'load', initialize);

RotateIcon 代码:

  var RotateIcon = function(options){
    this.options = options || {};
    this.rImg = options.img || new Image();
    this.rImg.src = this.rImg.src || this.options.url || '';
    this.options.width = this.options.width || this.rImg.width || 50;
    this.options.height = this.options.height || this.rImg.height || 50;
    var canvas = document.createElement("canvas");
    canvas.width = this.options.width;
    canvas.height = this.options.height;
    this.context = canvas.getContext("2d");
    this.canvas = canvas;
};
RotateIcon.makeIcon = function(url) {
    return new RotateIcon({url: url});
};
RotateIcon.prototype.setRotation = function(options){
    var canvas = this.context,
        angle = options.deg ? options.deg * Math.PI / 180:
            options.rad,
        centerX = this.options.width/2,
        centerY = this.options.height/2;

    canvas.clearRect(0, 0, this.options.width, this.options.height);
    canvas.save();
    canvas.translate(centerX, centerY);
    canvas.rotate(angle);
    canvas.translate(-centerX, -centerY);
    canvas.drawImage(this.rImg, 0, 0);
    canvas.restore();
    return this;
};
RotateIcon.prototype.getUrl = function(){
    return this.canvas.toDataURL('image/png');
};

图片与网页在同一个域中,两个资源都是普通的http(没有https)。 Chrome DevTools 不会报告任何警告或错误。 canvas.toDataURL 输出this

我在 Windows 8.1 上使用 Chrome 48

我注意到它还有一些奇怪的地方。如果我将 URL 更改为 /img/logo.png,它会创建我想要的图像,但尺寸错误。 canvas.toDataURL 输出this

-EDIT-
/img/airplane_icon.png可以找到here
/img/logo.png可以找到here

-编辑 2-
所以,我创建了一个test page,发现它可以工作了......所以我回到了我的第一页,并注意到如果我在地图画布之后有&lt;img src="/img/airplane_icon.png"&gt;,该页面将可以工作,但如果我删除它,页面不会。奇怪的。现在我只想在 img 中添加一个display:none,但有谁知道为什么必须包含 img 才能使页面正常工作?

【问题讨论】:

标签: javascript canvas google-maps-api-3


【解决方案1】:

如果图像在缓存中不可用,这似乎是图像异步加载的问题。一种解决方法是将图标作为数据 URI 加载:

var airplaneIcon = new RotateIcon({
  url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAgMAAABjUWAiAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAAlQTFRF////AH8OAH8OqhPhTgAAAAJ0Uk5TADqwnxSKAAAAZ0lEQVQoz2NgoCJQQOYwrkTmMa0aijy2VQ5IvKxVS5ClViFJZgF5S5ClEJJZYN4SZCmYpBaUtwDGm7RKCsGbAHSLFIw3AewyqQUD5XepVRNwhQTjqlUrcYULF5DXgOAtYchqoF5yAwBuvj9B9E9ozgAAAABJRU5ErkJggg==',
  height: 50,
  width: 50
})
var mark0 = new google.maps.Marker({
  position: latlong0,
  map: map,
  title: 'Aircraft',
  icon: {
  // size: new google.maps.Size(128, 128),
    scaledSize: new google.maps.Size(20, 20),
    anchor: new google.maps.Point(10, 10),
    url: airplaneIcon.setRotation({
        deg: 78
    })
    .getUrl()
  }
});

proof of concept fiddle

代码 sn-p:

var RotateIcon = function(options) {
  this.options = options || {};
  this.rImg = options.img || new Image();
  this.rImg.src = this.rImg.src || this.options.url || '';
  this.options.width = this.options.width || this.rImg.width || 50;
  this.options.height = this.options.height || this.rImg.height || 50;
  var canvas = document.createElement("canvas");
  canvas.width = this.options.width;
  canvas.height = this.options.height;
  this.context = canvas.getContext("2d");
  this.canvas = canvas;
};
RotateIcon.makeIcon = function(url) {
  return new RotateIcon({
    url: url
  });
};
RotateIcon.prototype.setRotation = function(options) {
  var canvas = this.context,
    angle = options.deg ? options.deg * Math.PI / 180 :
    options.rad,
    centerX = this.options.width / 2,
    centerY = this.options.height / 2;

  canvas.clearRect(0, 0, this.options.width, this.options.height);
  canvas.save();
  canvas.translate(centerX, centerY);
  canvas.rotate(angle);
  canvas.translate(-centerX, -centerY);
  canvas.drawImage(this.rImg, 0, 0);
  canvas.restore();
  return this;
};
RotateIcon.prototype.getUrl = function() {
  return this.canvas.toDataURL('image/png');
};

var map;
var latlong0 = new google.maps.LatLng(44.422036688671, -73.857908744819);

function initialize() {
  var mapOptions = {
    center: {
      lat: 44.422036688671,
      lng: -73.857908744819
    },
    zoom: 5
  };
  map = new google.maps.Map(document.getElementById('map-canvas'),
    mapOptions);
  var airplane = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAgMAAABjUWAiAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAAlQTFRF////AH8OAH8OqhPhTgAAAAJ0Uk5TADqwnxSKAAAAZ0lEQVQoz2NgoCJQQOYwrkTmMa0aijy2VQ5IvKxVS5ClViFJZgF5S5ClEJJZYN4SZCmYpBaUtwDGm7RKCsGbAHSLFIw3AewyqQUD5XepVRNwhQTjqlUrcYULF5DXgOAtYchqoF5yAwBuvj9B9E9ozgAAAABJRU5ErkJggg==';

  var infowindow0 = new google.maps.InfoWindow({
    content: `
      <div>
        <p class='spectxt'>&lt;Flight #&gt;</p>
    <div style='font-size:10px;'>
          <p class='gentxtl'>Airline: <span class='acptxt'>Aero Test Ltd</span></p>
      <p class='gentxtl'>Aircraft: <span class='acptxt'>Boeing 717-200 HGW</span></p>
      <p class='gentxtl'>From: <span class='acptxt'>YYZ</span></p>
      <p class='gentxtl'>To: <span class='acptxt'>YHZ</span></p>
        </div>
      </div>
      `
  });
  var airplaneIcon = new RotateIcon({
    url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAgMAAABjUWAiAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAAlQTFRF////AH8OAH8OqhPhTgAAAAJ0Uk5TADqwnxSKAAAAZ0lEQVQoz2NgoCJQQOYwrkTmMa0aijy2VQ5IvKxVS5ClViFJZgF5S5ClEJJZYN4SZCmYpBaUtwDGm7RKCsGbAHSLFIw3AewyqQUD5XepVRNwhQTjqlUrcYULF5DXgOAtYchqoF5yAwBuvj9B9E9ozgAAAABJRU5ErkJggg==',
    height: 50,
    width: 50
  })
  var mark0 = new google.maps.Marker({
    position: latlong0,
    map: map,
    title: 'Aircraft',
    icon: {
      // size: new google.maps.Size(128, 128),
      scaledSize: new google.maps.Size(20, 20),
      anchor: new google.maps.Point(10, 10),
      url: airplaneIcon.setRotation({
          deg: 78
        })
        .getUrl()
    }
  });
  mark0.setMap(map);
  mark0.addListener('click', function() {
    infowindow0.open(map, mark0);
  });
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-02
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多