2010-04-20 39 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对象的功能阵列,请尝试使用对象整数“钥匙”来代替。

我从来没有亲自做过关于对象与数组查找的基准测试,但我有朋友坚持在某些情况下对象要快得多(即使理论上它们应该是可比较的)。

这是一个非常快速和简单的代码模式,所以为什么不尝试呢?