Flex裏面寫動畫效果甚是簡單,並且沒有兼容性問題,這一點比js好太多了。也是最近學習Flex以來感到使人欣慰的地方。學習
廢話很少說,進入正題。測試
如今的需求是給定一張圖片(或其餘控件也能夠,暫時我就按本身作的項目上的來舉例吧),要求拖動四個角的時候,圖片能夠按比例縮放。這麼一個常見的需求,不用多想,網上確定已經有現成的控件了不是。google一下,果真,ObjectHandles,這個類庫還能支持旋轉。功能看那上去很強大,可是,跟個人需求仍是有些衝突,個人要求是拖動四個角的時候圖片大小按比率縮放,不能拉伸。不要緊,沒有的東西就本身動手吧,原本也以爲這個功能有點挑戰性,正和我意。動畫
那麼寫以前,簡單理一下思路:1),選中一張圖片後,四個角上出現可拖動的標誌;2)拖動一個角,此時其斜對角爲不動點,圖片縮放。嗯,看上去主要也就是這麼兩步。先上效果圖吧:google
P1P2P3P4圍成的是原始圖片,拖動P4時,原始圖片不動,跟着鼠標縮放的是另外一張半透明的圖片,固然這張圖片是拷貝自原始圖片的。spa
而後,鼠標鬆開後,圖片自動縮放至拖放後的大小。半透明圖消失。code
其實就是繪製四個小矩形而已,方法很簡單:orm
// 建立句柄,用來拖動和拉伸對象 private static function createRect():Image { var img:Image = new Image(); var size:int = 10; img.graphics.beginFill(0xcf67b9, 0.5); img.graphics.drawRect(-size / 2, -size / 2, size, size); img.graphics.endFill(); img.graphics.lineStyle(1, 0); img.graphics.drawRect(-size / 2, -size / 2, size, size); return img; }
有了這個方法以後,只要在圖片上加上點擊事件,第一步就算完成了。直接看效果圖:對象
點擊前: 點擊後:blog
方法其實也不難,但須要注意到的是,當拖動一個角的時候,以其對角的點做爲當前不動點。好比,在最上面的第一幅圖中,拖動P4時,P1爲不動點,拖動P2時,P3爲不動點,...以此類推。事件
不就是變換一下不動點嘛,easy,立馬就會想到,Flex裏面,圖片在縮放時是能夠設置變換中心的(也就是設置不動點,默認是圖片的左上角)。so,開始動手啦:核心功能代碼以下
// 在句柄上按下鼠標左鍵 private function rect_mouse_down(e:MouseEvent):void { trace("evt_rect_mouse_down"); currRect = e.currentTarget as Sprite; if (!currRect) { return; } container.addEventListener(MouseEvent.MOUSE_MOVE, mouse_move); startX = e.stageX; startY = e.stageY; // 跟隨鼠標縮放的操做對象 displayEl = cloneImage(widget as Image, widget.width, widget.height); displayEl.alpha = 0.5; displayEl.width = widget.width * widget.scaleX; displayEl.height = widget.height * widget.scaleY; displayEl.x = rects[0].x; displayEl.y = rects[0].y; container.addChild(displayEl); var index:int = rects.indexOf(currRect);
// 設置變換不動點 setTransformCenter(displayEl, index); } // 拖動矩形句柄,鼠標移動 private function mouse_move(e:MouseEvent):void { if (!currRect) { return; } trace("evt_mouse_move"); var moveX:int = e.stageX - startX; var moveY:int = e.stageY - startY; var ind:int = rects.indexOf(currRect); // 正表明放大,負表明縮小 if (ind == 0) { moveX = -moveX; moveY = -moveY; } else if (ind == 1) { moveY = -moveY; } else if (ind == 2) { moveX = -moveX; } deltaScale = Math.max( moveY / widget.height, moveX / widget.width ); displayEl.scaleX = deltaScale / widget.scaleX + 1; displayEl.scaleY = deltaScale / widget.scaleY + 1; } // 在句柄上鬆開鼠標左鍵 private function rect_mouse_up(e:MouseEvent):void { trace("rect_mouse_up"); if(!currRect) return; currRect = null; container.removeEventListener(MouseEvent.MOUSE_MOVE, mouse_move); container.removeChild(displayEl); widget.scaleX += deltaScale || 0; widget.scaleY += deltaScale || 0;
// 從新計算四個角上句柄的位置 setRects(); }
測試以後,出問題了,嗯,忘記設置原圖的變換中心了嘛!這樣致使拖動任意一個角後,鬆開鼠標,原圖的左上角都不動。不知道各位看官看明白沒有,仍是截個圖說明下吧:
上圖中,鼠標拖動P3,不動點是P2,鬆開鼠標後,應該是P2不動,但實際結果仍是P1沒動。這樣固然不行了,事先仍是少考慮了一層啊!。
考慮到之後的重用及可擴展性,這裏以爲一次性解決這個問題比較好,而不是每次都要改變圖片的變換中心,變來變去,本身都不知道最後的中心在哪了。如今固定變換的中心就是左上角,
指定最後圖片顯示的位置,讓圖片正確顯示就好。
private function fixPosition():void{ var index:int = rects.indexOf(currRect); var scale: Number = widget.scaleX + (deltaScale || 0); var w:Number = widget.width * scale; var h:Number = widget.height * scale; var left:Number, top:Number; switch (index){ case 0: // 左上角 left = rects[3].x - w; top = rects[3].y - h; break; case 1: // 右上角 left = rects[2].x; top = rects[2].y - h; break; case 2: // 左下角 left = rects[1].x - w; top = rects[1].y; break; case 3: // 右下角 left = rects[0].x; top = rects[0].y; break; } widget.x = left; widget.y = top; }
測試一下,嗯,沒什麼問題!到這裏,基本功能就算完成了。固然,這裏只是提供一個了基本的思路,這也只是一個最簡單的版本,不少項目中的功能還沒實現,好比,圖片旋轉操做,邊框不該被放大,圖片的平移等。
後面有時間再來補充一下。
測試源碼: 這裏下載