我最近一直在使用一些谷歌地图,我需要旋转 map 标记的图标。我做了一些研究,发现了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'><Flight #></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);
旋转图标代码:
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
-编辑-
/img/airplane_icon.png
可以查到here
/img/logo.png
可以查到here
-编辑2-
所以,我做了一个test page ,并发现它工作......所以我回到我的第一页,并注意到如果我有 <img src="/img/airplane_icon.png">
在 map Canvas 之后,页面将工作,但如果我删除它,页面将无法工作。奇怪的。现在我只需添加一个 display:none
到 img,但有人知道为什么必须包含 img 才能使页面正常工作吗?
最佳答案
如果图像在缓存中尚不可用,则图像的异步加载似乎存在问题。解决这个问题的一种选择是将图标作为数据 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()
}
});
代码片段:
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'><Flight #></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>
关于javascript - JS - canvas.toDataURL 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35531600/