javascript - 如何将 2 个 OpenLayer 标记动画添加到页面? Clickevent似乎被覆盖了

标签 javascript jquery html flask openlayers-3

我有一个 OpenLayer Marker Animation在我的(python) flask 应用程序中实现。

然而,在我用于标记动画的数据集中,我有一条额外的路线,我也想展示它的动画。

当我添加代码来处理第二个动画时,就像第一个动画的控件被覆盖一样,我不知道如何避免这种情况发生。我尝试将所有变量重命名为 1 和 2 以避免它们相互覆盖,但出于某种原因,它似乎仍然覆盖了控件。

我创建了 this fiddle来说明问题。如果您单击 map 1 下的开始动画,它将在 map 2 上运行动画。我刚刚在我的 fiddle 中使用了下面的过程,但最初我在 for 循环中有代码运行两次以提取两条路线然后绘制 map 。

Route points for Map 1
Set up Map 1
Bind functions to Map 1 buttons

Route points for Map 2
Set up Map 2
Bind functions to Map 2 buttons

我想我的问题是关于隔离代码和/或绑定(bind)。首先,我尝试将函数(moveFeature、startAnimation、stopAnimation)重命名为它们各自的名称,并添加“1”或“2”。这并没有起到作用,也没有类似地重命名所有变量。

最佳答案

您正在创建许多具有相同名称的变量。例如,当您覆盖函数 StartAnimation 时,按钮进入第二个按钮(因为两者都指向名为“StartAnimation”的函数)。

为避免这种情况,您必须为每个 map 创建不同的变量。这样您就可以避免无用的代码,并且可以确保每个元素都在使用它们应该使用的变量。

我已经根据您的 jsfiddle 代码构建了一个示例:

var locations1 = [[53.44241609, 6.84913974], [53.44241894, 6.84913726], [53.44242156, 6.84913385], [53.44242473, 6.84913076], [53.44242859, 6.84912721], [53.44243324, 6.84912446], [53.44243724, 6.84912303], [53.44243994, 6.84912206], [53.44244199, 6.84911994], [53.44244474, 6.84911928], [53.44244757, 6.8491193], [53.44245181, 6.84911968], [53.44245596, 6.84912085], [53.44246139, 6.84912072], [53.4424669, 6.84912142], [53.44247222, 6.84912279], [53.4424778, 6.84912454], [53.44248644, 6.84912644], [53.44249062, 6.84912761], [53.44249409, 6.84913057], [53.44249746, 6.84913362], [53.44250197, 6.84913592], [53.44250901, 6.84913629], [53.44251198, 6.84913792], [53.44251293, 6.84913988], [53.44251458, 6.84914126], [53.44251596, 6.8491434], [53.44251778, 6.84914727], [53.44251988, 6.8491501], [53.44252248, 6.8491531], [53.44252517, 6.84915473], [53.44252316, 6.84915181], [53.44252377, 6.84915124], [53.4425233, 6.84914949], [53.44252341, 6.84914848], [53.44252276, 6.84914827], [53.44252397, 6.84914868], [53.4425216, 6.84914477], [53.44252001, 6.84914287], [53.44252107, 6.84914273], [53.44251986, 6.84913869], [53.44251841, 6.84913463], [53.44251482, 6.84912822], [53.44251525, 6.84912649], [53.4425148, 6.84912465], [53.44251483, 6.84912049], [53.44251625, 6.84911749], [53.44251677, 6.84911403], [53.4425187, 6.84910978], [53.44252028, 6.84910694], [53.44252218, 6.84910622], [53.44252457, 6.84910649], [53.44252783, 6.84910729], [53.44253168, 6.84910888], [53.44253668, 6.84910943], [53.44254088, 6.84910976], [53.44254363, 6.84910898], [53.44254612, 6.84910996], [53.44254803, 6.84910946], [53.44255004, 6.84910945], [53.44255416, 6.84910766], [53.44256019, 6.84910343], [53.44256469, 6.84909908], [53.44256753, 6.84909764], [53.44257106, 6.84909639], [53.44257482, 6.84909654], [53.44257861, 6.84909769]];

var locations2 = [[53.44241609, 6.84913974], [53.44241894, 6.84913726], [53.44242156, 6.84913385], [53.44242473, 6.84913076], [53.44242859, 6.84912721], [53.44243324, 6.84912446], [53.44243724, 6.84912303], [53.44243994, 6.84912206], [53.44244199, 6.84911994], [53.44244474, 6.84911928], [53.44244757, 6.8491193], [53.44245181, 6.84911968], [53.44245596, 6.84912085], [53.44246139, 6.84912072], [53.4424669, 6.84912142], [53.44247222, 6.84912279], [53.4424778, 6.84912454], [53.44248644, 6.84912644], [53.44249062, 6.84912761], [53.44249409, 6.84913057], [53.44249746, 6.84913362], [53.44250197, 6.84913592], [53.44250901, 6.84913629], [53.44251198, 6.84913792], [53.44251293, 6.84913988], [53.44251458, 6.84914126], [53.44251596, 6.8491434], [53.44251778, 6.84914727], [53.44251988, 6.8491501], [53.44252248, 6.8491531], [53.44252517, 6.84915473], [53.44252316, 6.84915181], [53.44252377, 6.84915124], [53.4425233, 6.84914949], [53.44252341, 6.84914848], [53.44252276, 6.84914827], [53.44252397, 6.84914868], [53.4425216, 6.84914477], [53.44252001, 6.84914287], [53.44252107, 6.84914273], [53.44251986, 6.84913869], [53.44251841, 6.84913463], [53.44251482, 6.84912822], [53.44251525, 6.84912649], [53.4425148, 6.84912465], [53.44251483, 6.84912049], [53.44251625, 6.84911749], [53.44251677, 6.84911403], [53.4425187, 6.84910978], [53.44252028, 6.84910694], [53.44252218, 6.84910622], [53.44252457, 6.84910649], [53.44252783, 6.84910729], [53.44253168, 6.84910888], [53.44253668, 6.84910943], [53.44254088, 6.84910976], [53.44254363, 6.84910898], [53.44254612, 6.84910996], [53.44254803, 6.84910946], [53.44255004, 6.84910945], [53.44255416, 6.84910766], [53.44256019, 6.84910343], [53.44256469, 6.84909908], [53.44256753, 6.84909764], [53.44257106, 6.84909639], [53.44257482, 6.84909654], [53.44257861, 6.84909769]];

locations1.map(function(l) {
  return l.reverse();
});

locations2.map(function(l) {
  return l.reverse();
});

// ---------------------------
//Defining Map 1 and Events
// ---------------------------
var route1 = new ol.geom.LineString(locations1)
    .transform('EPSG:4326', 'EPSG:3857');

var routeCoords1 = route1.getCoordinates();
var routeLength1 = routeCoords1.length;

var routeFeature1 = new ol.Feature({
  type: 'route',
  geometry: route1
});
var geoMarker1 = new ol.Feature({
  type: 'geoMarker',
  geometry: new ol.geom.Point(routeCoords1[0])
});
var startMarker1 = new ol.Feature({
  type: 'icon',
  geometry: new ol.geom.Point(routeCoords1[0])
});
var endMarker1 = new ol.Feature({
  type: 'icon',
  geometry: new ol.geom.Point(routeCoords1[routeLength1 - 1])
});

var styles1 = {
  'route': new ol.style.Style({
    stroke: new ol.style.Stroke({
      width: 6,
      color: [237, 212, 0, 0.8]
    })
  }),
  'icon': new ol.style.Style({
    image: new ol.style.Icon({
      anchor: [0.5, 1],
      src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png'
    })
  }),
  'geoMarker': new ol.style.Style({
    image: new ol.style.Circle({
      radius: 7,
      snapToPixel: false,
      fill: new ol.style.Fill({
        color: 'black'
      }),
      stroke: new ol.style.Stroke({
        color: 'white',
        width: 2
      })
    })
  })
};

var animating1 = false;
var speed1, now1;
var speedInput1 = document.getElementById('speed1');
var startButton1 = document.getElementById('start-animation1');

var vectorLayer1 = new ol.layer.Vector({
  source: new ol.source.Vector({
    features: [routeFeature1, geoMarker1, startMarker1, endMarker1]
  }),
  style: function(feature) {
    // hide geoMarker if animation is active
    if (animating1 && feature.get('type') === 'geoMarker') {
      return null;
    }
    return styles1[feature.get('type')];
  }
});

var map1 = new ol.Map({
  target: document.getElementById('map1'),
  loadTilesWhileAnimating: true,
  view: new ol.View(),
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    vectorLayer1
  ]
});
map1.getView().fit(
    vectorLayer1.getSource().getExtent(), map1.getSize(),
    {padding: [30, 5, 5, 5]});
var center1 = map1.getView().getCenter();

var moveFeature1 = function(event) {
  var vectorContext = event.vectorContext;
  var frameState = event.frameState;

  if (animating1) {
    var elapsedTime = frameState.time - now1;
    // here the trick to increase speed is to jump some indexes
    // on lineString coordinates
    var index = Math.round(speed1 * elapsedTime / 1000);

    if (index >= routeLength1) {
      stopAnimation1(true);
      return;
    }

    var currentPoint = new ol.geom.Point(routeCoords1[index]);
    var feature = new ol.Feature(currentPoint);
    vectorContext.drawFeature(feature, styles1.geoMarker);
  }
  // tell OL3 to continue the postcompose animation
  map1.render();
};

function startAnimation1() {
  if (animating1) {
    stopAnimation1(false);
  } else {
    animating1 = true;
    now1 = new Date().getTime();
    speed1 = speedInput1.value;
    startButton1.textContent = 'Cancel Animation';
    // hide geoMarker
    geoMarker1.setStyle(null);
    // just in case you pan somewhere else
    map1.getView().setCenter(center1);
    map1.on('postcompose', moveFeature1);
    map1.render();
  }
}

function stopAnimation1(ended) {
  animating1 = false;
  startButton1.textContent = 'Start Animation';

  // if animation cancelled set the marker at the beginning
  var coord = ended ? routeCoords1[routeLength1 - 1] : routeCoords1[0];
  /** @type {ol.geom.Point} */
  (geoMarker1.getGeometry())
  .setCoordinates(coord);
  //remove listener
  map1.un('postcompose', moveFeature1);
}

startButton1.addEventListener('click', startAnimation1, false);


// ---------------------------
//Defining Map 2 and Events
// ---------------------------
var route2 = new ol.geom.LineString(locations2)
    .transform('EPSG:4326', 'EPSG:3857');

var routeCoords2 = route2.getCoordinates();
var routeLength2 = routeCoords2.length;

var routeFeature2 = new ol.Feature({
  type: 'route',
  geometry: route2
});
var geoMarker2 = new ol.Feature({
  type: 'geoMarker',
  geometry: new ol.geom.Point(routeCoords2[0])
});
var startMarker2 = new ol.Feature({
  type: 'icon',
  geometry: new ol.geom.Point(routeCoords2[0])
});
var endMarker2 = new ol.Feature({
  type: 'icon',
  geometry: new ol.geom.Point(routeCoords2[routeLength2 - 1])
});

var styles2 = {
  'route': new ol.style.Style({
    stroke: new ol.style.Stroke({
      width: 6,
      color: [237, 212, 0, 0.8]
    })
  }),
  'icon': new ol.style.Style({
    image: new ol.style.Icon({
      anchor: [0.5, 1],
      src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png'
    })
  }),
  'geoMarker': new ol.style.Style({
    image: new ol.style.Circle({
      radius: 7,
      snapToPixel: false,
      fill: new ol.style.Fill({
        color: 'black'
      }),
      stroke: new ol.style.Stroke({
        color: 'white',
        width: 2
      })
    })
  })
};

var animating2 = false;
var speed2, now2;
var speedInput2 = document.getElementById('speed2');
var startButton2 = document.getElementById('start-animation2');

var vectorLayer2 = new ol.layer.Vector({
  source: new ol.source.Vector({
    features: [routeFeature2, geoMarker2, startMarker2, endMarker2]
  }),
  style: function(feature) {
    // hide geoMarker if animation is active
    if (animating2 && feature.get('type') === 'geoMarker') {
      return null;
    }
    return styles2[feature.get('type')];
  }
});

var map2 = new ol.Map({
  target: document.getElementById('map2'),
  loadTilesWhileAnimating: true,
  view: new ol.View(),
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    vectorLayer2
  ]
});
map2.getView().fit(
    vectorLayer2.getSource().getExtent(), map2.getSize(),
    {padding: [30, 5, 5, 5]});
var center2 = map2.getView().getCenter();

var moveFeature2 = function(event) {
  var vectorContext = event.vectorContext;
  var frameState = event.frameState;

  if (animating2) {
    var elapsedTime = frameState.time - now2;
    // here the trick to increase speed is to jump some indexes
    // on lineString coordinates
    var index = Math.round(speed2 * elapsedTime / 1000);

    if (index >= routeLength2) {
      stopAnimation2(true);
      return;
    }

    var currentPoint = new ol.geom.Point(routeCoords2[index]);
    var feature = new ol.Feature(currentPoint);
    vectorContext.drawFeature(feature, styles2.geoMarker);
  }
  // tell OL3 to continue the postcompose animation
  map2.render();
};

function startAnimation2() {
  if (animating2) {
    stopAnimation2(false);
  } else {
    animating2 = true;
    now2 = new Date().getTime();
    speed2 = speedInput2.value;
    startButton2.textContent = 'Cancel Animation';
    // hide geoMarker
    geoMarker2.setStyle(null);
    // just in case you pan somewhere else
    map2.getView().setCenter(center2);
    map2.on('postcompose', moveFeature2);
    map2.render();
  }
}

function stopAnimation2(ended) {
  animating2 = false;
  startButton2.textContent = 'Start Animation';

  // if animation cancelled set the marker at the beginning
  var coord = ended ? routeCoords2[routeLength2 - 1] : routeCoords2[0];
  /** @type {ol.geom.Point} */
  (geoMarker2.getGeometry())
  .setCoordinates(coord);
  //remove listener
  map2.un('postcompose', moveFeature2);
}

startButton2.addEventListener('click', startAnimation2, false);
<script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
<link href="https://openlayers.org/en/v3.20.1/css/ol.css" rel="stylesheet"/>
<h1>
Map 1
</h1>
<div id="map1" class="map"></div>
<label for="speed1">
  speed:&nbsp;
  <input id="speed1" type="range" min="10" max="999" step="10" value="60">
</label>
<button id="start-animation1">Start Animation</button>

<h1>
Map 2
</h1>
<div id="map2" class="map"></div>
<label for="speed2">
  speed:&nbsp;
  <input id="speed2" type="range" min="10" max="999" step="10" value="60">
</label>
<button id="start-animation2">Start Animation</button>

关于javascript - 如何将 2 个 OpenLayer 标记动画添加到页面? Clickevent似乎被覆盖了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41588260/

相关文章:

javascript - 如何使用纯 javascript 将输入值保存在 JSON 对象中,然后将其保存在数组中?

javascript - 像 Q 一样定义空的 Bluebird promise

javascript - 如何检测浏览器是否是移动浏览器并使用 javascript "if else"显示不同尺寸的视频?

Javascript 表单创建是自动调用提交函数

html - 如何控制 CSS 驱动菜单下拉列表中子链接之间的间距?

javascript - 动态创建的卡片垂直排列它应该是水平的

javascript - jQuery:监听来自键盘的自动扫描仪输入?

javascript - 如何将速度参数分配给回调函数

python - Django heroku 上传文件

javascript - jQuery 切换列表代码冗余