Results 1 to 5 of 5

Thread: Horizontal menu that follows mouse along path.

  1. #1
    Join Date
    Nov 2009
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Horizontal menu that follows mouse along path.

    I'm new to the jQuery realm but have been messing with it quite a bit lately.

    What i'm looking to do is to replicate this menu without Flash: Horizontal Menu (not exactly but in general, where the menu stays on the side and follows the mouse up and down which has additional navigation in it once rolled over.)

    I've done extensive Googling and have yet to come across an example or tutorial on how to do something along those lines.

    Do any of you have a link to a tutorial and/or example of this being done with jQuery or alike? Any help would be greatly appreciated!

    Thank You.

  2. #2
    Join Date
    Dec 2008
    Location
    Portsmouth, UK
    Posts
    1,891
    Thanks
    2
    Thanked 441 Times in 435 Posts

    Default

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    
    <head>
      <title></title>
    <style type="text/css">
    /*<![CDATA[*/
    
    #nav {
     position: absolute;
     z-index: 100;
     left: 20px;
     top: 20px;
     width:40px;
     height:100px;
    }
    
    .tab {
     position: absolute;
     left: 0px;
     top: 0px;
     width:30px;
     height:100px;
     background-Color:red;
     border: 1px solid black;
    }
    
    .menu{
    position: absolute;
    left: 35px;
    top: -10px;
    visibility: visible;
    border: 1px solid black;
    border-bottom-width: 0;
    font: normal 12px Verdana;
    line-height: 18px;
    z-index: 100; /* zIndex should be greater than that of shadow's below */
    background: lightyellow;
    width: 200px; /* default width for menu */
    }
    
    .menu ul{
    margin: 0;
    padding: 0;
    list-style-type: none;
    }
    
    .menu ul li a{
    width: 100%;
    display: block;
    text-indent: 3px;
    border-bottom: 1px solid black;
    padding: 2px 0;
    text-decoration: none;
    font-weight: bold;
    text-indent: 5px;
    }
    
    .menu a:hover{ /*hover background color*/
    background: black;
    color: white;
    }
    
    
    
    #navh {
     position: absolute;
     z-index: 100;
     left: 220px;
     top: 20px;
     width:100px;
     height:40px;
    }
    
    .tabh {
     position: absolute;
     left: 0px;
     top: 0px;
     width:100px;
     height:30px;
     background-Color:red;
     border: 1px solid black;
    }
    
    .menuh{
    position: absolute;
    left: -55px;
    top: 35px;
    visibility: visible;
    border: 1px solid black;
    border-bottom-width: 0;
    font: normal 12px Verdana;
    line-height: 18px;
    z-index: 100; /* zIndex should be greater than that of shadow's below */
    background: lightyellow;
    width: 200px; /* default width for menu */
    }
    
    .menuh ul{
    margin: 0;
    padding: 0;
    list-style-type: none;
    }
    
    .menuh ul li a{
    width: 100%;
    display: block;
    text-indent: 3px;
    border-bottom: 1px solid black;
    padding: 2px 0;
    text-decoration: none;
    font-weight: bold;
    text-indent: 5px;
    }
    
    .menuh a:hover{ /*hover background color*/
    background: black;
    color: white;
    }
    
    
    
    /* ######### class for shadow DIV ######### */
    
    
    .shadow{ /*CSS for shadow. Keep this as is */
    position: absolute;
    left: 0;
    top: 0;
    z-index: 99; /*zIndex for shadow*/
    background: black;
    }
    /*]]>*/
    </style>
    <script type="text/javascript">
    // Animate (11-January-2010)
    // by Vic Phillips http://www.vicsjavascripts.org.uk
    
    // To progressively change the Left, Top, Width, Height or Opacity of an element over a specified period of time.
    // With the ability to scale the effect time on specified minimum/maximum values
    // and with three types of progression 'sin' and 'cos' and liner.
    
    // **** Application Notes
    
    // **** The HTML Code
    //
    // when moving an element the inline or class rule style position of the element should be assigned as
    // 'position:relative;' or 'position:absolute;'
    //
    // The element would normally be assigned a unique ID name.
    //
    
    // **** Initialising the Script.
    //
    // The script is initialised by assigning an instance of the script to a variable.
    // e.g A = new zxcAnimate('left','id1')
    // where:
    //  A           = a global variable                                                               (variable)
    //  parameter 0 = the mode(see Note 1).                                                           (string)
    //  parameter 1 = the unique ID name or element object.                                           (string or element object)
    //  parameter 1 = the initial value.                                                              (digits, default = 0)
    
    // **** Executing the Effect
    //
    // The effect is executed by an event call to function 'A.animate(10,800 ,5000,[10,800]);'
    // where:
    //  A           = the global referencing the script instance.                                 (variable)
    //  parameter 0 = the start value.                                                            (digits, for opacity minimum 0, maximum 100)
    //  parameter 1 = the finish value.                                                           (digits, for opacity minimum 0, maximum 100)
    //  parameter 2 =  period of time between the start and finish of the effect in milliseconds. (digits or defaults to previous or 0(on first call) milliSeconds)
    //  parameter 3 = (optional) to scale the effect time on a specified minimum/maximum.         (array, see Note 3)
    //                 field 0 the minimum value. (digits)
    //                 field 1 the maximum value. (digits)
    //  parameter 3 = (optional) the type of progression, 'sin', 'cos' or 'liner'.                (string, default = 'liner')
    //                 'sin' progression starts fast and ends slow.
    //                 'cos' progression starts slow and ends fast.
    //
    //  Note 1:  Examples modes: 'left', 'top', 'width', 'height', 'opacity.
    //  Note 2:  The default units(excepting opacity) are 'px'.
    //           For hyphenated modes, the first character after the hyphen must be upper case, all others lower case.
    //  Note 3:  The scale is of particular use when re-calling the effect
    //           in mid progression to retain an constant rate of progression.
    //  Note 4:  The current effect value is recorded in A.data[0].
    //  Note 5:  A function may be called on completion of the effect by assigning the function
    //           to the animator intance property .Complete.
    //           e.g. [instance].Complete=function(){ alert(this.data[0]); };
    //
    
    
    
    // **** Functional Code(1.58K) - NO NEED to Change
    
    function zxcAnimate(mde,obj,srt){
     this.to=null;
     this.obj=typeof(obj)=='object'?obj:document.getElementById(obj);
     this.mde=mde.replace(/\W/g,'');
     this.data=[srt||0];
     return this;
    }
    
    zxcAnimate.prototype.animate=function(srt,fin,ms,scale,c){
     clearTimeout(this.to);
     this.time=ms||this.time||0;
     this.neg=srt<0||fin<0;
     this.data=[srt,srt,fin];
     this.mS=this.time*(!scale?1:Math.abs((fin-srt)/(scale[1]-scale[0])));
     this.c=typeof(c)=='string'?c.charAt(0).toLowerCase():this.c?this.c:'';
     this.inc=Math.PI/(2*this.mS);
     this.srttime=new Date().getTime();
     this.cng();
    }
    
    zxcAnimate.prototype.cng=function(){
     var oop=this,ms=new Date().getTime()-this.srttime;
     this.data[0]=(this.c=='s')?(this.data[2]-this.data[1])*Math.sin(this.inc*ms)+this.data[1]:(this.c=='c')?this.data[2]-(this.data[2]-this.data[1])*Math.cos(this.inc*ms):(this.data[2]-this.data[1])/this.mS*ms+this.data[1];
     this.apply();
     if (ms<this.mS) this.to=setTimeout(function(){oop.cng()},10);
     else {
      this.data[0]=this.data[2];
      this.apply();
      if (this.Complete) this.Complete(this);
     }
    }
    
    zxcAnimate.prototype.apply=function(){
     if (isFinite(this.data[0])){
      if (this.data[0]<0&&!this.neg) this.data[0]=0;
      if (this.mde!='opacity') this.obj.style[this.mde]=Math.floor(this.data[0])+'px';
      else zxcOpacity(this.obj,this.data[0]);
     }
    }
    
    function zxcOpacity(obj,opc){
     if (opc<0||opc>100) return;
     obj.style.filter='alpha(opacity='+opc+')';
     obj.style.opacity=obj.style.MozOpacity=obj.style.WebkitOpacity=obj.style.KhtmlOpacity=opc/100-.001;
    }
    
    
    </script>
    
    </head>
    
    <body>
    <div id="nav" >
     <div class="menu" >
      <ul>
       <li><a href="#" >Text 1</a></li>
       <li><a href="#" >Text 2</a></li>
       <li><a href="#" >Text 3</a></li>
       <li><a href="#" >Text 4</a></li>
       <li><a href="#" >Text 5</a></li>
      </ul>
     </div>
     <div class="tab" ></div>
    </div>
    
    <div id="navh" >
     <div class="menuh" >
      <ul>
       <li><a href="#" >Text 1</a></li>
       <li><a href="#" >Text 2</a></li>
       <li><a href="#" >Text 3</a></li>
       <li><a href="#" >Text 4</a></li>
       <li><a href="#" >Text 5</a></li>
      </ul>
     </div>
     <div class="tabh" ></div>
    </div>
    
    <script type="text/javascript">
    /*<![CDATA[*/
    // Floating Menu (03-August-2010)
    // by Vic Phillips http://www.vicsjavascripts.org.uk
    
    function zxcFloatingMenu(o){
     this.mde=o.Mode.charAt(0).toUpperCase()=='V'?[1,'Height','top']:[0,'Width','left']
     var obj=document.getElementById(o.ID);
     this.os=obj['offset'+this.mde[1]]/2;
     this.nav=new zxcAnimate(this.mde[2],obj,0);
     this.menu=new zxcAnimate('opacity',obj.getElementsByTagName('DIV')[0],0);
     this.menu.Complete=function(){
      if (this.data[0]==0){
       this.obj.style.visibility='hidden';
      }
     }
     this.menu.obj.style.visibility='hidden';
     this.fms=o.FadeDuration||1000;
     this.sms=o.ScrollSpeed||1000;
     this.addevt(obj,'mouseover','fade');
     this.addevt(obj,'mouseout','fade');
     this.addevt(document,'mousemove','position');
    }
    
    zxcFloatingMenu.prototype={
    
     position:function(e){
      clearTimeout(this.nav.to);
      if (this.menu.obj.style.visibility=='hidden'){
       this.nav.animate(this.nav.data[0],this.mse(e)[this.mde[0]]-this.os,this.sms);
      }
     },
    
     fade:function(e){
      var eobj=(e.relatedTarget)?e.relatedTarget:(e.type=='mouseout')?e.toElement:e.fromElement;
      if (eobj){
       while (eobj.parentNode){
        if (eobj==this.nav.obj){
         return false;
        }
        eobj=eobj.parentNode;
       }
       this.menu.animate(this.menu.data[0],e.type=='mouseover'?100:0,this.fms,[0,100]);
       this.menu.obj.style.visibility='visible';
      }
     },
    
     addevt:function(o,t,f,p){
      var oop=this;
      if (o.addEventListener) o.addEventListener(t,function(e){ return oop[f](e,p);}, false);
      else if (o.attachEvent) o.attachEvent('on'+t,function(e){ return oop[f](e,p); });
     },
    
     mse:function(e){
      if (document.all) return [e.clientX+this.docs()[0],e.clientY+this.docs()[1]];
      return [e.pageX,e.pageY];
     },
    
     docs:function(){
      if (!document.body.scrollTop) return [document.documentElement.scrollLeft,document.documentElement.scrollTop];
      return [document.body.scrollLeft,document.body.scrollTop];
     }
    
    
    
    }
    
    new zxcFloatingMenu({
     Mode:'Vertical',
     ID:'nav',
     FadeDuration:1000,
     ScrollSpeed:1000
    });
    
    new zxcFloatingMenu({
     Mode:'Horizontal',
     ID:'navh',
     FadeDuration:1000,
     ScrollSpeed:1000
    });
    
    
    /*]]>*/
    </script>
    
    
    </body>
    
    </html>
    Vic
    God Loves You and will never love you less.
    http://www.vicsjavascripts.org/Home.htm
    If my post has been useful please donate to http://www.operationsmile.org.uk/

  3. #3
    Join Date
    Nov 2009
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Thank you for the reply and example! This will serve me well and is exactly what i'm looking for!

    I do have one question though that pertains to your code, how would you go about containing the menu to a specified height? As the code is now it will go off the page with the mouse.

    Thanks!

  4. #4
    Join Date
    Dec 2008
    Location
    Portsmouth, UK
    Posts
    1,891
    Thanks
    2
    Thanked 441 Times in 435 Posts

    Default

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    
    <head>
      <title></title>
    <style type="text/css">
    /*<![CDATA[*/
    
    #nav {
     position: absolute;
     z-index: 100;
     left: 20px;
     top: 50px;
     width:40px;
     height:100px;
    }
    
    .tab {
     position: absolute;
     left: 0px;
     top: 0px;
     width:30px;
     height:100px;
     background-Color:red;
     border: 1px solid black;
    }
    
    .menu{
    position: absolute;
    left: 35px;
    top: -10px;
    border: 1px solid black;
    border-bottom-width: 0;
    font: normal 12px Verdana;
    line-height: 18px;
    background-Color: lightyellow;
    width: 200px;
    }
    
    .menu ul{
    margin: 0;
    padding: 0;
    list-style-type: none;
    }
    
    .menu ul li a{
    width: 100%;
    display: block;
    text-indent: 3px;
    border-bottom: 1px solid black;
    padding: 2px 0;
    text-decoration: none;
    font-weight: bold;
    text-indent: 5px;
    }
    
    .menu a:hover{ /*hover background color*/
    background: black;
    color: white;
    }
    
    .hparent {
     position: relative;
     left: 220px;
     top: 20px;
     width:600px;
     height:40px;
     border: 1px solid black;
    }
    
    
    #navh {
     position: absolute;
     z-index: 100;
     left: 220px;
     top: 0px;
     width:100px;
     height:40px;
    }
    
    #navh .tab {
     position: absolute;
     left: 0px;
     top: 0px;
     width:100px;
     height:30px;
     background-Color:red;
     border: 1px solid black;
    }
    
    .menup{
    position: absolute;
    left: -50px;
    top: 33px;
    width: 220px;
    height: 125px;
    }
    
    #navh .menu{
    position: absolute;
    left: 0px;
    top: 0px;
    border: 1px solid black;
    border-bottom-width: 0;
    font: normal 12px Verdana;
    line-height: 18px;
    background-Color: lightyellow;
    width: 200px;
    }
    
    .shadow{
     position: absolute;
     left: 5px;
     top: 5px;
     background-Color:#BCBCBC;
     width: 200px;
     height: 115px;
     opacity:.5;
    }
    
    /*]]>*/
    </style>
    <script type="text/javascript">
    // Animate (11-January-2010)
    // by Vic Phillips http://www.vicsjavascripts.org.uk
    
    // To progressively change the Left, Top, Width, Height or Opacity of an element over a specified period of time.
    // With the ability to scale the effect time on specified minimum/maximum values
    // and with three types of progression 'sin' and 'cos' and liner.
    
    // **** Application Notes
    // removed to save space
    
    // **** Functional Code(1.58K) - NO NEED to Change
    
    function zxcAnimate(mde,obj,srt){
     this.to=null;
     this.obj=typeof(obj)=='object'?obj:document.getElementById(obj);
     this.mde=mde.replace(/\W/g,'');
     this.data=[srt||0];
     return this;
    }
    
    zxcAnimate.prototype={
    
     animate:function(srt,fin,ms,scale,c){
      clearTimeout(this.to);
      this.time=ms||this.time||0;
      this.neg=srt<0||fin<0;
      this.data=[srt,srt,fin];
      this.mS=this.time*(!scale?1:Math.abs((fin-srt)/(scale[1]-scale[0])));
      this.c=typeof(c)=='string'?c.charAt(0).toLowerCase():this.c?this.c:'';
      this.inc=Math.PI/(2*this.mS);
      this.srttime=new Date().getTime();
      this.cng();
     },
    
     cng:function(){
      var oop=this,ms=new Date().getTime()-this.srttime;
      this.data[0]=(this.c=='s')?(this.data[2]-this.data[1])*Math.sin(this.inc*ms)+this.data[1]:(this.c=='c')?this.data[2]-(this.data[2]-this.data[1])*Math.cos(this.inc*ms):(this.data[2]-this.data[1])/this.mS*ms+this.data[1];
      this.apply();
      if (ms<this.mS) this.to=setTimeout(function(){oop.cng()},10);
      else {
       this.data[0]=this.data[2];
       this.apply();
       if (this.Complete) this.Complete(this);
      }
     },
    
     apply:function(){
      if (isFinite(this.data[0])){
       if (this.data[0]<0&&!this.neg) this.data[0]=0;
       if (this.mde!='opacity') this.obj.style[this.mde]=Math.floor(this.data[0])+'px';
       else zxcOpacity(this.obj,this.data[0]);
      }
     }
    
    }
    
    
    function zxcOpacity(obj,opc){
     if (opc<0||opc>100) return;
     obj.style.filter='alpha(opacity='+opc+')';
     obj.style.opacity=obj.style.MozOpacity=obj.style.WebkitOpacity=obj.style.KhtmlOpacity=opc/100-.001;
    }
    
    
    </script>
    
    </head>
    
    <body>
    <div id="nav" >
     <div class="menu" >
      <ul>
       <li><a href="#" >Text 1</a></li>
       <li><a href="#" >Text 2</a></li>
       <li><a href="#" >Text 3</a></li>
       <li><a href="#" >Text 4</a></li>
       <li><a href="#" >Text 5</a></li>
      </ul>
     </div>
     <div class="tab" ></div>
    </div>
    <div class="hparent" >
    <div id="navh" >
     <div class="menup" >
     <div class="shadow" ></div>
      <div class="menu" >
       <ul>
        <li><a href="#" >Text 1</a></li>
        <li><a href="#" >Text 2</a></li>
        <li><a href="#" >Text 3</a></li>
        <li><a href="#" >Text 4</a></li>
        <li><a href="#" >Text 5</a></li>
       </ul>
      </div>
     </div>
     <div class="tab" ></div>
    </div>
    </div>
    <script type="text/javascript">
    /*<![CDATA[*/
    // Floating Menu (03-August-2010)
    // by Vic Phillips http://www.vicsjavascripts.org.uk
    
    function zxcFloatingMenu(o){
     this.mde=typeof(o.Mode)=='string'&&o.Mode.charAt(0).toUpperCase()=='V'?[1,'top','Top','Height']:[0,'left','Left','Width']
     var obj=document.getElementById(o.NavigationID);
     this.xy=obj['offset'+this.mde[2]];
     this.nav=new zxcAnimate(this.mde[1],obj,this.xy);
     this.mobj=obj.getElementsByTagName('DIV')[0];
     this.menu=new zxcAnimate('opacity',this.mobj,0);
     this.menu.oop=this;
     this.menu.Complete=function(){
      if (this.data[0]==0){
       this.obj.style.visibility='hidden';
       this.oop.move();
      }
     }
     this.nested=o.Nested||false
     this.parent=document.getElementById(this.nested)||obj.parentNode;
     this.mobj.style.visibility='hidden';
     this.os=obj['offset'+this.mde[3]]/2;
     this.fms=o.FadeDuration||1000;
     this.sms=o.ScrollSpeed||1000;
     this.min=o.MinTravel||0;
     this.max=o.MaxTravel||100000;
     this.addevt(obj,'mouseover','fade');
     this.addevt(obj,'mouseout','fade');
     this.addevt(document,'mousemove','msemove');
    }
    
    zxcFloatingMenu.prototype={
    
     msemove:function(e){
      clearTimeout(this.nav.to);
      var os=this.nested?this.pos(this.parent)[this.mde[0]]:0;
      this.xy=Math.max(Math.min(this.mse(e)[this.mde[0]]-this.os-os,this.max),this.min);
      if (this.mobj.style.visibility=='hidden'){
       this.move();
      }
     },
    
     move:function(e){
       this.nav.animate(this.nav.data[0],this.xy,this.sms);
     },
    
     fade:function(e){
      var eobj=(e.relatedTarget)?e.relatedTarget:(e.type=='mouseout')?e.toElement:e.fromElement;
      if (eobj){
       while (eobj.parentNode){
        if (eobj==this.nav.obj){
         return false;
        }
        eobj=eobj.parentNode;
       }
       this.menu.animate(this.menu.data[0],e.type=='mouseover'?100:0,this.fms,[0,100]);
       this.mobj.style.visibility='visible';
      }
     },
    
     addevt:function(o,t,f,p){
      var oop=this;
      if (o.addEventListener) o.addEventListener(t,function(e){ return oop[f](e,p);}, false);
      else if (o.attachEvent) o.attachEvent('on'+t,function(e){ return oop[f](e,p); });
     },
    
     mse:function(e){
      if (document.all) return [e.clientX+this.docs()[0],e.clientY+this.docs()[1]];
      return [e.pageX,e.pageY];
     },
    
     docs:function(){
      if (!document.body.scrollTop) return [document.documentElement.scrollLeft,document.documentElement.scrollTop];
      return [document.body.scrollLeft,document.body.scrollTop];
     },
    
     pos:function(obj){
      var rtn=[0,0];
      while(obj){
       rtn[0]+=obj.offsetLeft;
       rtn[1]+=obj.offsetTop;
       obj=obj.offsetParent;
      }
      return rtn;
     }
    
    
    
    }
    
    
    
    new zxcFloatingMenu({
     NavigationID:'navh', // the unique id name of the floating menu DIV element.                       (string)
     Nested:true,         // (optional) nested in an element with position of 'relative' or 'absolute'. (boolean, default = not nested)
     Mode:'Horizontal',   // (optional) 'Horizontal' = scroll X or 'Vertical' = scroll Y.               (digits, default = 'Horizontal')
     FadeDuration:1000,   // (optional) the fade duration in milliseconds.                              (digits, default = 1000)
     ScrollSpeed:1000,    // (optional) the scroll duration in milliseconds.                            (digits, default = 1000)
     MinTravel:0,         // (optional) the minimum scroll position.                                    (digits, default = 0)
     MaxTravel:500        // (optional) the minimum scroll position.                                    (digits, default = 100000)
    });
    
    new zxcFloatingMenu({
     NavigationID:'nav',
     Mode:'Vertical',
     MinTravel:50,        // (optional) the minimum scroll position.                                    (digits, default = 0)
     MaxTravel:400        // (optional) the minimum scroll position.                                    (digits, default = 100000)
    });
    
    
    /*]]>*/
    </script>
    
    
    </body>
    
    </html>
    Vic
    God Loves You and will never love you less.
    http://www.vicsjavascripts.org/Home.htm
    If my post has been useful please donate to http://www.operationsmile.org.uk/

  5. #5
    Join Date
    Nov 2009
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Thank you for your help, it is greatly appreciated and your script works wonderfully!

    I have another question though:
    Instead of having to manually specify the Minimum and Maximum travel distances, is there a way to attach it to a DIV and have it start and stop based on the height of that DIV? Reason being is that not all pages will be the same size.

    Thanks!
    Last edited by jet71dl; 08-12-2010 at 05:27 PM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •