5 Replies Latest reply on Nov 2, 2012 3:17 AM by raegtime

    Make an hgroup within a scroller "snap"

    A Sad Sam

      I'm developing an app for mobile devices using Flash Builder 4.5 and am having trouble figuring out how to accomplish one aspect of my  app.


      I have an HGroup inside of a Scroller.  The HGroup has images whose width is the same as the screen's width. Now what I want, is to make the users able to scroll through these images, but if they would stop scrolling in a point where they could see half of one image and half of another image in the viewport, it would snap to the nearest image. A behaviour wich you can see in action in many mobile apps.


      I know that this must be accomplished by listening for the swipe event in the scroller, and then setting that scroller viewport's horizontalScrollPosition to the nearest acceptable position. If a user of an HTC EVO (480 width) would stop scrolling in the position 260, the scroller would than move to position 480. Now, what I don't know is actually how am I going to make this snapping work.


      So, can anyone give me some advice as to how can I accomplish this feature?

        • 1. Re: Make an hgroup within a scroller "snap"
          A Sad Sam Level 1

          Well, looks like I figured it out myself. To all of you who might come across this problem, here's the code:


          scroller.addEventListener(TransformGestureEvent.GESTURE_SWIPE, snapViewPort);


          protected function snapViewPort(event:TransformGestureEvent):void {
               var pos:Number = scroller.viewport.horizontalScrollPosition;
                var remainder:Number = pos % this.width;

               if(remainder > 0) {
                    if(remainder <= this.width/2) {
                         scroller.viewport.horizontalScrollPosition = pos - remainder;
                    } else{
                         scroller.viewport.horizontalScrollPosition = pos - remainder + this.width;

          • 2. Re: Make an hgroup within a scroller "snap"

            http://mootricks.blogspot.com/2011/09/flex-snapscroller.html (German Blog)




                      import flash.events.MouseEvent;

                      import flash.events.TimerEvent;

                      import flash.utils.Timer;


                      import mx.core.ScrollPolicy;


                      import spark.components.Group;

                      import spark.components.Scroller;


                      public class SnapScroller extends Scroller


                                private var xStart:Number;

                                private var mouseUpDownXDistance : Number;

                                private var t:Timer;

                                private var nextHorizontalPosition: Number;

                                private var nextHorizontalPositionDistance : Number;

                                private var _twidth:Number;

                                private var _theight:Number;

                                private var lastDate:Date;


                                [Inspectable(category="General", type="Number", defaultValue="200")]

                                public function set theight(val:Number):void


                                          this.height = val;

                                          this._theight = val;



                                public function get theight():Number


                                          return theight;



                                public function SnapScroller()




                                          this.minHeight = 500;






                                protected function onMouseDown(event:MouseEvent):void



                                          if (t)



                                          xStart = mouseX;




                                protected function onMouseMove(event:MouseEvent):void


                                                    mouseUpDownXDistance = mouseX-xStart;

                                                    this.viewport.horizontalScrollPosition -= mouseUpDownXDistance;

                                                    xStart = mouseX;



                                protected function onMouseUp(event:MouseEvent):void




                                          if(mouseUpDownXDistance > 0)

                                                    nextHorizontalPosition = (int(this.viewport.horizontalScrollPosition/this.width))*this.width;


                                                    nextHorizontalPosition = (int(this.viewport.horizontalScrollPosition/this.width)+1)*this.width;


                                          if (nextHorizontalPosition > ((this.getElementAt(0) as Group).contentWidth)-this.width)

                                                    nextHorizontalPosition = ((this.getElementAt(0) as Group).contentWidth)-this.width;


                                          t = new Timer(1,0);


                                          lastDate = new Date();





                                protected function timerEnds(event:TimerEvent):void


                                          var timeDifferenzSinceLastTimerEnds:Date;



                                                    timeDifferenzSinceLastTimerEnds = new Date(new Date().time-lastDate.time);


                                          this.lastDate = new Date();


                                          var updateTime:Number;


                                                    updateTime = timeDifferenzSinceLastTimerEnds.milliseconds*.05;



                                          var distanceToTarget:Number = Math.abs(this.viewport.horizontalScrollPosition - nextHorizontalPosition);


                                          if(this.viewport.horizontalScrollPosition > nextHorizontalPosition)

                                                    this.viewport.horizontalScrollPosition -= updateTime*Math.sqrt(distanceToTarget);



                                                    this.viewport.horizontalScrollPosition += updateTime*Math.sqrt(distanceToTarget);


                                          if (distanceToTarget < 10.0)


                                                    this.viewport.horizontalScrollPosition = nextHorizontalPosition;








            • 3. Re: Make an hgroup within a scroller "snap"
              A Sad Sam Level 1

              That approach sounds good too, but it's got too many lines of code xD. I appreciate your help, some of that code might be of use one day, but for now I prefer sticking to my own version as it's simpler.

              • 4. Re: Make an hgroup within a scroller "snap"

                Thank you raegtime for posting code here. This helped me in building an iOS PageControl like component for Flex.