如何在openlayers3或openlayers4中添加带动画的新画布

时间:2017-09-23 15:51:44

标签: javascript html5 animation canvas openlayers-3

我在画布中绘制了一个动画,如this,并使用openlayers4渲染了一张地图。我想在下一步中将这个画布添加到地图[openlayers canvas]。

我曾使用 ol.source.ImageCanvas 为openlayers添加边界,因此我尝试使用ImageCanvas添加带动画的画布,但失败了。

还有更多,openlayers API ol.source.ImageCanvas 方法只能添加图片画布。我不知道动画画布是否也是如此。

我应该坚持使用 ImageCanvas 方法还是尝试别人?

如果我放弃 ImageCanvas 方法,有人会举个例子吗?

1 个答案:

答案 0 :(得分:1)

经过一番尝试,我得到了解决方案!哈哈!

首先 ol.source.ImageCanvas 可以仍然使用,但您将获得停止的动画,就像截图一样。

第二:必须知道openlayers3或openlayers4中的ol.map.render(),其描述如下:

  

请求地图渲染(在下一个动画帧处)。

因此,您可以使用它来刷新地图并获取下一个画布动画

以下是我的代码片段:

    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];
}