views:

82

answers:

3

I am adapting the Coverflow technique to work with a div. Following is the html:

    <html> 
 <head> 
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
  <style type="text/css" media="screen"> 
   body,html {
    margin: 0;
    padding: 0;
    background: #000;
    height: 100%;
    color: #eee;
    font-family: Arial;
    font-size: 10px;
   }
   div.magnifyme {
    height: 80px;
    padding: 80px;
    position: absolute;
    top: 0px;
    left: 0px;
    width: 2000px;
   }
   div.wrapper {
    margin: 0px;
    height: 470px;
    /*border: 2px solid #999;*/
    overflow: hidden;
    padding-left: 40px;
    right: 1px;
    width: 824px;
    position: relative;
   }

   div.container {position: relative; width: 854px; height: 480px; background: #000; margin: auto;}
   div.nav {position: absolute; top: 10px; width: 20%; height: 10%; right: 1px; }
   div.magnifyme div {
    position: absolute;
    width: 300px;
    height: 280px;
    float: left;
    margin: 5px;
    position: relative;
    border: 2px solid #999;
    background: #500;
   }
  </style> 
  <script type="text/javascript" src="jquery-1.3.2.js"></script> 
  <script type="text/javascript" src="ui.coverflow.js"></script> 
  <script type="text/javascript" src="ui.core.js"></script>  
  <script type="text/javascript"> 
   $(function() {
              $("div.magnifyme").coverflow();
    $("#add").click(function() {
     $(".magnifyme").append("<div id=\"div5\">hello world</div>");
     $("div.magnifyme").coverflow();
    });

   });

  </script> 
 </head> 
 <body> 
    <div class="container">
    <div class="wrapper"> 
  <div class="magnifyme"> 
   <div id="div0">This is div 0</div>  
   <div id="div1">This is div 1</div>  
   <div id="div2">This is div 2</div>  
   <div id="div3">This is div 3</div>  
   <div id="div4">This is div 4</div>  

  </div> 
    </div>
    <div class="nav">
  <button type="button" id="add">Add to Deck</button>
    </div> 
   </div>
</body> 
</html>  

The coverflow function (included as a js file in the head section) is here. When I click the button, I was expecting it to add a DIV to the already present deck. For some reason, it doesn't show the newly added DIV. I tried calling the coverflow() function after I added the new element but that didn't work either. The modified coverflow function is given here:

;(function($){

    $.widget("ui.coverflow", {
        init: function() {

            var self = this;

            this.items = $(this.options.items, this.element).bind("click", function() {
                self.moveTo(this);
                //$("div.slider").slider("moveTo", self.current, null, true);
            });
            this.itemWidth = this.items.outerWidth(true);

            this.current = 0; //Start item

            this.refresh(1, 0, this.current);
            this.element.css("left",
                (-this.current * this.itemWidth/2)
                + (this.element.parent()[0].offsetWidth/2 - this.itemWidth/2) //Center the items container
                - (parseInt(this.element.css("paddingLeft")) || 0) //Subtract the padding of the items container
            );

        },
        moveTo: function(item) {

            this.previous = this.current;
            this.current = !isNaN(parseInt(item)) ? parseInt(item) : this.items.index(item);
            if(this.previous == this.current) return false; //Don't animate when clicking on the same item

            var self = this, to = Math.abs(self.previous-self.current) <=1 ? self.previous : self.current+(self.previous < self.current ? -1 : 1);
            $.fx.step.coverflow = function(fx) {
                self.refresh(fx.now, to, self.current);
            };

            this.element.stop().animate({
                coverflow: 1,
                left: (
                    (-this.current * this.itemWidth/2)
                    + (this.element.parent()[0].offsetWidth/2 - this.itemWidth/2) //Center the items container
                    - (parseInt(this.element.css("paddingLeft")) || 0) //Subtract the padding of the items container
                )
            }, {
                duration: 1000,
                easing: "easeOutQuint"
            });

            /*current = this.current;
            $("[id^=div]").each(function() {
                if(this.id != "div"+current) {
                    console.info(this.id + " Current: " + current);
                    $(this).fadeTo( 'slow', 0.1);
                }
            });*/

        },
        refresh: function(state,from,to) {

            var self = this, offset = null;

            this.items.each(function(i) {

                var side = (i == to && from-to < 0 ) ||  i-to > 0 ? "left" : "right";
                var mod = i == to ? (1-state) : ( i == from ? state : 1 );              

                var before = (i > from && i != to);

                $(this).css({
                    webkitTransform: "matrix(1,"+(mod * (side == "right" ? -0.5 : 0.5))+",0,1,0,0) scale("+(1+((1-mod)*0.5))+")",
                    left: (
                        (-i * (self.itemWidth/2))
                        + (side == "right"? -self.itemWidth/2 : self.itemWidth/2) * mod //For the space in the middle
                    ),
                    zIndex: self.items.length + (side == "left" ? to-i : i-to)
                });

                if(!$.browser.msie)
                    $(this).css("opacity", 1 - Math.abs((side == "left" ? to-i : i-to))/2);
            });

        }
    });

    $.extend($.ui.coverflow, {
        defaults: {
            items: "> *"
        }
    });

})(jQuery); 

One thing I did notice is that after clicking the button for about 5-10 times, the elements show up but not along with the already present divs but rather below them. I am guessing that this has something to do with the CSS of the magnifyme class (2000px), but I am not sure what it is. Is there any way I can make this work?

+2  A: 

First, you need to add a references to the jQuery UI core, and it also appears that it requires the jQuery slider plugin.

Second, in your click event you're doing a location.reload, which is refreshing the page from the server, resetting any changes you had made to the page. (if you make the DIVs much smaller you can see one flash in before the page is reloaded).

great_llama
@great_llama: Sorry! That location.reload somehow came up. I was just playing around with it. I just updated my code with the actual version. +1 for correcting me.
Legend
You still need to add in the jQuery slider library, http://jqueryui.com/demos/slider/
great_llama
Thanks. I'm trying with that. In the mean time, I added the coverflow I am using (I modified the original one to remove some stuff that I didn't need).
Legend
@great_llama: Sorry. I'm still facing the same problem. The div gets added and I can see it overflow after clicking the button a number of times but it doesn't get added in a way that lets me animate it.
Legend
+1  A: 

You are getting a js error on the page -- "$.widget is not a function" because you didn't include the jqueryUI library. http://jqueryui.com/

Also if you remove the location.reload line, your code will work, however, I would rewrite that script block like this, so that everything clearly runs when the document is ready:

<script type="text/javascript">
    $(document).ready(function() {
        $("div.magnifyme").coverflow();
        $("#add").click(function() {
            $(".magnifyme").append("<div id=\"div5\">hello world</div>");
            $("div.magnifyme").coverflow();
        });
    });
</script> 
jessica
@user126272: Thanks for getting back but that $ error should not occur because I am including the jQuery library :) And like I mentioned in one of the comments, I just updated my code. That location.reload was accidentally placed. Sorry about that.
Legend
You need to include the *jqueryUI* library in addition to the core jquery library.See my link above. :)
jessica
Yes. I did... The line jquery-1.3.2.js does exactly this.
Legend
Oh, there was no way to tell that from your code..I'm not sure what the problem is, then, because your code does add extra divs when the button is clicked. You can't see them because the .wrapper div is set to 824px wide and overflow:hidden, so they are showing up outside the viewable area. Once the row of divs gets longer than the width of .magnifyme (2000px), they start showing up on the next line, which is why they show up underneath if you click it a bunch of times.
jessica
Yeap... I'm stuck at the same point. I tried calling the coverflow function again as well but it still doesn't show up for some reason.
Legend
Is your problem that you can't see the divs when they're added? Or is it that the coverflow script isn't working?
jessica
Oh.. the coverflow script works initially. What I want to do is when the button is clicked, a new div should be added to the already present list so that I can animate it along with other divs. +1 for your time. You can see the coverflow script in my post. I modified it to remove some stuff that I didn't need.
Legend
I see. I don't see it working on my copy. I am also not sure if you want it to work without the slider div?
jessica
Yeah. I managed to get it working without the slider. The coverflow version that I posted works without the slider.
Legend
I just re-copied your code exactly how it is above, but I changed:jquery 1.3.2 to reference http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js, ui.core.js to reference http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.3/jquery-ui.min.js, pasted your coverflow script over ui.coverflow.js, and i had to include the jqueryui script above the coverflow script to avoid js errors. The coverflow does not work at all for me, so I think something might be missing from your example.
jessica
ok actually i just included the code straight from the paulbakaus.com site directly and it works now. to achieve what you want to do, you're going to have to write another function for the coverflow widget. i'll repost an answer so i can post code.
jessica
+1  A: 

You need to write an additional function for the coverflow widget:

    add: function(el) {
        var self = this;
        this.element.append(el)
        this.options.items = $('> *', this.element);
        this.items = $(this.options.items, this.element).bind("click", function() {
            self.moveTo(this);
        });
        this.itemWidth = this.items.outerWidth(true);
        this.moveTo(this.items.length-1);
    },

and then call it like so:

$("#add").click(function() {
    $("div.magnifyme").coverflow('add', "<div></div>");
});
jessica
Awesome... Thanks a lot! Works perfect... Really appreciate your time.
Legend