OpenLayers 3 - 动画后缩放到特定级别

OpenLayers 3 - zoom to specific level after animation

我在 Openlayers 3 中创建了一个地图,该地图基于此示例脚本 (goo.gl/YoR7Ta) 中的 "doBounce"(平移和弹跳动画)。这是基本的 doBounce 动画的 FIDDLE #1

我的目标是让地图在 "doBounce" 动画之后也对特定的缩放级别执行缩放动画。每个位置都有不同的缩放级别。例如,当我单击 "North Coast" 时,它会执行 "doBounce" 动画,然后执行缩放动画到缩放级别 10。当我单击 "Fraser River" 时,它会执行 "doBounce", 然后缩放动画到缩放级别 12.

过去几天我一直在努力弄清楚如何去做,并且在 google 和 Whosebug 中进行了搜索,但没有成功。

我能想出的最好办法就是把这个 hacky FIDDLE #2 放在一起,至少让我可以在之后做一些缩放动画……但这不是我想要的。

这是我修改后的 "doBounce" 第二个脚本 fiddle:

function doBounce(location) {
    var duration = 2500;
    var start = +new Date();

    //REMOVE COMMENT FROM NEXT LINE TO SEE TEMP FIX SO ZOOM OCCURS EACH TIME
    //map.getView().setResolution(500);

    var bounce = ol.animation.bounce({
        duration: duration,
        resolution: view.getResolution() * 5,
        start: start
    });

    var pan = ol.animation.pan({
        duration: duration,
        source: view.getCenter(),
        start: start
    });

    var zoom = ol.animation.zoom({
        resolution: view.getResolution(),
        duration: 800,
        easing: ol.easing.linear,
      start: start + 2500
    });

    map.beforeRender(bounce, pan);
    view.setCenter(location);

    setTimeout(function() {
        map.beforeRender(zoom);
        view.setResolution(250);
    }, 2510);
}

我使用超时来延迟缩放动画,直到 "deBouce" 动画完成。这最终让我有了一个缩放动画,但它只会在第一次点击时发生。以下点击不会显示缩放动画(我假设是因为 ol.animation.bounce() returns 与开始时的分辨率相同)。

为了解决这个问题,我在函数的开头添加了 view.setResolution(500); 以更改分辨率。这样,至少缩放动画会在每次点击时起作用。您可以通过 运行 和 fiddle 明白我的意思,然后删除注释行并再次 运行 它。

有没有办法让每个位置在 "doBounce" 动画之后平滑地放大到特定的缩放级别?

我是 Javascript 和 Openlayers 的新手,所以非常感谢任何帮助或建议。

您可以使用像 Q.js 这样的 promise 帮助程序库来构造此流链接(按顺序调用)您的函数。可以是这样的:

function flyTo(location) {
  var final_zoom = 12,
      initial_zoom = 4;

  zoom(initial_zoom)
    .then(function() {
      console.info('Zoomed Out!');
      return panTo(location);
    })
    .then(function() {
      console.info('Panned to ... ');
      return zoom(final_zoom);
    })
    .then(function() {
      console.log('done!');
    });
}

或更短:

function flyTo(location) {
  var final_zoom = 12,
      initial_zoom = 4;

  zoom(initial_zoom)
    .then(panTo.bind(null, location))
    .then(zoom.bind(null, final_zoom))
    .then(function() {
        console.log('done!');
    });
}

其他功能:

function zoom(zoom_level) {
  var duration = 500;
  var deferred = Q.defer();
  var zoom = ol.animation.zoom({
    duration: duration,
    resolution: view.getResolution()
  });

  map.beforeRender(zoom);
  view.setZoom(zoom_level);

  Q.delay(duration).then(deferred.resolve);
  return deferred.promise;
}

function panTo(location) {
  var duration = 1500;
  var deferred = Q.defer();
  var pan = ol.animation.pan({
    duration: duration,
    source: view.getCenter()
  });

  map.beforeRender(pan);
  view.setCenter(location);

  Q.delay(duration)
    .then(deferred.resolve); // <---- here's where things happen
  return deferred.promise;
}

(fiddle)