Displaying unique objects generated by Raphael.js in FancyBox I'm using Raphael.js to generate objects which are unique but do basically the same thing. I'm also using Fancybox to display a unique image after a click on a generated object.

Is there a way to write this more concise?

//OBJECT 101
    var p1_101 = p1.path("M361,146.773 366.25,192.94 365.917,196.606 366.583,199.69 387,197.773 392.417,179.023 387.75,178.273 395.833,146.106 397.583,145.94 398,143.023 374,145.273z").attr({"fill":"#d3ae6b", "stroke-width": 0, "fill-opacity": .5, "stroke": "transparent","cursor": "pointer", "title": "101"}).click(function () { 
        $.fancybox.open([
            {
                href : 'img/rzuty/p1/101.jpg',
                openEffect : 'elastic',
                openSpeed  : 150,
                closeEffect : 'elastic',
                closeSpeed  : 150,
                padding: 2,
            }
        ], {
            beforeShow : function() {
                $('&lt;a class="pdf" href="img/rzuty/p1/101.pdf" target="_blank"&gt;&lt;/a&gt;').appendTo(".fancybox-inner");                   
            }
        });
    }).mouseover(
        function () {
            this.animate({"fill-opacity": .8}, 200);
        }).mouseout(function () {
            this.animate({"fill-opacity": .5}, 200);
    });

    //SETTING CLASS AND ID
    p1_101.node.setAttribute('class','reserved'); // CLASS 'reserved' OR 'sold'
    p1_101.node.id = 'p1_101';


    //OBJECT 102
    var p1_102 = p1.path("M337.583,149.023 342.667,196.69 342.333,197.023 342.833,202.107 365.667,199.857 365.167,194.523 364.667,194.357 359.917,150.357 356,150.773 355.75,147.19z").attr({"fill":"#d3ae6b", "stroke-width": 0, "fill-opacity": .5, "stroke": "transparent","cursor": "pointer", "title": "102"}).click(function () { 
        $.fancybox.open([
            {
                href : 'img/rzuty/p1/102.jpg',
                openEffect : 'elastic',
                openSpeed  : 150,
                closeEffect : 'elastic',
                closeSpeed  : 150,
                padding: 2,
            }
        ], {
            beforeShow : function() {
                $('&lt;a class="pdf" href="img/rzuty/p1/102.pdf" target="_blank"&gt;&lt;/a&gt;').appendTo(".fancybox-inner");                   
            }
        });
    }).mouseover(
        function () {
            this.animate({"fill-opacity": .8}, 200);
        }).mouseout(function () {
            this.animate({"fill-opacity": .5}, 200);
    });

    //SETTING CLASS AND ID
    p1_102.node.setAttribute('class','sold'); // CLASS 'reserved' OR 'sold'
    p1_102.node.id = 'p1_102';


    //OBJECT 103
    var p1_103 = p1.path("M314.5,155.107 319.167,197.607 319.167,199.19 318.667,199.44 319.25,204.357 342,202.273 341.583,197.023 340.833,196.607 340.833,195.357 335.917,149.357 331.833,149.607 316.5,151.107 316.75,154.607z").attr({"fill":"#d3ae6b", "stroke-width": 0, "fill-opacity": .5, "stroke": "transparent","cursor": "pointer", "title": "103"}).click(function () { 
        $.fancybox.open([
            {
                href : 'img/rzuty/p1/103.jpg',
                openEffect : 'elastic',
                openSpeed  : 150,
                closeEffect : 'elastic',
                closeSpeed  : 150,
                padding: 2,
            }
        ], {
            beforeShow : function() {
                $('&lt;a class="pdf" href="img/rzuty/p1/103.pdf" target="_blank"&gt;&lt;/a&gt;').appendTo(".fancybox-inner");                   
            }
        });
    }).mouseover(
        function () {
            this.animate({"fill-opacity": .8}, 200);
        }).mouseout(function () {
            this.animate({"fill-opacity": .5}, 200);
    });

    //SETTING CLASS AND ID
    p1_103.node.setAttribute('class','reserved'); // CLASS 'reserved' OR 'sold'
    p1_103.node.id = 'p1_103';
Well you could author a jQuery plugin. That would have default settings, with the option of passing some parameters and override settings.

General ideas behind this are :


Making reusable code. Another project with similar stuff? You include the lib and re-use it.
Making the code as dry as possible. Writing the same thing again and again is annoying and hard to refactor. In a plugin everything is wrote once.
Even though you want everything to look the same, you have to build it a way you can override default setting, because there's always one object that need to be different.




I haven't debug the whole  plugin as I had no idea what did a paper object looked lik. But it seemed like it was a jQuery built object as you called .attr, .mouseover and .mouseout which are jQuery function. Though I have debugged the rest of the plugin without calling .path and it was working.

To call the plugin just do something like :

var basePath = 'img/rzuty/p1/';
paperObject.animatePath('M36.146...', 101, basePath);
paperObject.animatePath('M337.583...', 102, basePath); 
//...


So the plugin code looks like that :

(function ($) {
    /**
     *
     * @param path the paper path
     * @param imageNumber the image number which is used in href and pdf and for the id
     * @param basePath the base path for the image
     * @param options option to override defaults settings
     */
    $.fn.animatePath = function (path, imageNumber, basePath, options) {

        //Default settings
        var defaults = {
            htmlAttr: {
                'class': 'reserved',
                    'id': 'ap_' + imageNumber
            },
            cssOptions: {
                fill: '#d3ae6b',
                    'stroke-width': 0,
                    'fill-opacity': 0.5,
                stroke: 'transparent',
                cursor: 'pointer',
                title: imageNumber
            },
            fancyboxOptions: {
                href: basePath + imageNumber + '.jpg ',
                openEffect: 'elastic',
                openSpeed: 150,
                closeEffect: 'elastic',
                closeSpeed: 150,
                padding: 2
            },
            fancyboxAnimations: {
                beforeShow: function () {
                    $('&lt;a class ="pdf" href="' + basePath + imageNumber + '.pdf' + '"target="_blank" &gt;&lt;/a&gt;')
                        .appendTo(".fancybox-inner");
                }
            },
            mouseOver: function () {
                $(this).animate({
                    'fill-opacity': 0.8
                }, 200);
            },
            mouseOut: function () {
                $(this).animate({
                    'fill-opacity': 0.5
                }, 200);
            }

        };

        //Merge settings
        var settings = $.extend(true, defaults, options || {});

        //Add the fancybox and stuff
        this.path(path)
            .attr(settings.htmlAttr)
            .css(settings.cssOptions);
        this.click(function () {
            $.fancybox.open([settings.fancyboxOptions], settings.fancyboxAnimations);
        });
        this.mouseover(settings.mouseOver);
        this.mouseout(settings.mouseOut);

        return this;
    };
})(jQuery);


As you can see every default settings is defined in an object and you can override it by passing it in the options object (which is then merge recursively with the defaults object). The nice thing is that it is now easily reusable. Also, using function($){}(jQuery); enclose the function scope so that it doesn't clash with any other library using $.

Here is a link to a fiddle, be free to update it with the paperObject, because I couldn't do it not knowing what it was.



To learn more about jQuery Authoring.