Google Maps API v3 - 带动画的多个点

时间:2012-07-03 19:18:01

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

我正在建立一个成员目录,以及按照名称和城镇或城市的距离顺序列出成员,将使用Google Maps API v3在地图上显示。

我的工作几乎是我想要的,但我担心它有点慢。我已经异步加载它,但标记有问题。

我想加载地图,然后标记一个接一个地逐个出现在一个下拉动画中。目前有一个延迟,他们都在一起,有时他们出现在地图上然后下降看起来很奇怪。

我正在使用PHP foreach脚本(来自MYSQL数据库)为成员输出javascript数组 - 地图上可以有10到400个标记,但通常一次不超过100个。 / p>

为简洁起见,我在下面的例子中只包含了4个标记(正如我之前所说的那样是从PHP foreach脚本输出的):

<script>
var infowindow = null;
$(document).ready(function () { initialize();  });
function initialize() {
    var centerMap = new google.maps.LatLng(53.1,-2.2);
    var myOptions = {
        zoom: 9,
        center: centerMap,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        scrollwheel: false
    }

    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    setMarkers(map, sites);
    infowindow = new google.maps.InfoWindow({
            content: "loading..."
        });
}

 var sites = [
 ['Joe Bloggs',52.1022,-2.1070,1,"Member &nbsp;<a href=\"#\">Joe Bloggs</a>"],                              
 ['Peter Pan',52.2022,-2.2070,1,"Member &nbsp;<a href=\"#\">Peter Pan</a>"],                                
 ['Andrew Andrewson',52.0322,-2.0170,1,"Member &nbsp;<a href=\"#\">Andrew Andrewson</a>"],                              
 ['Peter Peterson',52.0022,-2.0070,1,"Member &nbsp;<a href=\"#\">Peter Peterson</a>"],  
 ];

function setMarkers(map, markers) {
    for (var i = 0; i < markers.length; i++) {
        var sites = markers[i];
        var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
        var marker = new google.maps.Marker({
            position: siteLatLng,
            map: map,
            title: sites[0],
            zIndex: sites[3],
            html: sites[4],
            animation: google.maps.Animation.DROP
        });

        var contentString = "Some content";
        google.maps.event.addListener(marker, "click", function () {
            infowindow.setContent(this.html);
            infowindow.open(map, this);
        });
    }
}


  function loadScript() {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://maps.googleapis.com/maps/api/js?key=my-key-is-here&sensor=false&' +'callback=initialize';
    document.body.appendChild(script);
  }

  window.onload = loadScript;
</script>

如何加快速度并在页面加载后让标记显示在拖放动画中?

3 个答案:

答案 0 :(得分:10)

TL,DR:link to demo

在我看来,你必须编写自定义动画功能来创建一些光滑的东西。

我使用开箱即用的google.maps.Animation.DROP和各种setTimeout设置,并且无法提供令人满意的设置。最大的障碍似乎是同时发生的少量标记DROP会迅速降低动画的平滑度,从而导致标记出现难看,波涛汹涌,凌乱的雨水。它甚至撞坏了我的IE7 :(

换句话说,如果你想要一个好看的DROP序列,连续DROP之间的时间延迟需要相对较大(100-200毫秒),而在100个标记处,这意味着等待10到20秒,直到最后一个标记掉落我认为让最终用户完成整个动画的时间太长了,但如果DROP延迟很短,那么地图的动画看起来不太好。它是动画质量和加载速度之间的平衡。

一种解决方法可能是向地图添加点击侦听器,以便在触发时立即显示剩余的未显示标记。我没有在我的演示中添加这个逻辑。

这是demo on JSFiddle。有三个变量可供使用,一个控制标记的数量,另外两个控制标记DROP之间的延迟。您可以更改这些值,然后单击&gt;运行查看更改。

一些注意事项:

  1. 我对随机列表进行排序,以便标记从上到下掉落。我认为它看起来比标记的零星雨更好。您也可以按距离重写排序函数,以便首先接近预定义中心DROP的站点。

  2. 有一个自动执行的匿名函数包装超时,因此为每个标记创建了新的变量范围。

答案 1 :(得分:2)

如果您的网页需要很长时间才能加载,您可以选择使用callback异步加载Google Maps API,该<script> window.onload = loadGoogleMaps; function loadGoogleMaps() { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "http://maps.googleapis.com/maps/api/jssensor=false&callback=initialize"; document.body.appendChild(script); } 可能会被定义为加载Google Maps JavaScript库的网址上的参数:< / p>

initialize

这样您就可以保留现有的initialize()功能,该功能将在Google Maps JavaScript库完全加载后运行,但您需要删除当前位于您的$(document).ready之内的号码。 DROP以便它不会运行两次。

您不应该看到标记放在地图上的两步过程,然后是setMarkers动画。您可能还想查看setTimeout( function, delayInMilliseconds函数运行的时间长度,因为如果运行时间过长,则可能是您所描述内容的根本原因。

根据跟进编辑评论:

如果您想创建所有标记,可以在JavaScript中使用,但在每个标记创建之间添加延迟是JavaScript setTimeout函数。您必须跟踪调用中标记数组中的位置,但它的作用是将工作划分为不同的工作单元。使用{{1}},您应该能够在每个标记丢弃之间添加一个短暂的延迟,这可以为您提供您想要达到的效果。

答案 2 :(得分:1)

要按时间间隔创建标记,可以使用window.setTimeout(),例如:

//UNTESTED!!
            function setMarkers(map, markers) {
                   while (markers.length) {
                    var markerData = markers.shift();
                    window.setTimeout(function(){doSetMarker(markerData,map)},10);// 10 miliseconds. (play with this value).
                    }
                }

                function doSetMarker(markerData,map) {
                    var sites = markerData;
                    var siteLatLng = new google.maps.LatLng(parseFloat(sites[1]), parseFloat(sites[2]));
                    var marker = new google.maps.Marker({
                        position: siteLatLng,
                        map: map,
                        title: sites[0],
                        zIndex: sites[3],
                        html: sites[4],
                        animation: google.maps.Animation.DROP
                    });
                        var contentString = "Some content";
                        google.maps.event.addListener(marker, "click", function () {
                            infowindow.setContent(this.html);
                            infowindow.open(map, this);
                        });

                }