JS Google Maps API v3在坐标之间设置动画标记

时间:2012-06-05 20:30:54

标签: javascript google-maps animation google-maps-api-3 google-maps-markers

我有一个简单的javascript地图应用程序,我正在研究它需要我动画不同坐标之间的多个标记的移动。每个标记可以自由移动,所有标记都存储在数组列表中。但是,我一直无法让他们顺利过渡到位置。

我做了大量的研究和试验/错误,但没有运气,任何人都有运气吗?

4 个答案:

答案 0 :(得分:19)

我的快速和肮脏的方法不涉及大量的研究:(

以下是演示:http://jsfiddle.net/yV6xv/4/点击标记开始移动它,停止后,您可以再次单击返回其初始点。在运动中单击会产生奇怪的结果。

initialize()中预定义了起点和终点。通过将起点和终点分成100个段来定义动画,并将标记放置在这些点上并设置间隔。因此动画时间是固定的:标记比较短的距离“更快”地传播更长的距离。

我没有做太多测试,我知道点击移动标记会产生意想不到的结果(起点和终点错位)

这是演示的“有趣”部分:

      // store a LatLng for each step of the animation
      frames = [];
      for (var percent = 0; percent < 1; percent += 0.01) {
        curLat = fromLat + percent * (toLat - fromLat);
        curLng = fromLng + percent * (toLng - fromLng);
        frames.push(new google.maps.LatLng(curLat, curLng));
      }

      move = function(marker, latlngs, index, wait, newDestination) {
        marker.setPosition(latlngs[index]);
        if(index != latlngs.length-1) {
          // call the next "frame" of the animation
          setTimeout(function() { 
            move(marker, latlngs, index+1, wait, newDestination); 
          }, wait);
        }
        else {
          // assign new route
          marker.position = marker.destination;
          marker.destination = newDestination;
        }
      }

      // begin animation, send back to origin after completion
      move(marker, frames, 0, 20, marker.position);

答案 1 :(得分:12)

您可以使用marker-animate-unobtrusive库制作标记 顺利地从一个地方过渡到另一个地方。

您可以像这样初始化您的标记:

var marker = new SlidingMarker({
   //your original marker options
   //...
   duration: 1000
});

定义此标记后,您的标记将在1秒内平稳移动到新位置,只需调用marker.setPosition()。

如果您想要来回设置标记,只需每秒切换一次setPosition。

setTimeout(function() {
   var newPosition = /* select new position */
   marker.setPosition(newPosition)
}, 1000);

P.S。我是图书馆的作者。

答案 2 :(得分:8)

我不确定这是不是你要找的,但无论如何我都会分享它:我把这段代码编写成模拟汽车的移动,具体速度为km / H。您只需要指定您希望标记/汽车前往的每个点的坐标(然后它将为坐标之间的标记设置动画)。

我修改了rcravens's answer以达到这个目的:

sp

jsfiddle - DEMO

请注意,您需要添加&#34;几何&#34;当您包含Google地图以便能够使用tract_geom<-fortify(tract,region="STUSPS")时,库 http://maps.google.com/maps/api/js?sensor=true&libraries=geometry

希望它有所帮助!

答案 3 :(得分:0)

另一种方法是使用CSS过渡。重要的是识别谷歌地图用于你的标记的DIV(有两个是触摸事件透明的)调查已经完成,你真的只需要了解一次。

可以找到一个完整的例子here看看Hansel和Gretel在地图上的移动有多顺畅!如果有任何延迟,转换时间会合并。

我的Brotkrumen Ultimate Web App的所有代码都可以找到here你最感兴趣的是HandleMap.js文件,但是有一个aaa_readme.txt

以下是代码的一部分: -

function showJourney(){
    map.setZoom(map.getZoom());
    map.setOptions({gestureHandling: "none"});
    zoomOut.style.display = "none";
    zoomIn.style.display  = "none";

    hat.setPosition(
        new google.maps.LatLng(
                lastPos.coords.latitude,
                lastPos.coords.longitude)); 
    hat.setVisible(true);
    hat.setAnimation(bounce);

    HandG.setPosition(
        new google.maps.LatLng(
                firstPos.coords.latitude,
                firstPos.coords.longitude)); 
    HandG.setVisible(true);

    map.panTo(path[0]); 
    google.maps.event.trigger(map, 'resize');

    if (document.querySelectorAll(MARKER_SELECTOR).length == 0){
        observer.observe(mapDiv, {
                        childList     : true,
                        subtree       : true ,
                        attributes    : true ,
                        characterData : false
                        })
    } else {
        setTimeout(plotTrip,0);
    }
}
function plotTrip(){
    nextFunc = plotStep;
    hat.setAnimation(bounce);
    HandG.setPosition(path[0]);
    dirPoly.setVisible(true);       
    progressPath = [];
    progressPath.push(path[0]);
    dirPoly.setPath(path);
    stepPoly.setPath(progressPath);
    stepPoly.setVisible(true);
    currStep = 1;
    markerDivs = [];
    var markerImgs = document.querySelectorAll(MARKER_SELECTOR);
    for (var i=0; i<markerImgs.length; i++){
        console.log(markerImgs[i].src);
        markerDivs[i] = markerImgs[i].parentNode;
        markerDivs[i].style.transitionDuration = "0s";
        markerDivs[i].style.transitionProperty = "left, top";
        markerDivs[i].style.transitionTimingFunction = "linear";
    }

    setTimeout(plotStep,0);
    abort = false;
    btn.value = "Cancel";
    btn.disabled = false;
}
function plotStep(){
    if (abort) return;

    if (legs[currStep].didLoiter){
        countDown = legs[currStep].restTime;
        infoWindow.setContent(
            "<div id='waitDiv'><span>Waiting</span></div>");
        infoWindow.open(map,HandG);
        showInterval();
    } else {
        plotIt();
    }
}
function showInterval(){
    if (abort) return;

    infoWindow.setContent(
        "<div id='waitDiv'><span>Waiting "+deltaDate(countDown)+"</span></div>");
    countDown -= (ONE_SEC * multiSpeed);
    if (countDown < 1){
        infoWindow.close(); 
        plotIt();
    } else {
        setTimeout(showInterval, ONE_SEC);
    }
}
function plotIt(){
    if (abort) return;

    progressPath.push(path[currStep]);
    stepPoly.setPath(progressPath);
    map.panTo(path[currStep]);
    var transitionMS = legs[currStep].duration / multiSpeed;
    for (var i=0; i<markerDivs.length; i++){
        markerDivs[i].style.transitionDuration = transitionMS + "ms";
    }
    HandG.setPosition(path[currStep])

    if (++currStep >= path.length)
        nextFunc = cleanUp;

    plotTimer = setTimeout(nextFunc,transitionMS);
}
function cleanUp(){
    infoWindow.close();
    hat.setAnimation();
    btn.value = "Replay";
    btn.disabled = false;
    clearTimeout(plotTimer);
    for (var i=0; i<markerDivs.length; i++){
        markerDivs[i].style.transitionDuration = "0s";
    }
    HandG.setPosition(
        new google.maps.LatLng(
                lastPos.coords.latitude,
                lastPos.coords.longitude)); 
    HandG.setVisible(false);
    map.setOptions({gestureHandling: "cooperative"});
    zoomIn.style.display  = "";
    zoomOut.style.display = "";
    if (canTalk && !abort)
        speechSynthesis.speak(finish);
}
function waitForMarker(mutations, myInstance) {
    outer:
    for (var i=0; i<mutations.length; i++){
        if (mutations[i].type           == "attributes" && 
            mutations[i].target.tagName == "IMG"        &&
            mutations[i].target.src.toLowerCase().indexOf(MARKER_SRC) != -1){
            console.log("result")
            myInstance.disconnect();
            setTimeout(plotTrip,0)
            break outer;
        }
        if (mutations[i].type != "childList" ||
            mutations[i].addedNodes.length   == 0) 
            continue;
        for (var j=0; j<mutations[i].addedNodes.length; j++) {
            var node = mutations[i].addedNodes[j];
            if (node.tagName == "DIV" && node.firstChild && node.firstChild.tagName == "IMG" &&
                node.firstChild.src.toLowerCase().indexOf(MARKER_SRC) != -1){
                console.log(node.firstChild.src);
                myInstance.disconnect();
                setTimeout(plotTrip,0)
                break outer;
            }
        }
    }
}