<? xml version = " 1.0 " encoding = " utf-8 " ?> < mx:Canvas xmlns:mx = " http://www.adobe.com/2006/mxml " horizontalScrollPolicy = " off " creationComplete = " init() " > < mx:Script > <! [CDATA[ import mx.managers.DragManager; import mx.core.DragSource; import mx.core.Application; import mx.utils.StringUtil; private var tickers:String = null ; private var timer:Timer = null ; private var quoteUrl:String = " http://xxxx " ; private var duration: int = 20000 ; private var timeOut: int = 8000 ; private var xFrom: int ; private var xTo: int ; private var needConstructPanel:Boolean = false ; [Bindable] private var panelWidth: int = 0 ; [Bindable] private var moveDuration: int = 0 ; public function setTicker(tickerList:String): void ... { this.tickers = tickerList; if (tickerList == "") ...{ } needConstructPanel = true; quoteTicker(null); } private function clear(): void ... { timer.stop(); this.moving.stop(); this.display.removeAllChildren(); } private function quoteTicker(e:TimerEvent): void ... { if (timer) ...{ timer.stop(); timer = null; } trace (quoteUrl) var req:URLRequest = new URLRequest(quoteUrl); req.data = this.tickers; req.contentType = "text/plain"; req.method= URLRequestMethod.POST; var loader:URLLoader = new URLLoader(); loader.addEventListener("complete", quoteTickerDone); loader.load(req); } private function filterTickerInfo(ticker:XML): void ... { var chgPercent:Number = 0; var price:Number = Number(ticker.attribute("price")); var change:Number = Number(ticker.attribute("change")); if (price>0) ...{ chgPercent = change*100/price; if (change < 0) ...{ chgPercent = -chgPercent; ticker.@["change"] = String(ticker.attribute("change")).substr(1); ticker.@["sign"] = "-"; } else ...{ ticker.@["sign"] = "+"; } } ticker.@["chgPercent"] = chgPercent.toFixed(2)+"%"; } private function setTickerInfo(ticker:XML, container:HBox, idx:Number, actionAdd:Boolean): int ... { var widthInfo:int = 0 var tickerInfo:TickerInfo; if (actionAdd) ...{ tickerInfo = new TickerInfo(); filterTickerInfo(ticker); var nFont:int = (String(ticker.attribute("price")).length + String(ticker.attribute("chgPercent")).length); var symbol:String = String(ticker.attribute("symbol")); if (Settings.Instance.marketMap[symbol]) ...{ nFont += Settings.Instance.marketMap[symbol].length; } else ...{ nFont += symbol.length; } widthInfo = 20 + nFont*7; tickerInfo.width = widthInfo; container.addChild(tickerInfo); tickerInfo.data = ticker; widthInfo += 5; } else if (container.numChildren > idx) ...{ tickerInfo = TickerInfo(this.display.getChildAt(idx)); filterTickerInfo(ticker); tickerInfo.data = ticker; } return widthInfo; } private function quoteTickerDone(event:Event): void ... { var dataRes:XML = XML(event.target.data); var idx:int = 0; if (needConstructPanel) ...{ this.moving.stop(); this.panelWidth = 0; this.display.removeAllChildren(); } for each(var ticker:XML in dataRes.ticker) ...{ this.panelWidth += setTickerInfo(ticker, this.display, idx, needConstructPanel); idx++; } if (timer) ...{ timer.stop(); } if (this.tickers != null && this.tickers!="") ...{ timer = new Timer(this.timeOut, 0); timer.addEventListener(TimerEvent.TIMER, quoteTicker); timer.start(); } if (panelWidth>this.width) ...{ for each(ticker in dataRes.ticker) ...{ setTickerInfo(ticker, this.display, idx, needConstructPanel); idx++; } this.moveDuration = (duration/this.width) * (panelWidth+this.width); if (needConstructPanel) ...{ xFrom = 0; xTo = -panelWidth; moving.play(); } } else ...{ if (needConstructPanel) ...{ display.x = 0; } } needConstructPanel = false; trace ("change Ticker") } private function myEasingFunction(t:Number, b:Number, c:Number, d:Number):Number ... { if (c == 0) ...{ return 0; } var pos:Number = ((t%d)/d)*(-panelWidth)+xFrom; if (pos<-this.panelWidth) ...{ pos += this.panelWidth; } return pos; } private var initPos:Number = 0 ; private var initX:Number = 0 ; private function mouseMoveHandler(event:MouseEvent): void ... { if (event.buttonDown && initPos>0) ...{ // Call the DragManager doDrag() method to start the drag. var tmp:int = initX + (event.stageX - initPos); if (this.panelWidth > this.width) ...{ var chang:int = 0; if (tmp > 0) ...{ tmp -= this.panelWidth; //initPos = event.stageX; } else if (tmp <-2*panelWidth+this.width) ...{ tmp += this.panelWidth; //initPos = event.stageX; } chang = display.x - tmp; this.xFrom -= chang; if (this.xFrom < -panelWidth) ...{ this.xFrom += panelWidth; } else if (this.xFrom > 0) ...{ this.xFrom -= panelWidth; } this.xTo = this.xFrom - panelWidth; display.x = tmp; } else ...{ if (tmp < 0) ...{ tmp = 0; } else if (tmp > this.width - this.panelWidth + 3) ...{ tmp = this.width - this.panelWidth; } this.display.x = tmp; } } else ...{ trace(event.buttonDown); trace(initPos); } } private function mouseDownHandler(event:MouseEvent): void ... { initPos = event.stageX; initX = this.display.x; } private function mouseOutHandler(): void ... { moving.resume(); initPos=-1; } ]] > </ mx:Script > < mx:Move xFrom = " 0 " xTo = " {-panelWidth} " easingFunction = " {myEasingFunction} " target = " {display} " duration = " {moveDuration} " startDelay = " 0 " repeatDelay = " 0 " repeatCount = " 0 " id = " moving " > </ mx:Move > < mx:HBox mouseMove = " mouseMoveHandler(event) " mouseDown = " mouseDownHandler(event) " id = " display " width = " 100% " horizontalGap = " 5 " mouseOver = " {moving.pause();} " mouseOut = " mouseOutHandler() " > </ mx:HBox > </ mx:Canvas > 关键点: 1. 构造自己的 easingFunction2. 给显示内容做2,3个拷贝,使之超过显示屏的2倍3. initPos的引入是为了修正flex的鼠标左键检测bug:当鼠标左键按住离开当前flash,会导致 event.buttonDown为true直到发生点击事件。