Optimizing a 3D World Javascript Animation
- by johnny
Hi!
I've recently come up with the idea to create a tag cloud like animation shaped like the earth. I've extracted the coastline coordinates from ngdc.noaa.gov and wrote a little script that displayed it in my browser. Now as you can imagine, the whole coastline consists of about 48919 points, which my script would individually render (each coordinate being represented by one span). Obviously no browser is capable of rendering this fluently - but it would be nice if I could render as much as let's say 200 spans (twice as much as now) on my old p4 2.8 Ghz (as a representative benchmark). Are there any javascript optimizations I could use in order to speed up the display of those spans?
One 'coordinate':
<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>
The script:
$(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
});
}
I'd appreciate any suggestions to optimize my script, maybe there is even a totally different approach on how to go about this.
The whole .js file which stores the array for all the coordinates is available on my page, the file is about 2.9 mb, so you might consider pulling the .zip for local testing:
metaroulette.com/files/31218.zip
metaroulette.com/files/31218.js
P.S. the php I use to create the spans:
<?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";
}
?>