forked from: Kinetic Scroll sanoi forked:1favorite:2lines:203license : MIT License modified : 2011-01-03 13:36:10 Embed Tweet // 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; } } } Code Fullscreen Preview Fullscreen xor m0ose : ipodkineticlikescrollscroll ipod kinetic like scroll sort new page view favorite forked pv198 forked from: forked from: Kine.. hacker_a7xbpc4j forked:0 favorite:0lines:203 (diff:8)