locked
Side Scrolling Chapter Menu RRS feed

  • Question

  • I'm trying to create a side scrolling chapter menu and was wondering if anyone has solved this riddle script side.

    Basically I want to scroll through chapter images using left and right arrow buttons, so the menu would start like this:

    < #1 #2 #3 >

    Then by clicking on the right arrow button it would then look like this:

    < #4 #5 #6 >

    And so on. The version I have built simply replaces the images (#1 replaced with #4, #2 replaced with #5 and so on). But I would love to make them scroll so the new images come in as if they are all on the track moving left and right.  I did try to solve the problem be creating on long block of all the chapter images, masked behind a div that was only big enough to show three at a time, and then used animated to move the chapter block side to side to change what the mask allowed you to see.  However that didn't work as images tended to bounce off the ends of the mask.

    Any ideas on how to do this or other help would be greatly appreciated.
    Monday, August 28, 2006 4:11 PM

Answers

All replies

  • You can also potentially overrun the pixel buffer if you do that and don't intelligently set unwanted chapter marks to display=none.

    There are a couple of approaches:

    1. The approach you have used. Not sure what you mean by "bounce off the ends"; the child buttons should be clipped by the containing div. This will require managing the pixel buffer though.
    2. A hybrid approach where you have (eg) 2 x the number of on-screen buttons, and you scroll them back and forth (so it looks pretty) but as soon as a button scrolls off-screen you swap it out for the next button. Then you do some creative juggling to put all the buttons back in the right place again (and there are at least two approaches to doing that, too :-) ).

    I have a sample that does #2 which I will be posting any day now; just waiting on the next release of iHDSim. 

    Tuesday, August 29, 2006 3:34 PM
  • Maybe the pixel buffer is my problem.  I looked at the markup for Million Dollar Baby and they divide their buttons into several blocks, with all the ones not being displayed set to none.

    What I don't get is how you animate the currently viewed buttons to slide off while the next set slide on right on their trail since they are two distinct divs. 

    Is the sequence:
    1) set display of off screen chapter buttons to auto
    2) animate on screen buttons
    3) animate off screen buttons
    4) set display of newly offscreen buttons to none


    What are the restrictions of the pixel buffer?
    Tuesday, August 29, 2006 4:22 PM
  • That sequence is good.

    The pixel buffer basically has 2 x HD pixels in it, ie 2 x 1920 x 1080 or around 4 million pixels. Any font glyphs you have rendered, any drawings, and any images that are not set to display=none are counted in the pixel buffer. Background images that are not currently the active background frame do not count.

     

     

    Thursday, August 31, 2006 11:28 PM
  • So maybe my problem is the containing div.  Images scrolling off to one side will scroll off, but then reapear at the last slot before the edge and stack there - so in my set up the 3 scenes that slide off to make room for 3 more come back and stack in the first or last position (depending on which way they scroll).

    I'll re-work the parent container and see if that is the problem.
    Friday, September 1, 2006 1:25 AM
  • Very nice - all done in markup too.


    Saturday, September 2, 2006 2:17 AM
  • What's interesting is that I just watched the HD-DVD version of Four Brothers. The scrolling chapter menu on that DVD suffers from the same bug I saw in one of my early attempts at making a side scroller: the images will appear outside the mask.

    I cannot get Peter's to work flawlessly either - it won't scroll back to the left at some point.

    Hopefully between the lot on this board we can come up with one that works well. I am dying to know how the one for Serenity and say Million Dollar Baby were done.  I'm trying to smooth out Peter's version and will post when done.
    Thursday, September 14, 2006 2:39 AM
  • That blog was definitely slapped together in a hurry and has some issues (for example, without some explicity navLeft / navRight animation, it is unusable without a mouse) and it isn't completely fool-proof.

    I hope to update it soon with a more stable / usable version.

    Thursday, September 14, 2006 3:27 PM
  • Awesome!...I was going to throw in the chapter pics today in a vertical scrolling arrangement...but I will hold off if Will has some tighter code...

    Thanks you guys...We should have a sit down sometime...Im sure we are all in Tinsel town.
    Thursday, September 14, 2006 4:42 PM
  • Nope the MSFT folks are in Redmond and I am in Seattle.

    Peter - I didn't mean to sound unappreciative of the example posted on the blog.  It was very helpful.


    Thursday, September 14, 2006 5:04 PM
  • Here is an implementation of a side scrolling menu that uses script.  What I have not completed yet is a way (in the script) to set the display of the non-viewable chapters to none.  See my other post about timing animations.

    ### MARKUP ###
      <head>
        <styling>
          <style id="MENU_TRAY" style:backgroundImage="url('MENU/BTN_TRAY.png')"
                 style:position="absolute" style:x="190px" style:y="720px"
                 style:width="900px" style:height="200px" style:display="auto" />   
                                       
          <style id="BUTTON_LF_ARROW" style:position="absolute"
                 style:width="110px" style:height="110px"
                 style:x="55px" style:y="45px"
                 style:backgroundImage="url('MENU/LF_ARW_NORM.png')
                                        url('MENU/LF_ARW_FOCUS.png')
                                        url('MENU/LF_ARW_ACTION.png')" />
                
          <style id="BUTTON_RT_ARROW" style:position="absolute"
                 style:width="110px" style:height="110px"
                 style:x="740px" style:y="45px"
                 style:backgroundImage="url('MENU/RT_ARW_NORM.png')
                                        url('MENU/RT_ARW_FOCUS.png')
                                        url('MENU/RT_ARW_ACTION.png')" />
                
          <style id="SCENE_MASK" style:position="absolute"
                 style:x="165px" style:y="45px"
                 style:width="575px" style:height="110px" style:display="auto" />   
                             
          <style id="SCENE_GROUP1" style:position="absolute"
                 style:x="0px" style:y="0px"
                 style:width="575px" style:height="110px" style:display="auto" />
                                          
          <style id="BUTTON_SCENE_POSITION1" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="15px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE1_NORM.png')
                                        url('MENU/SCENE1_FOCUS.png')" />
                                       
          <style id="BUTTON_SCENE_POSITION2" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="215px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE2_NORM.png')
                                        url('MENU/SCENE2_FOCUS.png')" />   
                                       
          <style id="BUTTON_SCENE_POSITION3" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="415px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE3_NORM.png')
                                        url('MENU/SCENE3_FOCUS.png')" /> 
                                       
          <style id="SCENE_GROUP2" style:position="absolute"
                 style:x="575px" style:y="0px"
                 style:width="575px" style:height="110px" style:display="none" />
                                          
          <style id="BUTTON_SCENE_POSITION4" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="15px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE4_NORM.png')
                                        url('MENU/SCENE4FOCUS.png')" />
                                       
          <style id="BUTTON_SCENE_POSITION5" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="215px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE5_NORM.png')
                                        url('MENU/SCENE5_FOCUS.png')" />   
                                       
          <style id="BUTTON_SCENE_POSITION6" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="415px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE6_NORM.png')
                                        url('MENU/SCENE6_FOCUS.png')" />                                                                                                    

          <style id="SCENE_GROUP3" style:position="absolute"
                 style:x="575px" style:y="0px"
                 style:width="575px" style:height="110px" style:display="none" />
                                          
          <style id="BUTTON_SCENE_POSITION7" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="15px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE7_NORM.png')
                                        url('MENU/SCENE7_FOCUS.png')" />
                                       
          <style id="BUTTON_SCENE_POSITION8" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="215px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE8_NORM.png')
                                        url('MENU/SCENE8_FOCUS.png')" />   
                                       
          <style id="BUTTON_SCENE_POSITION9" style:position="absolute"
                 style:width="150px" style:height="100px"
                 style:x="415px" style:y="5px"
                 style:backgroundImage="url('MENU/SCENE9_NORM.png')
                                        url('MENU/SCENE9_FOCUS.png')" /> 

        </styling>

        <timing clock="page">
          <defs>
            <!-- button state management -->
            <g id="ButtonFocus">
              <set style:backgroundFrame="1" />
            </g>
            <g id="ButtonActioned">
              <set style:backgroundFrame="2" />
              <event name="VideoMenuButtonPressed" />
            </g>     
         
           
            <!-- effects for side scrolling -->
            <g id="SlideSceneButton">
              <event name="SlideSceneButtonPressed" />
            </g>
                           
          </defs>
       
          <par>
            <par>
              <cue use="ButtonFocus"
                   begin="id('BTN_TRY_LF_ARW')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_TRY_RT_ARW')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_01')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_02')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_03')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_04')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_05')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_06')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />                                                                                                                                       
               
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_07')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_08')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />  
                
              <cue use="ButtonFocus"
                   begin="id('BTN_POS_09')[state:focused()]"
                   end="defaultNode()[state:focused()=false()]" />    
               
              <cue use="ButtonActioned"
                   begin="id('BTN_POS_01')[state:actioned()]" dur="1s" /> 
                
              <cue use="ButtonActioned"
                   begin="id('BTN_POS_02')[state:actioned()]" dur="1s" />     

              <cue use="ButtonActioned"
                   begin="id('BTN_POS_03')[state:actioned()]" dur="1s" /> 
                
              <cue use="ButtonActioned"
                   begin="id('BTN_POS_04')[state:actioned()]" dur="1s" />  
                
              <cue use="ButtonActioned"
                   begin="id('BTN_POS_05')[state:actioned()]" dur="1s" /> 
                
              <cue use="ButtonActioned"
                   begin="id('BTN_POS_06')[state:actioned()]" dur="1s" />     

              <cue use="ButtonActioned"
                   begin="id('BTN_POS_07')[state:actioned()]" dur="1s" /> 
                
              <cue use="ButtonActioned"
                   begin="id('BTN_POS_08')[state:actioned()]" dur="1s" /> 
                
              <cue use="ButtonActioned"
                   begin="id('BTN_POS_09')[state:actioned()]" dur="1s" />
                
              <cue use="SliderButtonAction"
                   begin="id('BTN_TRY_RT_ARW')[state:actioned()]" dur="1s" />  
                
              <cue use="SliderButtonAction"
                   begin="id('BTN_TRY_LF_ARW')[state:actioned()]" dur="1s" />
                  

           
            <par begin="id('BTN_TRY_RT_ARW')[state:actioned()]">
              <cue select="id('BTN_TRY_RT_ARW')" use="SlideSceneButton" dur="1s" />  
            </par>
           
            <par begin="id('BTN_TRY_LF_ARW')[state:actioned()]">
              <cue select="id('BTN_TRY_LF_ARW')" use="SlideSceneButton" dur="1s" />  
            </par>       

          </par>
        </timing>
      </head>
      <body>
     
        <!-- Menu Tray -->
        <div id="MENU" style="MENU_TRAY" >
       
          <!-- Left Arrow Button -->
          <div>
            <button id="BTN_TRY_LF_ARW" style="BUTTON_LF_ARROW" />
          </div>
         
          <!-- Scene Viewport -->
          <div id="MASK" style="SCENE_MASK">
         
            <!-- First Scene Group -->
            <div id="SCN_GRP_1" style="SCENE_GROUP1" >
              <button id="BTN_POS_01" style="BUTTON_SCENE_POSITION1" />
              <button id="BTN_POS_02" style="BUTTON_SCENE_POSITION2" />
              <button id="BTN_POS_03" style="BUTTON_SCENE_POSITION3" />
            </div>
           
            <!-- Second Scene Group -->
            <div id="SCN_GRP_2" style="SCENE_GROUP2" >
              <!-- <button style="BUTTON_TEST" /> -->
              <button id="BTN_POS_04" style="BUTTON_SCENE_POSITION4" />
              <button id="BTN_POS_05" style="BUTTON_SCENE_POSITION5" />
              <button id="BTN_POS_06" style="BUTTON_SCENE_POSITION6" />
            </div>
           
            <!-- Third Scene Group -->
            <div id="SCN_GRP_3" style="SCENE_GROUP3" >
              <!-- <button style="BUTTON_TEST" /> -->
              <button id="BTN_POS_07" style="BUTTON_SCENE_POSITION7" />
              <button id="BTN_POS_08" style="BUTTON_SCENE_POSITION8" />
              <button id="BTN_POS_09" style="BUTTON_SCENE_POSITION9" />
            </div>
           
          </div>  
          
          <!-- Right Arrow Button -->
          <div>
            <button id="BTN_TRY_RT_ARW" style="BUTTON_RT_ARROW" />
          </div> 
         
        </div>
      
      </body>

    ### SCRIPT ###

    function OnSlideSceneButtonPressed(evt) {
        var id = evt.target.getAttribute("id");
        var currentPosition = sceneSliderPosition;
        if (id == "BTN_TRY_RT_ARW") {
            if (currentPosition == 1 ) {
                document.BTN_TRY_LF_ARW.style.navRight = "BTN_POS_04";
                document.BTN_TRY_RT_ARW.style.navLeft = "BTN_POS_06";
                document.SCN_GRP_1.style.animateProperty("x","0px;-575px",2);
                document.SCN_GRP_2.style.display = "auto";
                document.SCN_GRP_2.style.animateProperty("x","575px;0px",2);
                sceneSliderPosition = 2;
           
            } else if (currentPosition  == 2) {
                document.BTN_TRY_LF_ARW.style.navRight = "BTN_POS_07";
                document.SCN_GRP_2.style.animateProperty("x","0px;-575px",2);
                document.SCN_GRP_3.style.display = "auto";
                document.SCN_GRP_3.style.animateProperty("x","575px;0px",2);
                sceneSliderPosition = 3;
              
            }
         
        } else if (id == "BTN_TRY_LF_ARW") {
            if (currentPosition == 2 ) {
                document.BTN_TRY_RT_ARW.style.navLeft = "BTN_POS_03";
                document.SCN_GRP_1.style.animateProperty("x","-575px;0px",2);
                document.SCN_GRP_2.style.display = "auto";
                document.SCN_GRP_2.style.animateProperty("x","0px;575px",2);
                sceneSliderPosition = 1;
           
            } else if (currentPosition == 3) {
                document.BTN_TRY_LF_ARW.style.navRight = "BTN_POS_07";
                document.BTN_TRY_RT_ARW.style.navLeft = "BTN_POS_03";
                document.SCN_GRP_2.style.animateProperty("x","-575px;0px",2);
                document.SCN_GRP_3.style.display = "auto";
                document.SCN_GRP_3.style.animateProperty("x","0px;575px",2);
                sceneSliderPosition = 2;
           
            }   
        }
        //timer = createTimer("00:00:01:00", TIMER_APPLICATION, SetSliderDisplay(id, currentPosition));
        //timer.enabled = true;
        //timer.autoReset = false;
    }

    // This part is not working at this time due to an error above when I create the timer
    function SetSliderDisplay(id, currentPosition) {
        if (id == "BTN_TRY_RT_ARW") {
            if (currentPosition == 1 ) {
                document.SCN_GRP_1.style.display = "none";
                document.BTN_TRY_LF_ARW.style.display = "auto";
                document.BTN_TRY_RT_ARW.style.display = "auto";
           
            } else if (currentPosition  == 2) {
                document.SCN_GRP_2.style.display = "none";
                document.BTN_TRY_LF_ARW.style.display = "auto";
                document.BTN_TRY_RT_ARW.style.display = "none";
              
            }
         
        } else if (id == "BTN_TRY_LF_ARW") {
            if (currentPosition == 2 ) {
                document.SCN_GRP_2.style.display = "none";
                document.BTN_TRY_LF_ARW.style.display = "none";
                document.BTN_TRY_RT_ARW.style.display = "auto";
           
            } else if (currentPosition == 3) {
                document.SCN_GRP_3.style.display = "none";
                document.BTN_TRY_LF_ARW.style.display = "auto";
                document.BTN_TRY_RT_ARW.style.display = "auto";
           
            }   
        }
    }

    var timer = null;
    var sceneSliderPosition = 1;

    addEventListener("VideoMenuButtonPressed",OnVideoMenuButtonPressed,false);
    addEventListener("SlideSceneButtonPressed",OnSlideSceneButtonPressed,false);
    Friday, September 15, 2006 6:12 PM
  • Thanks so much Will,  I am going to add this to my popup and main menu!
    Monday, September 18, 2006 6:14 PM
  • Hey Will if you ever get it working correct please post the .js for it...I am having trouble with the scripting on this.
    Wednesday, September 20, 2006 11:53 PM
  • I'll post the corrections soon.  I got it fixed.
    Friday, September 22, 2006 12:32 AM
  • sweeeeeet!

    Best news all day!!!!

    Thanx Will!  Im out for the rest of the day...but tommorow is another day!
    Friday, September 22, 2006 12:44 AM
  • Hit me with the finished .xmu and .js whenever you are ready I cant wait to drop it in!
    Friday, September 22, 2006 3:34 PM