我最近提出了创建像地球一样的动画标签云的想法。我从ngdc.noaa.gov中提取了海岸线坐标,并编写了一个在我的浏览器中显示它的小脚本。现在你可以想象,整个海岸线由大约48919个点组成,我的脚本将单独渲染(每个坐标由一个跨度表示)。显然没有浏览器能够流畅地呈现这一点 - 但是如果我可以在旧的p4 2.8 Ghz(作为代表性基准)上渲染尽可能多的200跨度(现在的两倍),那就太好了。我是否可以使用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
P.S。我用来创建跨度的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 :(得分:1)
您可以随时使用<canvas>
element。它会在支持它的浏览器上更快地呈现更多。
但是,在版本9发布之前,您必须使用Internet Explorer的解决方法。您可以使用ExplorerCanvas来模拟IE的画布支持。但是,只知道它非常慢 - 甚至可能比你的算法慢。如果IE支持对您很重要,您可以要求用户安装Google Chrome Frame,如果他们想要在使用Internet Explorer浏览器时获得更好的体验;但除此之外,你无法在IE中加快这种速度。
答案 1 :(得分: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对象的函数,请尝试使用带有整数“keys”的对象。
我从来没有亲自完成对象与数组查找的基准测试,但我有朋友坚持认为在某些情况下对象速度要快得多(尽管理论上它们应该具有可比性)。
这是一个非常快速简单的代码模型,为什么不尝试呢?