2010-04-20 42 views
2

我最近想出了創建標籤雲的想法,就像動畫像地球一樣。我已經從ngdc.noaa.gov提取海岸線座標,並編寫了一個腳本,在瀏覽器中顯示它。現在,您可以想象,整個海岸線由大約48919個點組成,我的腳本將單獨渲染(每個座標由一個跨度表示)。顯然,沒有瀏覽器能夠流利地渲染 - 但如果我能夠在我的舊版P4 2.8 Ghz(作爲代表性基準)上渲染200個跨度(現在的兩倍),那將是一件好事。有什麼JavaScript優化,我可以用來加快顯示這些跨度?優化3D世界的Javascript動畫

一個「座標」:

<div id="world_pixels"> 
<span id="wp_0" style="position:fixed; top:0px; left:0px; z-index:1; font-size:20px; cursor:pointer;cursor:hand;" onmouseover="magnify_world_pixel('wp_0');" onmouseout="shrink_world_pixel('wp_0');" onClick="set_askcue_bar('', 'new york')">new york</span> 
</div> 

腳本:

$(document).ready(function(){ 

     world_pixels = $("#world_pixels span"); 

     world_pixels.spin(); 

     setInterval("world_pixels.spin()",1500); 

}); 


z = new Array(); 

$.fn.spin = function() { 

    for(i=0; i<this.length; i++) { 

      /*actual screen coordinates: x/y/z --> left/font-size/top 
        300/13/0 300/6/300 
         |/
         |/ 
      0/13/300 ----|---- 600/13/300 
         /| 
        /| 
       300/20/300 300/13/600 
      */ 

      /*scale font size*/ 
     var resize_x = 1; 
      /*scale width*/ 
     var resize_y = 2.5; 
      /*scale height*/ 
     var resize_z = 2.5; 

     var from_left = 300; 
     var from_top = 20; 

      /*actual math coordinates: 

         1 -1 
         |/
         |/ 
        1 ----|---- -1 
         /| 
        /| 
         1 -1 
      */ 

     //var get_element = document.getElementById(); 
     //var font_size = parseInt(this.style.fontSize); 
     var font_size = parseInt($(this[i]).css("font-size")); 

     var left = parseInt($(this[i]).css("left")); 




     if (coast_line_array[i][1]) { 

     } else { 

      var top = parseInt($(this[i]).css("top")); 

      z[i] = from_top + (top - (300 * resize_z))/(300 * resize_z); 
      //global beacause it's used in other functions later on 

      var top_new = from_top + Math.round(Math.cos(coast_line_array[i][2]/90*Math.PI) * (300 * resize_z) + (300 * resize_z)); 

      $(this[i]).css("top", top_new); 

      coast_line_array[i][3] = 1; 

     } 


     var x = resize_x * (font_size - 13)/7; 

     var y = from_left + (left- (300 * resize_y))/(300 * resize_y); 




     if (y >= 0) { 

      this[i].phi = Math.acos(x/(Math.sqrt(x^2 + y^2))); 

     } else { 

      this[i].phi = 2*Math.PI - Math.acos(x/(Math.sqrt(x^2 + y^2))); 
      i 
     } 

     this[i].theta = Math.acos(z[i]/Math.sqrt(x^2 + y^2 + z[i]^2)); 

     var font_size_new = resize_x * Math.round(Math.sin(coast_line_array[i][4]/90*Math.PI) * Math.cos(coast_line_array[i][0]/180*Math.PI) * 7 + 13); 

     var left_new = from_left + Math.round(Math.sin(coast_line_array[i][5]/90*Math.PI) * Math.sin(coast_line_array[i][0]/180*Math.PI) * (300 * resize_y) + (300 * resize_y)); 



     //coast_line_array[i][6] = coast_line_array[i][7]+1; 

     if ((coast_line_array[i][0] + 1) > 180) { 

      coast_line_array[i][0] = -180; 

     } else { 

      coast_line_array[i][0] = coast_line_array[i][0] + 0.25; 

     } 

     $(this[i]).css("font-size", font_size_new); 

     $(this[i]).css("left", left_new); 




    } 

} 

resize_x = 1; 

function magnify_world_pixel(element) { 

    $("#"+element).animate({ 
     fontSize: resize_x*30+"px" 
        }, { 
     duration: 1000 
        }); 

} 

function shrink_world_pixel(element) { 

    $("#"+element).animate({ 
     fontSize: resize_x*6+"px" 
        }, { 
     duration: 1000 
        }); 



} 

我會很感激的任何建議,以優化我的劇本,也許甚至有關於如何去一個完全不同的方法這個。 存儲陣列的所有座標整個.js文件可我的網頁上,該文件是大約2.9 MB,所以你可以考慮拉的.zip本地測試:

metaroulette.com/files/31218.zip

metaroulette。 com/files/31218.js

PS我用來創建跨度的php:

<?php 

       //$arbitrary_characters = array('a','b','c','ddsfsdfsdf','e','f','g','h','isdfsdffd','j','k','l','mfdgcvbcvbs','n','o','p','q','r','s','t','uasdfsdf','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9',); 
       $arbitrary_characters = array('cat','table','cool','deloitte','askcue','what','more','less','adjective','nice','clinton','mars','jupiter','testversion','beta','hilarious','lolcatz','funny','obama','president','nice','what','misplaced','category','people','religion','global','skyscraper','new york','dubai','helsinki','volcano','iceland','peter','telephone','internet', 'dialer', 'cord', 'movie', 'party', 'chris', 'guitar', 'bentley', 'ford', 'ferrari', 'etc', 'de facto'); 


        for ($i=0; $i<96; $i++) { 

         $arb_digits = rand (0,45); 

         $arbitrary_character = $arbitrary_characters[$arb_digits]; 
         //$arbitrary_character = "."; 

         echo "<span id=\"wp_$i\" style=\"position:fixed; top:0px; left:0px; z-index:1; font-size:20px; cursor:pointer;cursor:hand;\" onmouseover=\"magnify_world_pixel('wp_$i');\" onmouseout=\"shrink_world_pixel('wp_$i');\" onClick=\"set_askcue_bar('', '$arbitrary_character')\">$arbitrary_character</span>\n"; 

        } 

       ?> 
+0

檢查了這一點 - 我瞭解它,並可能能夠幫助您http://code.google.com/closure/ – 2010-04-20 22:22:22

回答

1

您可以隨時使用<canvas> element。它在支持它的瀏覽器上更快速地提供更多

但是,您必須使用Internet Explorer的解決方法,直到版本9出來。您可以使用ExplorerCanvas模仿IE瀏覽器畫布的支持。但是,只要知道它非常慢 - 甚至可能比您的算法慢。如果IE支持對你很重要,你可以要求用戶安裝Google Chrome Frame,如果他們想要更好的體驗,同時仍然使用Internet Explorer瀏覽器;但除此之外,在IE中加速這種事情並不多。

+0

在IE中的舊故事。意味着我可能不得不在服務器端檢查用戶擁有哪個瀏覽器併發送適當的腳本。絕對會給帆布嘗試 - thnx! – jcfrei 2010-04-20 22:29:35

1

嗯,我看到一個簡單的優化:

for(i=0;i<this.length; i++) { 

您this.length每次檢查這個循環迭代。這很昂貴,除非你預計長度會改變,不必要的。

嘗試:

for(i=0,ii=this.length;i<ii; i++) { 

代替。

我沒有做太多的速度,關鍵工作JS,所以我只能提供一些試探性的建議。

你可進行移動一些繁重的計算的一個WebWorker,但我不知道,如果你的情況會從中受益很多。

檢查出來這裏:https://developer.mozilla.org/En/Using_web_workers

另外,如果你不使用任何的Array對象的功能陣列,請嘗試使用對象整數「鑰匙」來代替。

我從來沒有親自做過關於對象與數組查找的基準測試,但我有朋友堅持在某些情況下對象要快得多(即使理論上它們應該是可比較的)。

這是一個非常快速和簡單的代碼模式,所以爲什麼不嘗試呢?