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

时间:2016-06-15 23:45:05

标签: javascript animation openlayers-3

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

我的目标是让地图在“doBounce”动画之后对特定缩放级别进行缩放动画。每个位置都有不同的缩放级别。例如,当我点击“北海岸”时,它会执行“doBounce”动画,然后执行缩放动画以缩放10级。当我点击“Fraser River”时,它会执行“doBounce”,然后是缩放动画缩放级别为12。

过去几天我一直试图弄清楚如何做到这一点。通过谷歌搜索stackoverflow没有运气。

我能想到的最好的就是把这个hacky FIDDLE #2 放在一起,至少让我之后会做某种缩放动画......但这并不是我想要的。

这是我修改过的第二小提琴“doBounce”脚本:

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()返回与其开始时相同的分辨率)。

为了解决这个问题,我在函数的开头添加了view.setResolution(500);,以便更改分辨率。这样,至少缩放动画将适用于每次点击。您可以通过运行小提琴,然后删除注释行并再次运行它来查看我的意思。

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

我对Javascript& Openlayers所以任何帮助或建议都非常感谢。

1 个答案:

答案 0 :(得分:2)

您可以使用诸如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