我像这样在画布上绘制了一个动画,并使用 openlayers4 渲染了一张地图。我想在下一步中将此画布添加到地图 [openlayers 画布]。
我曾使用ol.source.ImageCanvas 为 openlayers添加边界,所以我尝试使用 ImageCanvas 添加带有动画的画布,但失败了。
更何况openlayers API说ol.source.ImageCanvas方法只能添加图片画布。我不知道动画画布是否也是如此。
我应该坚持使用ImageCanvas方法还是尝试其他方法?
如果我放弃ImageCanvas方法,有人可以举个例子吗?
解决方案
经过一些尝试,我得到了解决方案!哈哈!
第一:ol.source.ImageCanvas仍然可以使用,但你会得到一个停止的动画,就像截图一样。
第二:必须知道openlayers3或openlayers4中的ol.map.render(),其描述为:
请求地图渲染(在下一个动画帧)。
因此,您可以使用它来 刷新地图并获取 canvas 的下一个动画。
以下是我的代码片段:
<span style="color:#333333"><span style="background-color:#f5f5f5"><code class="language-java"> var topoCanvas = function(extent, resolution, pixelRatio, size, projection) {
// topo features;
var features = topojson.feature(tokyo, tokyo.objects.counties);
var canvasWidth = size[0];
var canvasHeight = size[1];
var canvas = d3.select(document.createElement('canvas'));
canvas.attr('width', canvasWidth).attr('height', canvasHeight);
var context = canvas.node().getContext('2d');
var d3Projection = d3.geo.mercator().scale(1).translate([0, 0]);
var d3Path = d3.geo.path().projection(d3Projection);
var pixelBounds = d3Path.bounds(features);
var pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
var pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];
var geoBounds = d3.geo.bounds(features);
var geoBoundsLeftBottom = ol.proj.transform(geoBounds[0], 'EPSG:4326', projection);
var geoBoundsRightTop = ol.proj.transform(geoBounds[1], 'EPSG:4326', projection);
var geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
if (geoBoundsWidth < 0) {
geoBoundsWidth += ol.extent.getWidth(projection.getExtent());
}
var geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];
var widthResolution = geoBoundsWidth / pixelBoundsWidth;
var heightResolution = geoBoundsHeight / pixelBoundsHeight;
var r = Math.max(widthResolution, heightResolution);
var scale = r / (resolution / pixelRatio);
var center = ol.proj.transform(ol.extent.getCenter(extent), projection, 'EPSG:4326');
d3Projection.scale(scale).center(center).translate([canvasWidth / 2, canvasHeight / 2]);
d3Path = d3Path.projection(d3Projection).context(context);
d3Path(features);
context.stroke();
// above code is add a topoJson boundary to canvas
// below code is add an animation to canvas
var settings = createSettings(tokyo, {
width: canvasWidth,
height: canvasHeight
});
// reset the projection and bounds for animation canvas
settings.projection = d3Projection;
settings.bounds = geoBounds;
var mesh = buildMeshes(tokyo, settings);
when(render(settings, mesh, {
width: canvasWidth,
height: canvasHeight
})).then(function(masks) {
when(interpolateField(stations, data, settings, masks)).then(function(field) {
// wind moving animation
animate(settings, field, canvas);
// refresh the map to get animation
window.setInterval(function() {
map.render();
}, 50);
});
});
return canvas[0][0];
}</code></span></span>