+ -
当前位置:首页 → 问答吧 → 一个iPhone的拖动加速度减速度效果,帮忙解释一下代码原理。

一个iPhone的拖动加速度减速度效果,帮忙解释一下代码原理。

时间:2011-02-22

来源:互联网

一个模仿iPhone的拖动的加速度减速度效果,演示在这:

Kinetic scrolling
http://www.nbilyk.com/kinetic-scrolling-example

代码如下,帮忙解释一下,不是很明白:
复制内容到剪贴板
代码:
/**
* @author Nicholas Bilyk - April 2009
*/
package com.nbilyk.utils {
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.utils.getTimer;
    
    import mx.core.Container;
    
    /**
     * To use via mxml:
     * <utils:KineticScrollManager target="{targetContainer}"/>
     *
     * To use via actionscript:
     * create a non-temporary instance of KineticScrollManager, passing the UIComponent you wish to
     * use kinetic scrolling on.
     *
     * Example:
     * private var ksm:KineticScrollManager;
     * ksm = new KineticScrollManager(component, true);
     */
    public class KineticScrollManager {
        private static const HISTORY_LENGTH:uint = 5; // The amount of mouse move events to keep track of
        
        private var _target:Container;
        [ArrayElementType("Point")]
        private var previousPoints:Array;
        [ArrayElementType("int")]
        private var previousTimes:Array;
        private var velocity:Point;
        
        public function KineticScrollManager(targetVal:Container = null) {
            target = targetVal;
        }
        public function get target():Container {
            return _target;
        }
        public function set target(value:Container):void {
            if (_target) removeAllListeners();
            _target = value;
            if (value) {
                target.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true);
            }
        }
        private function mouseDownHandler(event:MouseEvent):void {
            if (target.verticalScrollBar && target.verticalScrollBar.owns(DisplayObject(event.target))) return;
            if (target.horizontalScrollBar && target.horizontalScrollBar.owns(DisplayObject(event.target))) return;
            stop();
            previousPoints = [new Point(target.mouseX, target.mouseY)];
            previousTimes = [getTimer()];
            target.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, false, 0, true);
            target.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);
        }
        private function mouseMoveHandler(event:MouseEvent):void {
            if (!event.buttonDown) {
                mouseUpHandler();
                return;
            }
            var currPoint:Point = new Point(target.mouseX, target.mouseY);
            var currTime:int = getTimer();
            var previousPoint:Point = Point(previousPoints[previousPoints.length - 1]);
            var previousTime:int = int(previousTimes[previousTimes.length - 1]);
            var diff:Point = currPoint.subtract(previousPoint);
            target.horizontalScrollPosition -= diff.x;
            target.verticalScrollPosition -= diff.y;
            
            // Keep track of a set amount of positions and times so that on release, we can always look back a consistant amount.
            previousPoints.push(currPoint);
            previousTimes.push(currTime);
            if (previousPoints.length >= HISTORY_LENGTH) {
                previousPoints.shift();
                previousTimes.shift();
            }
        }
        private function mouseUpHandler(event:MouseEvent = null):void {
            target.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            target.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            target.addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true);
            
            var currPoint:Point = new Point(target.mouseX, target.mouseY);
            var currTime:int = getTimer();
            var firstPoint:Point = Point(previousPoints[0]);
            var firstTime:int = int(previousTimes[0]);
            var diff:Point = currPoint.subtract(firstPoint);
            var time:Number = (currTime - firstTime) / (1000 / 24);
            velocity = new Point(diff.x / time, diff.y / time);
        }
        private function enterFrameHandler(event:Event):void {
            velocity = new Point(velocity.x * .8, velocity.y * .8);
            if (Math.abs(velocity.x) < .1) velocity.x = 0;
            if (Math.abs(velocity.y) < .1) velocity.y = 0;
            if (!velocity.x && !velocity.y) stop();
            target.horizontalScrollPosition -= velocity.x;
            target.verticalScrollPosition -= velocity.y;
            x -= 8
            x = x-8
        }
        public function stop():void {
            target.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            velocity = new Point();
        }
        private function removeAllListeners():void {
            target.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            target.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            if (target.stage) {
                target.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                target.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
            }
        }
    }
}

作者: vinewood   发布时间: 2011-02-22

不要着急,慢慢来

作者: flash023   发布时间: 2011-02-22

仔細看 function mouseMoveHandler函數

作者: enc0717   发布时间: 2011-02-22