2 Replies Latest reply on Jan 28, 2008 6:15 AM by Solerous

    autoscrolling with mouseover

    Solerous Level 1
      I am having some problems with making a custom scrolling component. I see this type of behavior all over the web and am surprised I can't find anything on getting it to work in Flex.

      The code below is inside a Canvas object and I am just moving the VBox y value up or down when I get a mouseover in the canvas. The problem is that I can't get the mouse y value to evaluate properly. What I want is to check the mouse Y value and if its at the top (y<10) have the VBox scroll up. Conversely if it is at the bottom (y>120) to scroll down. But the localY is captured from whatever the mouse happens to be over. So the code works fine until the mouse goes over one of the Buttons, then the Y gets captured from this component (and its quite easy to get y<10 on the button since it is only 26 pixels high). Is there anyway to disable the events on the buttons or to access the parent canvas from the button capture event. Here is a sample of some of the code I'm using. I didn't paste it all but I think this represents the nuts and bolts of what is going on.

      <mx:Canvas verticalScrollPolicy="off" mouseOut="stopMove()" creationComplete="init()">

      private var dp:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9];

      //make a timer for moving the view up and down
      public function init():void {
      var myTimer:Timer = new Timer(20);
      myTimer.addEventListener("timer", timerHandler);
      myTimer.start();
      this.addEventListener(MouseEvent.MOUSE_OVER, seekDirection);
      }

      private function seekDirection(event:MouseEvent):void {
      if (event.localY < 10) goUp = true;
      else goUp = false;
      if (event.localY > 120) goDown = true;
      else goDown = false;
      }

      <mx:VBox width="100%" paddingLeft="0" paddingRight="0" paddingBottom="5" paddingTop="5"
      x="1" id="view" horizontalAlign="center" verticalScrollPolicy="off">
      <mx:Repeater id="rp" dataProvider="{dp}" >
      <mx:Button height="26" width="26"
      label="{String(rp.currentItem)}" />
      </mx:Repeater>
      </mx:VBox>



        • 1. autoscrolling with mouseover
          VarioPegged Level 2
          There are a few different ways to do this... one is a simple approach (based on what I'm guessing your missing code looks like) with a button at the top and one at the bottom with alpha set to zero that'll trigger the scroll:

          <?xml version="1.0" encoding="utf-8"?>
          <mx:Canvas xmlns:mx=" http://www.adobe.com/2006/mxml" verticalScrollPolicy="off" creationComplete="init()">

          <mx:Script>
          <![CDATA[

          import flash.display.Sprite;
          import flash.events.MouseEvent;

          [Bindable]
          private var dp:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9];

          private var myTimer:Timer;
          private var scrollSpeed:Number = 5;
          private var scrollUpBttn:Button;
          private var scrollDownBttn:Button;
          private var hitAreaHeight:Number = 20

          public function init():void {
          scrollUpBttn = new Button();
          scrollUpBttn.width = this.width;
          scrollUpBttn.height = hitAreaHeight;
          scrollUpBttn.alpha = 0;

          scrollDownBttn = new Button();
          scrollDownBttn.width = this.width;
          scrollDownBttn.height = hitAreaHeight;
          scrollDownBttn.alpha = 0;
          scrollDownBttn.y = this.height - hitAreaHeight;

          scrollUpBttn.addEventListener(MouseEvent.MOUSE_OVER, seekDirection);
          scrollDownBttn.addEventListener(MouseEvent.MOUSE_OVER, seekDirection);
          scrollUpBttn.addEventListener(MouseEvent.MOUSE_OUT, stopMove);
          scrollDownBttn.addEventListener(MouseEvent.MOUSE_OUT, stopMove);

          addChild(scrollUpBttn);
          addChild(scrollDownBttn);
          }

          private function seekDirection(event:MouseEvent):void {
          myTimer = new Timer(20);
          myTimer.addEventListener("timer", timerHandler);
          myTimer.start();
          }

          private function stopMove(event:MouseEvent):void {
          myTimer.removeEventListener("timer", timerHandler);
          myTimer.stop();
          myTimer = null;
          }

          private function timerHandler(event:TimerEvent):void {
          if (mouseY < hitAreaHeight ) view.y = Math.min(view.y + scrollSpeed, 0);
          if ((mouseY > this.height - hitAreaHeight) ) view.y = Math.max(view.y - scrollSpeed, -(view.height - 36));
          }

          ]]>
          </mx:Script>


          <mx:VBox width="100%" paddingLeft="0" paddingRight="0" paddingBottom="5" paddingTop="5"
          x="1" id="view" horizontalAlign="center" verticalScrollPolicy="off">
          <mx:Repeater id="rp" dataProvider="{dp}" >
          <mx:Button height="26" width="52"
          label="{String(rp.currentItem)}" />
          </mx:Repeater>
          </mx:VBox>

          </mx:Canvas>

          Note that I hard-coded 36 in the timerHandler function, which you could further refine as variables instead:
          36 = 26 + 5 + 5 (Your dynamically created Button height + paddingTop + paddingBottom). The additional logic is so that the buttons don't scroll completely off the page (in both directions)

          TS
          • 2. autoscrolling with mouseover
            Solerous Level 1
            Thanks, that worked great!

            Very good idea about setting the alpha to 0, I never would have though of that.