2013-05-20 62 views
6

我開始使用maps api v3實現我的軟件。不幸的是,我發現v3 API有一些嚴重的問題,這些問題將我從商業許可證中吸引回來。谷歌地圖api v3沒有流暢的拖拽

我的客戶使用高清分辨率爲1920x1080的顯示器,地圖佔用了屏幕空間的90%。不幸的是,這裏出現了我正在談論的問題。當我在地圖上用鼠標點擊並開始拖動它時,它不是平滑地它真的很煩人。所有的樂趣都消失了。

我嘗試使用視窗XP,Windows 7和Windows 8一些不同scenarious我與工作中的瀏覽器Firefox的是,Chrome和IE的最新版本。 下面是結果,當我嘗試拖動地圖:

  1. 小屏幕分辨率320×240:火狐,Chrome和IE處理得很好。不可能注意到拖動不順暢。
  2. 小屏幕分辨率爲320x240,在地圖上有10條折線:Chrome和IE可以很好地處理這種情況,但如果您有關於v2 API的經驗,您會發現它們有所不同。火狐 - 噩夢,拖拽根本不流暢。
  3. 中等屏幕分辨率1024x768。 Firefox - 有一些滯後性滯後。 Chrome瀏覽器和IE瀏覽器 - 平滑拖曳,但如果你移動鼠標,事情會變得更糟。
  4. 中等屏幕分辨率1024x768,在地圖上有10條折線。火狐 - 惡夢。 Chrome和IE瀏覽器 - 你開始注意到有一些延遲,但同時它看起來很平穩。
  5. 高屏幕分辨率1920x1080。 Firefox - 巨大的滯後。 Chrome和IE - 稍微好一點,但仍然存在明顯的滯後。 6)屏幕分辨率高達1920x1080,地圖上有折線:Firefox,Chrome ad IE - NIGHTMARE。拖動地圖幾乎是不可能的。

有趣的事實:

  1. 上面並沒有與谷歌地圖的API V2存在所述的問題。
  2. 當鼠標移動速度低於每秒50-60像素時,上述問題不存在。拖動非常流暢。當鼠標快速移動時,會出現滯後現象。
  3. http://maps.google.com這個問題根本不存在但是當我打開開發者的一些代碼示例時,指導問題就在那裏。這裏是一個例子:https://google-developers.appspot.com/maps/documentation/javascript/examples/full/circle-simple

我認爲我描述的問題儘可能深,無論我多麼努力地繞過它,我找不到任何解決方案。

如果有人分享他們對這個問題的看法,我會很高興。

P.S.不幸的是,我沒有V2的關鍵,所以我不能創建一個例子,您可以查看我的本地主機外的地圖,但我發現一個網站有一個並排比較(V2和V3)。嘗試拖動地圖看到非常不同。

http://www.wolfpil.de/v2-v3-sidebyside.html

地圖的分辨率是很小的,很可能沒有經驗的用戶可能看不出來區別,所以我會給你也是單獨的鏈接到地圖,你只需要使用螢火蟲或類似debuger使畫布分辨率更大。然後你會看到我在說什麼。

回答

5

同樣在這裏。我注意到,v3在瀏覽地圖時觸發了大量事件,瀏覽器往往會窒息(尤其是FF)。我這樣說是因爲我還使用了Bing Maps API,並且每秒鐘的事件數爲viewchange(相當於Google中的center_changed)要小得多。他們還提供了方法addThrottledHandler(),可以減少生成的事件數量。

從我所知道的情況來看,Google地圖似乎爲每個mousemove事件觸發了一個center_changed事件,並且在地圖視圖更新之前觸發了一個center_changed事件。所以你會得到很多生成的事件,但是沒有一個會在屏幕上覆制;瀏覽器窒息地圖視圖更新,或者可能是地圖等待,直到沒有更多的更改,只有它更新視圖。

編輯:如果我們避免一些mousemove事件達到谷歌地圖,然後瀏覽器不會嗆mousemove事件加上所有的谷歌地圖從該事件中產生,如center_changed其他事件,而地圖將順利平移。

爲此,我們爲#map div添加一個事件監聽器(我們也可以將它添加到body標籤中)。我們添加捕獲階段的事件。當鼠標在屏幕上移動時,首先body標籤接收事件,然後我們的#map div,然後Google地圖元素(div,tile)。這是捕獲階段。接下來是氣泡階段,其中事件從Google地圖元素返回到我們的#map div,然後到body標記。通常事件處理程序是爲冒泡階段註冊的,所以如果我們爲捕獲階段註冊一個處理程序,我們可以取消事件,因此這個事件不會有冒泡階段。這也意味着Google地圖不會收到該活動。

您可以增加參數periodspace以殺死更多事件。殺死太多事件意味着地圖將開始從一個位置跳到下一個位置。殺死太少意味着所有事件都會到達谷歌地圖,並且瀏覽器會窒息Google地圖中新生成的事件,因此地圖會從一個位置跳到另一個位置。一些中間地帶效果最好。

現在畢竟這些,谷歌地圖將不會像Bing地圖那樣流暢。這是因爲Bing地圖使用慣性:當您猛烈地移動地圖時,地圖將慢慢地開始跟隨鼠標,然後越來越快。這確實創造了一個非常平滑的鍋。

我發現一個有趣的事實是,即使鼠標不移動,Google Chrome和Opera/Chrommium每秒鐘也會產生大約一個mousemove事件!該代碼也會殺死這些事件(因爲distance對於這些事件爲零)。

http://jsfiddle.net/uNm57/(請在Firefox JS控制檯,你應該看到都會停止,然後允許一個事件的一些事件)

<html> 
    <head> 
    <style type='text/css'> 
     #map { 
      position: absolute; 
      width: 100%; 
      height: 100%; 
      margin: 20px; 
     } 
    </style> 

    <script type='text/javascript'> 
     var last = {time : new Date(), // last time we let an event pass. 
        x : -100,   // last x position af the event that passed. 
        y : -100};   // last y position af the event that passed. 
     var period = 100; // ms - don't let pass more than one event every 100ms. 
     var space = 2; // px - let event pass if distance between the last and 
         //  current position is greater than 2 px. 

     function init_map() { 
      map_div = document.getElementById("map") 
      // map 
      var map_options = { 
       center: new google.maps.LatLng(45.836454, 23.372497), 
       zoom: 8 
      }; 
      map = new google.maps.Map(document.getElementById("map"), map_options); 

      // register event handler that will throttle the events. 
      // "true" means we capture the event and so we get the event 
      // before Google Maps gets it. So if we cancel the event, 
      // Google Maps will never receive it. 
      map_div.addEventListener("mousemove", throttle_events, true); 
     }; 

     function throttle_events(event) { 
      var now = new Date(); 
      var distance = Math.sqrt(Math.pow(event.clientX - last.x, 2) + Math.pow(event.clientY - last.y, 2)); 
      var time = now.getTime() - last.time.getTime(); 
      if (distance * time < space * period) { //event arrived too soon or mouse moved too little or both 
       console.log("event stopped"); 
       if (event.stopPropagation) { // W3C/addEventListener() 
        event.stopPropagation(); 
       } else { // Older IE. 
        event.cancelBubble = true; 
       }; 
      } else { 
       console.log("event allowed: " + now.getTime()); 
       last.time = now; 
       last.x = event.clientX; 
       last.y = event.clientY; 
      }; 
     }; 
    </script> 
</head> 
<body onload = "init_map()"> 
    <div id="map"></div> 
</body> 
</html> 
+0

所以讓我們嘗試找到一個解決方案:) –

+0

當我刪除顯卡驅動程序或登錄通過遠程桌面問題不在那裏:) –

+0

我有一個想法。我會回來的 :)。 – GoTo