Optimizing a 3D World Javascript Animation

Posted by johnny on Stack Overflow See other posts from Stack Overflow or by johnny
Published on 2010-04-20T22:11:30Z Indexed on 2010/04/20 22:13 UTC
Read the original article Hit count: 402

Filed under:
|
|
|

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";

                    }

                ?>

© Stack Overflow or respective owner

Related posts about JavaScript

Related posts about 3d