In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Kinetic Scroll

Get Adobe Flash player
by sanoi 03 Jan 2011
/**
 * Copyright sanoi ( http://wonderfl.net/user/sanoi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/5cfy
 */

// forked from gggiyeok's Kinetic Scroll
package {
    import flash.display.AVM1Movie;
    import flash.display.Sprite;
    import com.bit101.components.*;
    import flash.events.*;
    import flash.utils.*;
    public class FlickList extends Sprite {
       /* 
        minimalComps를 Flash IDE에서 사용시 폰트임베트 시키기 
        Style.embedFonts = true;
        var font = new FontA();
        Style.fontName = font.fontNuint
       */      
        private var listCnt:uint=200000;
        private var listItemH:uint=40;
        private var listH:uint=200;
        private var totalH:uint=listItemH*listCnt;
        private var containerPosY:int = 50;
        
        private var tCnt:uint=0;
        private var tension:Array=[.5,.3,.2,.1,0];
        private var tmpY:Number=0;
        private var dragStatus:int=0;//tensino direction
        private var tensionPosSum:Number=0;
        
        private var cy:Number=0;
        private var listW:uint=300;
        private var viewCnt:uint=Math.ceil(listH/listItemH)*2;
        private var listContainer:Panel;
        private var scrollValue:Number=0;
        private var listItems:Array
        private var scrollBar:VScrollBar;
        private var dy:Number=0;
        private var flickTime:Number;
        private var spd:int;
        
        public function FlickList(){
            listItems = new Array();
            if (listCnt<int(listH/listItemH)) {
                totalH=listH;
            }           
            listContainer =new Panel(this, 0, containerPosY);
            listContainer.setSize(listW, listH);
            scrollBar = new VScrollBar(this,listW,containerPosY,changeScroll);
            scrollBar.setSize(10, listH);
            scrollBar.setThumbPercent(listItemH/(totalH-listH));
            var max:int=totalH-listH;
            if (max<0) {
                max=0;
            }
            scrollBar.setSliderParams(0, max, 0);
            
            init();
        }
        private function init() :void{
            for (var i:uint = 0; i < viewCnt; i++) {
                var item:ListItem = new ListItem(listContainer.content,0,listItemH*i);
                item.y = listItemH*i;        
                //listContainer.addChild(item);
                item.setSize(listW, listItemH);
                listItems.push(item);
                if (i<listCnt) {
                    item.data={label:String(i),id:i};
                } else {
                    item.data={label:'',id:i};
                }
            }
            listContainer.addEventListener(MouseEvent.MOUSE_DOWN, down);
        }
        private function changeScroll(e:Event) :void{
            scrollJump(scrollBar.value);
        }
        /* scroll by scorllBar */
        private function scrollJump(val:Number):void{
            var index:int=int(val/listItemH);
            var iy:Number = listItemH*(index) - val;
            for (var i:uint = 0; i < viewCnt; i++) {
                var item:ListItem=listItems[i];
                item.y = iy + listItemH * i;
                var newIndex:int = i + index;
                item.data = { label:String(newIndex), id:newIndex };
                item.visible = true;
                if (newIndex < 0 || newIndex > listCnt-1) item.visible = false;
            }
            cy = -val;
        }
        private function down(e:MouseEvent) :void{
            dy=mouseY;
            flickTime=getTimer();
            removeEventListener(Event.ENTER_FRAME, flickList);
            removeEventListener(Event.ENTER_FRAME, rewind);
            stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
            e.currentTarget.addEventListener(Event.ENTER_FRAME, drag);
            tensionPosSum=0;
            tmpY=0;
        }
        
        private function endDrag(e:MouseEvent) :void{
            removeEventListener(Event.ENTER_FRAME, flickList);
            if (dragStatus>0) {
                tmpY=cy;
                addEventListener(Event.ENTER_FRAME, rewind);
            } else if (dragStatus < 0) {
                tmpY = (totalH-listH)+cy;
                addEventListener(Event.ENTER_FRAME, rewind);
            }
            if (Math.abs(spd)>10&&dragStatus==0) {
                addEventListener(Event.ENTER_FRAME, flickList);
            }
            listContainer.removeEventListener(Event.ENTER_FRAME, drag);
        }
        
        private function rewind(e:*=null) :void{
            listContainer.removeEventListener(Event.ENTER_FRAME, drag);
            
            //Floating-point 에러 보정
            var divideVal:int=Math.round(tmpY*tension[tCnt]);
            if (tCnt==tension.length-2) {
                divideVal=tmpY-tensionPosSum;
            }
            tensionPosSum+=divideVal;
            tCnt++;
            scroll(-divideVal);
            if (tCnt==tension.length) {
                removeEventListener(Event.ENTER_FRAME, rewind);
                tensionPosSum=0;
                tCnt=0;
            }
        }
        private function flickList(e:Event) :void{
            spd*=.9;
            //상하 리스트의 끝자리에서 크게 flick했을 때 텐션 범위 조절
            if(spd < 0){
                if(cy > listH/4) spd*=.4;
            }else if( spd > 0){
                if(cy+listH < -(totalH-listH)) {
                    spd*=.4;
                }
            }
            if (Math.abs(spd)<1) {
                removeEventListener(Event.ENTER_FRAME, flickList);
                //되돌아가기
                if (dragStatus>0) {
                    tmpY=cy;
                    addEventListener(Event.ENTER_FRAME, rewind);
                } else if (dragStatus < 0) {
                    tmpY = (totalH-listH)+cy;
                    addEventListener(Event.ENTER_FRAME, rewind);
                }
                return;
            }else     scroll(-spd);
        }
        private function drag(e:Event) :void{
            spd=dy-mouseY;
            dy=mouseY;
            flickTime=getTimer();
            var abs:Number=Math.abs(spd);
            if (abs>0) {
                scroll(-spd);
            }
        }
        private function scroll(val:Number) :void{
            cy+=val;
            var i:int,item:ListItem,id:int;
            if (-(totalH-listH) > cy ) dragStatus=-1; //pull up 
            else if (cy > 0) dragStatus=1; //pull down
            else dragStatus=0; // drag
            var popItem:Vector.<ListItem> = new Vector.<ListItem>();
            if (val<0) {
                for (i = 0; i < viewCnt; i++) {
                    item=listItems[i];
                    item.y+=val;
                    if (item.y+item.height<0) {
                        popItem.push(item);
                    }
                }
                if (dragStatus!=0)     return; 
                if (popItem.length>0) {
                    for (i = 0; i < popItem.length; i++) {
                        item=listItems.shift();
                        var prev:ListItem=listItems[listItems.length-1];
                        id=prev.data.id+1;
                        if (id>listCnt-1) {
                            item.visible=false;
                        } else {
                            item.visible=true;
                        }
                        item.data={label:String(prev.data.id+1),id:prev.data.id+1};
                        item.y=prev.y+listItemH;
                        listItems.push(item);
                    }
                }
            } else if (val > 0) {
                for (i = 0; i < viewCnt; i++) {
                    item=listItems[i];
                    item.y+=val;
                    if (item.y>listH) {
                        popItem.push(item);
                    }
                }
                if (dragStatus!=0)return;
                if (popItem.length>0) {
                    for (i = 0; i < popItem.length; i++) {
                        item=listItems.pop();
                        var next:ListItem=listItems[0];
                        id=next.data.id-1;
                        if (id<0) {
                            item.visible=false;
                        } else {
                            item.visible=true;
                        }
                        item.data={label:String(next.data.id-1),id:next.data.id-1};
                        item.y=listItems[0].y-item.height;
                        listItems.unshift(item);
                    }
                }
            }
            scrollBar.value=- cy;
        }
    }
}