加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

IPhoneScroll Effect with Flash ActionScript3.0

发布时间:2020-12-15 06:47:55 所属栏目:百科 来源:网络整理
导读:Overview ? What the effect looks like? When you press mouse left button at the content,and hold it,while moving your mouse,then the content will follow your mouse position. If you drag the content off its position range,it will bounce to w


Overview?


What the effect looks like?


prog-snapshot



When you press mouse left button at the content,and hold it,while moving your mouse,then the content will follow your mouse position. If you drag the content off its position range,it will bounce to where it should be. During the two processes,the movement is not linear,which means that the velocity is not constant,and in addition,the bouncing animation is designed with elasticity.


The Outline and the Spec


This diagram demostrates the layout and outline of the application.


stage-outline



As shown,the scroll Element is the content to be scrolled,and its height - EH is 1815.95. The canvas height - cH is 400,it is the window user will see,when you see the content on its top,scrollElement's y position is 0; when you see it on its bottom,its y position is:

cH - EH = 400 - 1815.95 = -1415.95

which is negtive,means the the most top part of scrollElement is above the window,where you will not see. So,the valid position of scrollElement on y-axis is?[0,-1415.95].


y should be: 0 <= y <= cH-EH


The Key Parameters and Events


The overall skeleton of the key class:?


package com.shinedraw.controls {
	...
	public class IPhoneScroll extends MovieClip {

		// Constant variables
        private static var DECAY:Number = 0.93;
        private static var MOUSE_DOWN_DECAY:Number = 0.5;
        private static var SPEED_SPRINGNESS:Number = 0.4;
        private static var BOUNCING_SPRINGESS:Number = 0.08;
		
		// variables
        private var _mouseDown:Boolean = false;
        private var _velocity:Number = 0;
        private var _mouseDownY:Number = 0;
        private var _mouseDownPoint:Point = new Point();
        private var _lastMouseDownPoint:Point = new Point();
        		
        // elements
        private var _canvasHeight:Number = 0;
		private var _myCanvas:MovieClip;
		private var _myScrollElement:MovieClip;
		
		public function IPhoneScroll() 
		{
			...
			
			// add handlers
			_myCanvas.addEventListener(MouseEvent.MOUSE_DOWN,on_mouse_down);
			addEventListener(Event.ENTER_FRAME,on_enter_frame);
		}
		
		private function on_enter_frame(e:Event):void
		{
            ...
		}
		
        private function on_mouse_down(e:MouseEvent):void
        {
            if (!_mouseDown)
            {
                ...

				// add some more mouse handlers
                stage.addEventListener(MouseEvent.MOUSE_UP,on_mouse_up);
                stage.addEventListener(MouseEvent.MOUSE_MOVE,on_mouse_move);
            }
        }

        private function  on_mouse_move(e:MouseEvent):void
        {
			...
        }

        // clear everythign when mouse up
        private function on_mouse_up(e:MouseEvent):void
        {
            if (_mouseDown)
            {
                _mouseDown = false;
                stage.removeEventListener(MouseEvent.MOUSE_UP,on_mouse_up);
                stage.removeEventListener(MouseEvent.MOUSE_MOVE,on_mouse_move);
            }
        }
	}
}


According to the code,there are four events in all. One is?ENTER_FRAME,and?MOUSE_DOWN,they will be regisitered at beginning. The other two are?MOUSE_MOVE and?MOUSE_UP,these two will be regisitered in?MOUSE_DOWN handler,which means user click mouse left button. When?MOUSE_UP dispatched,these two events' listener will be removed.


There are two main parameters that impact scrollElement's movement,velocity and?bouncing. And these two variables will be impacted by mouse y position while it is moving. To explore that logic,let's add some comments to the functions to trace the variables and reset the frame rate to 3 for simplicity.


link to the as file


The output should be like:


_canvasHeight: 400
---------decay the velocity--------
mouse up now
velocity after by 0.93: 0
----not mouse down,apply the velocity----
textHeight: 1815.95
y: 0
check if y is out of its range,to apply bouncing:
finally,bouncing is: 0
_myScrollElement.y after update: 0
******************************
dispatching mouse down event!
_mouseDownPoint: (x=367,y=319)
_lastMouseDownPoint: (x=367,y=319)
_mouseDownY: 0
********************************
******************************
dispatching mouse move event!
mouse is moving and mouse is down
the new point: (x=367,y=318)
_myScrollElement.y after update: -1
_velocity after update: -0.4
_lastMouseDownPoint after update: (x=367,y=318)
************************************
******************************
dispatching mouse move event!
mouse is moving and mouse is down
the new point: (x=367,y=317)
_myScrollElement.y after update: -2
_velocity after update: -0.8
_lastMouseDownPoint after update: (x=367,y=317)
************************************
******************************
dispatching mouse move event!
mouse is moving and mouse is down
the new point: (x=367,y=315)
_myScrollElement.y after update: -4
_velocity after update: -1.6
_lastMouseDownPoint after update: (x=367,y=315)
************************************

According to this output,the first thing is that,each event handling function will run atomically,I mean when a handler run,it?will not be interruppted. And the second thing is,by statisticing the events frequancy,we can figure out?the peroid of how long time will MOUSE_MOVE be dispatched.?


event-frequancy



As shown,ratio is nearly 1:35,means that during the peroid ENTER_FRAME dispatched for just one time,MOUSE_MOVE wll be diapatched for around?35 times. And since the frame rate is?3,then?ENTER_FRAME is dispatched?3 times per second,means that?MOUSE_MOVE be dispatched for around?105 times per second.


How to make the velocity non-linear


		private function on_enter_frame(e:Event):void
		{
            // decay the velocity
            if(_mouseDown)
			{
				_velocity *= MOUSE_DOWN_DECAY;
			}
            else
			{
				_velocity *= DECAY;
			}

            // if not mouse down,then move the element with the velocity
            if (!_mouseDown)
            {
                var textHeight:Number = _myScrollElement.height;

                var y:Number = _myScrollElement.y;
				
                var bouncing:Number = 0;

                // calculate a bouncing when the text moves over the canvas size
                if (y > 0)
                {
                    bouncing = -y * BOUNCING_SPRINGESS;
                }
				else if( y + textHeight < _canvasHeight)
				{
                    bouncing = (_canvasHeight - textHeight - y) * BOUNCING_SPRINGESS;
                }

                _myScrollElement.y = y + _velocity + bouncing;
            }
		}
		
        private function  on_mouse_move(e:MouseEvent):void
        {
            if (_mouseDown)
            {
                // update the element position
                var point:Point = new Point(e.stageX,e.stageY);
				
                _myScrollElement.y = _mouseDownY + (point.y - _mouseDownPoint.y);
				
                // update the velocity
                _velocity += ((point.y - _lastMouseDownPoint.y) * SPEED_SPRINGNESS);		
				
                _lastMouseDownPoint = point;
            }
        }


If the velocity is not constant,then there should be acceleration invloved. But according to the code,there is no variable indicating that. In fact,the acceleration itself is not constant,it keeps changing as the mouse moving,and how much it changes depends on how fast the mouse moving.


accumulate-v-element-move



First of all,if the mouse left button is surpressed by user (_mouseDown is?true),then on each frame,the scrollElement will be moved immediately by the?offset (see the diagram) that the mouse is moved from its position when it is clicked.


_myScrollElement.y = _mouseDownY + (point.y - _mouseDownPoint.y);


Whereas?the velocity is accumulated each time the?MOUSE_MOVE dispatched. Its?augment is caculated by timing the movement offset by?0.4.?


_velocity += ((point.y - _lastMouseDownPoint.y) * SPEED_SPRINGNESS);


?In order to protect the velocity burst,?it will be halfed on each frame if?_mouseDown is?true,otherwise timed by?0.93 (because it stops increasing).?


if(_mouseDown)
			{
				_velocity *= MOUSE_DOWN_DECAY;
			}
            else
			{
				_velocity *= DECAY;
			}


The following diagram shows its variation curve along time.


velocity-function




How to Plot the Bounce Effect


The bouncing factor its calculation process is:


check if scrollElement y-axis position is out of its range,if yes,calculate how much it is off its boundary.


if (y > 0)
                {
		
                    bouncing = -y * BOUNCING_SPRINGESS;
                }
				else if( y + textHeight < _canvasHeight)
				{
                    bouncing = (_canvasHeight - textHeight - y) * BOUNCING_SPRINGESS;
                }

If the y position is off the bottom boundary,then its value is just the offset,otherwise if it is off top boundary,the offset shoud be?


y - (cH - EH)


_canvasHeight - textHeight - y

And the offset should time -0.4,negtive sign is to make it move toward the opposit direction,and 0.4 is just springness.



Finally,the Overall Logic?


As the?flow chart:

logic-flow-chart

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读