I've been building a coloring book for kids: http://coloringbook.core.ba.lightburncloud.com/It's got to work on an iPad, so I decided to try out Raphal JS.  I want to try and make this as efficient as possible, and was wondering if anybody had any suggestions on how to tighten things up.I'm just kind of flying by the seat of my pants here, so if anybody has any best practices/general tips for Raphal (or jQuery, or JavaScript), it'd help me out a lot.// Primes the page, gets the scene via JSON// -------------------------------------------------------------------var engine = {    paper           : Object,    prime           : function(){        // Makes new instance of scalable raphael        engine.paper = new ScaleRaphael(stage, 960, 525);        engine.handleResize();        $(window).resize(engine.handleResize);     },    load            : function(json){               $.getJSON(json, function(data){            // Collects Scene Elements            scene.set(data.elements);            // Collects Colors            color.set(data.colors);                     // Collects Audio Elements            audio.set(data.audio);            // Collects Save State Elements            save.set(data.state);            // Sets up ui            engine.uiAudio();            engine.uiControls();        });    },    handleResize    : function(){        // Resizes stage        var win = $(window);        engine.paper.changeSize(win.width(), win.height(), true, false);    },    handleClick     : function(elem){        if(elem.attr('fill') != color.active){            // Saves the previous state to the history stack            history.save(elem.id, elem.attr('fill'));            // Fill with active color            elem.attr('fill', color.active);            //Save ID & Color, eg:            //$.post([url of save function], { id : elem.id, color : color.active });            //console.log(elem.id + ' ' + color.active)        }        // Gets name, checks to see if there's audio associated with it        audio.check(elem.data(name));    },    uiAudio         : function(){        $('body').append('<div id=uiPop></div>');        $('#uiPop').jPlayer({            ready   : function(){                $(this).jPlayer('setMedia', {                    wav: cogs/audio/ui/pop.wav,                    mp3: cogs/audio/ui/pop.mp3                });            },            swfPath: cogs/scripts,            supplied: wav, mp3,            wmode: window        });    },    uiControls      : function(){        var buttonStyle = {                'stroke-width' : '5px',                'stroke' : '#d1d2d3',                'fill' : '#0082c8'            },            shadowStyle = {                'stroke-width' : '0',                'stroke' : 'transparent',                'fill' : 'r#666666-#73afdf'                     },            iconStyle = {                'stroke-width' : '0',                'stroke' : 'transparent',                'fill' : '#fff'                     }        // Home Button -----------------------------------------------            var homeButton = engine.paper.set();            // shadow            engine.paper.ellipse(895, 96, 40, 15).attr(shadowStyle);            // button            homeButton.push(engine.paper.ellipse(895, 60, 35, 35).attr(buttonStyle).attr('href','http://www.google.com'));            homeButton.push(engine.paper.path(M895.025,41.46L875,60.962h4.536v15.383c0,1.213,1.311,2.195,2.927,2.195h25.152 c1.617,0,2.928-0.982,2.928-2.195V60.962H915L895.025,41.46z).attr(iconStyle).attr('href','http://www.google.com'));            // events            homeButton.hover(function(){                homeButton[0].attr('stroke','#fff');            },function(){                homeButton[0].attr('stroke','#d1d2d3');            });        // -----------------------------------------------------------        // Sound Button ----------------------------------------------             var soundButton = engine.paper.set();            // shadow            engine.paper.ellipse(895, 296, 40, 15).attr(shadowStyle);            // button            soundButton.push(engine.paper.ellipse(895, 260, 35, 35).attr(buttonStyle));            soundButton.push(engine.paper.path(M920.156,260c0-13.871-11.284-25.156-25.156-25.156c-7.395,0-14.057,3.21-18.664,8.31  c-0.012,0.012-0.028,0.021-0.041,0.034c-0.07,0.07-0.134,0.147-0.186,0.228c-3.895,4.431-6.266,10.235-6.266,16.584  c0,13.871,11.286,25.156,25.156,25.156c6.294,0,12.053-2.328,16.47-6.164c0.132-0.068,0.26-0.149,0.368-0.261  c0.074-0.072,0.137-0.152,0.189-0.233C917.022,273.897,920.156,267.309,920.156,260z M917.283,260  c0,6.107-2.472,11.648-6.467,15.678l-31.494-31.494c4.03-3.994,9.57-6.466,15.678-6.466  C907.287,237.717,917.283,247.713,917.283,260z M872.718,260c0-5.146,1.759-9.884,4.697-13.66l31.246,31.245  c-3.775,2.938-8.517,4.698-13.661,4.698C882.714,282.283,872.718,272.286,872.718,260z).attr(iconStyle).hide());            soundButton.push(engine.paper.path(M904.188,255.004c-1.183-2.239-3.318-3.446-5.036-5.218c-1.323-1.365-2.391-2.973-2.918-4.813  c-0.073-0.261-0.371-1.102-0.391-1.632v-0.102c0.005-0.103,0.022-0.19,0.06-0.25c0,0-0.023,0.037-0.06,0.095v-0.095  c0-0.341-0.276-0.618-0.617-0.618s-0.618,0.276-0.618,0.618v27.036c-1.332-0.96-3.544-1.144-5.729-0.32  c-2.979,1.125-4.77,3.693-3.998,5.736c0.77,2.044,3.811,2.789,6.791,1.665c2.449-0.924,4.09-2.822,4.171-4.604  c0-0.001,0-0.002,0-0.002v-22.568l0.059,0.073c0.676,1.572,2.831,2.661,2.831,2.661c2.147,1.083,4.159,3.058,4.864,5.38  c0.625,2.059,0.271,4.383-0.497,6.356c-0.353,0.905-0.795,2.041-1.464,2.776c1.349-1.483,2.639-3.338,3.256-5.26  C905.643,259.583,905.321,257.152,904.188,255.004z).attr(iconStyle));;            // events            soundButton.hover(function(){                soundButton[0].attr('stroke','#fff');            },function(){                soundButton[0].attr('stroke','#d1d2d3');            }).click(function(){                if(audio.isOn){                    audio.isOn = false;                    soundButton[1].show();                }else{                    audio.isOn = true;                    soundButton[1].hide();                }            });        // -----------------------------------------------------------        // Clear Button ----------------------------------------------            var clearButton = engine.paper.set();            // shadow            engine.paper.ellipse(895, 396, 40, 15).attr(shadowStyle);            //button            clearButton.push(engine.paper.ellipse(895, 360, 35, 35).attr(buttonStyle))            clearButton.push(engine.paper.path(M899.326,343.448c0-2.286-1.989-2.286-1.989-2.286h-3.38c-2.585,0-2.286,2.286-2.286,2.286 H899.326z M906.085,344.84c0,0-18.49,0-22.565,0c-4.076,0-3.878,3.877-3.878,3.877h30.718 C910.359,344.542,906.085,344.84,906.085,344.84z M883.966,374.961c0.497,3.777,4.474,3.877,4.474,3.877h12.525 c4.672,0,5.069-4.075,5.069-4.075l2.784-24.355h-27.637C881.182,350.407,883.47,371.184,883.966,374.961z M901.411,353.741 c0.035-0.591,0.539-1.044,1.132-1.007c0.59,0.034,1.041,0.541,1.007,1.131l-1.158,19.947c-0.033,0.569-0.505,1.01-1.068,1.01 c-0.021,0-0.042-0.002-0.063-0.002c-0.59-0.034-1.041-0.541-1.007-1.132L901.411,353.741z M893.93,353.787 c0-0.592,0.479-1.071,1.071-1.071c0.591,0,1.07,0.479,1.07,1.071v19.98c0,0.591-0.479,1.071-1.07,1.071 c-0.593,0-1.071-0.48-1.071-1.071V353.787z M887.533,352.734c0.586-0.036,1.097,0.416,1.13,1.007l1.159,19.947 c0.034,0.591-0.416,1.098-1.007,1.132c-0.021,0-0.042,0.002-0.063,0.002c-0.563,0-1.035-0.44-1.068-1.01l-1.159-19.947 C886.491,353.275,886.942,352.769,887.533,352.734z).attr(iconStyle));            // events            clearButton.hover(function(){                clearButton[0].attr('stroke','#fff');            },function(){                clearButton[0].attr('stroke','#d1d2d3');            }).click(function(){                scene.colorable.attr('fill','#fff');                history.clear();            });        // -----------------------------------------------------------        // Undo Button -----------------------------------------------            var undoButton = engine.paper.set();            // shadow            engine.paper.ellipse(895, 496, 40, 15).attr(shadowStyle);            // button            undoButton.push(engine.paper.ellipse(895, 460, 35, 35).attr(buttonStyle));            undoButton.push(engine.paper.path(M917.962,441.608l-15.218-1.075l-1.074,15.219l6.732-5.843c2.508,3.128,3.88,6.97,3.88,11.048 c0,9.78-7.956,17.736-17.736,17.736c-9.779,0-17.736-7.956-17.736-17.736c0-4.736,1.846-9.189,5.195-12.541l-3.374-3.374 c-4.252,4.251-6.593,9.905-6.593,15.915c0,12.412,10.097,22.51,22.508,22.51c12.41,0,22.509-10.098,22.509-22.51 c0-5.244-1.776-10.189-5.038-14.186L917.962,441.608z).attr(iconStyle));            // events            undoButton.hover(function(){                undoButton[0].attr('stroke','#fff');            },function(){                undoButton[0].attr('stroke','#d1d2d3');            }).click(function(){                history.recall();            });        // -----------------------------------------------------------    }}// -------------------------------------------------------------------// Handles colors// -------------------------------------------------------------------var color = {    active          : Object,    list            : Object,    set             : function(array){        color.list = engine.paper.set();        var shadowStyle = {                'stroke-width' : '0',                'stroke' : 'transparent',                'fill' : 'r#666666-#73afdf'                     }        // Displays Colors        for(var i = 0; i < array.length; i++){            // Shadows            var x = 96+(100*i);            engine.paper.ellipse(65, x, 40, 15).attr(shadowStyle)               var y = 60+(100*i);            color.list.push(                engine.paper.ellipse(65, y, 35, 35).attr({                    'stroke-width' : '5px',                    'stroke' : '#d1d2d3',                    'fill' : '#'+array[i].hex                }).hover(function(){                    this.attr('stroke','#fff')                }, function(){                    if(!this.data('active')){                        this.attr('stroke','#d1d2d3');                    }                }).click(function(){                    color.handleClick(this);                })            );        }        // Sets Active Color        color.active = '#'+array[0].hex        color.list[0].attr('stroke','#fff').data('active',true);    },    handleClick     : function(elem){        color.active = elem.attr('fill');        color.list.attr('stroke','#d1d2d3').removeData('active');        elem.attr('stroke','#fff').data('active',true);    }}// -------------------------------------------------------------------// Handles scene// -------------------------------------------------------------------var scene = {    outlines        : Object,    colorable       : Object,    set             : function(array){        // Initializes the sets        scene.outlines = engine.paper.set();        scene.colorable = engine.paper.set();           // Draws Objects, puts outlines in one set, colorable items in the other        for(var i = 0; i < array.length; i++){                  if(array[i].colorable == 'true'){                scene.colorable.push(                    eval('engine.paper.' + array[i].type +'('+array[i].coords+').data(name,'+array[i].name+')')                );            }else{                scene.outlines.push(                    eval('engine.paper.' + array[i].type +'('+array[i].coords+')')                );                      }        }        // Colors the outlines        scene.outlines.attr({            'fill' : '#000',            'stroke' : 'transparent',            'stroke-width' : 0        });        // Colors the colorable items        scene.colorable.attr({            'fill' : '#fff',            'stroke' : 'transparent',            'stroke-width' : 0              });        // Listens for clicks on the colorable items        scene.colorable.forEach(function(e){            e.click(function(){                engine.handleClick(this);            });        });        // Shifts elements over        engine.paper.forEach(function(elem){            elem.translate(130,0);        });    }}// -------------------------------------------------------------------// Sets up audio// -------------------------------------------------------------------var audio = {    collection      : [],    isOn            : true,    set             : function(array){        for(var i = 0; i < array.length; i++){            var a = array[i].wav,                b = array[i].mp3,                id = 'audio_'+i,                rel = array[i].rel;            $('body').append('<div id='+id+'></div>');            $('#'+id).jPlayer({                ready   : function(){                    $(this).jPlayer('setMedia', {                        wav: a,                        mp3: b                    });                },                play    : function(){                    $(this).jPlayer(pauseOthers);                },                swfPath: cogs/scripts,                supplied: wav, mp3,                wmode: window            });            audio.collection.push({                rel : rel,                id : id            });        }    },    check           : function(name){           var audID,            play = false;        for(var i = 0; i < audio.collection.length; i++){            if(audio.collection[i].rel == name){                audID = audio.collection[i].id;                play = true;            }        }        if(play && audio.isOn){            $('#'+audID).jPlayer('play');        }else if(audio.isOn){            $('#uiPop').jPlayer('play');        }    }}// -------------------------------------------------------------------// Handles Saved data// -------------------------------------------------------------------var save = {    set             : function(array){        for(var i = 0; i < array.length; i++){            // Gets elements by saved ID, sets color to saved color            engine.paper.getById(array[i].id).attr('fill',array[i].color)        }    }}// -------------------------------------------------------------------// History// -------------------------------------------------------------------var history = {    stack           : [],    save            : function(id, color){        // Pushes state onto the stack        history.stack.push({            id : id,            color : color        });    },    recall          : function(){        // Recalls previous state        if(history.stack.length){            var prev = history.stack.pop()            engine.paper.getById(prev.id).attr({                fill        : prev.color            })        }    },    clear           : function(){        // Clears history        history.stack.length = 0;    }}// -------------------------------------------------------------------// Start// -------------------------------------------------------------------$(function(){    engine.prime();    engine.load('cogs/scenes/choking2.json');})// -------------------------------------------------------------------
Optimize  coloring book built with Raphal and jQuery
javascript;jquery;optimization;svg;raphael.js