日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

flex 图片旋转(解决公转和自转问题)

發布時間:2024/4/17 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 flex 图片旋转(解决公转和自转问题) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

在Flex中圖片的旋轉是既有公轉和自轉的。這樣在圖片旋轉的時候就有一定小麻煩;

為了更好地說明問題,先引入兩個概念:“自轉”和“公轉”。想象一下,地球在繞著太陽公轉的同時,它自己也在自轉。Flash應用中的顯示對象可以進行自身的自轉,也可以繞著某個點公轉,也可以兩者同時進行。

?

實現旋轉常用的方法

1)??????displayObject.rotation=degree; //實現顯示對象的自轉(flash|Flex

2)??????spark.effects.Rotate; //實現顯示對象的自轉(Flex

3)??????matrix.rotate; //同時實現顯示對象的自轉和公轉(flash|Flex

本文重點介紹matrix.rotate的實現細節。

最近做的一個小項目需要實現“圖片繞中心旋轉”的效果。在網上搜索了相關的資料,在很多帖子中都推薦使用Matrix來實現。代碼如下:?

var matrix:Matrix = img.transform.matrix;

matrix.translate(-img.width/2,-img.height/2);

matrix.rotate(radian);

matrix.translate(+img.width/2,+img.height/2);

img.transform.matrix = matrix;

相信做過“圖片繞中心旋轉”效果的朋友都見過這段代碼。實現原理就是先把圖片的中點移動到左上角,然后進行旋轉操作,最后再把圖片移回來。看起來很好理解,但是這段代碼在我的Flex應用中卻不能正常工作。又回到網上搜索了很長時間,發現這段代碼出現在很多論壇博客中,沒有一個說這段代碼有問題的。通過測試,最后才發現了問題所在:此段代碼需要在特定的前提下才能正常使用。這個前提下面會細說。現在我們先來看matix.rotate這個方法究竟做了什么。

?

matix.rotate做了什么

Flash IDE中做了一系列試驗:在場景中放置一個影片剪輯,影片剪輯的注冊點分別在左上角和中心,影片剪輯的x,y分別在(0,0)(70,70)

試驗的結論是:

matrix.rotate方法讓目標對象同時進行“自轉和公轉”,旋轉的實現跟“影片剪輯的注冊點的位置”和“影片剪輯的初始位置”有很大的關系。詳見下面的4個場景(灰色框為場景,黑色框為旋轉目標):

場景1影片剪輯的注冊點在左上角,影片剪輯在場景中的初始位置為(0,0)

結果:影片剪輯自轉的同時繞著(0,0)公轉。因為公轉的半徑為0,所以沒有體現在圖片上。

?

場景2影片剪輯的注冊點在左上角,影片剪輯在場景中的初始位置為(70,70)

結果:影片剪輯自轉的同時繞著(0,0)公轉,公轉的半徑為70

?

場景3影片剪輯的注冊點在中心,影片剪輯在場景中的初始位置為(0,0)

結果:影片剪輯自轉的同時繞著(0,0)公轉,因為公轉的半徑為0,所以沒體現在圖上。

?

場景4影片剪輯的注冊點在中心,影片剪輯在場景中的初始位置為(125,30)

結果:影片剪輯自轉的同時繞著(0,0)公轉,因為公轉的半徑為125

?

在上面的這些場景中,第三個場景的影片剪輯是繞中心旋轉的。也就是說,影片剪輯在滿足以下兩個條件時,才能使用matrix.rotate方法實現繞中心旋轉。?

1)??影片剪輯的注冊點在中心;

2)??影片剪輯的中心點與場景(或父影片剪輯)(0,0)重疊。

再重新觀察上面的那段代碼:

var matrix:Matrix = img.transform.matrix;

matrix.translate(-img.width/2,-img.height/2);

matrix.rotate(radian);

matrix.translate(+img.width/2,+img.height/2);

img.transform.matrix = matrix;

代碼中使用了translate方法,很顯然目的就是為了讓img的中心點與父影片剪輯的(0,0)點重疊。所以,使用這段代碼的前提條件是:

1)??Flash IDE中開發;(才能調整注冊點的位置)

2)??目標影片剪輯的注冊點在中心;

3)??把目標影片剪輯放在一個空影片剪輯中,并設置x,y(0,0)

善了個哉的,網上這么多篇文章提到這段代碼,居然沒有一篇提到上述的條件,坑爹吶!

?如果是在Flash IDE環境中進行開發,實現旋轉還有一個更方便的可選項,那就是MatrixTransformer.rotateAroundInternalPointMatrixTransformer.rotateAroundExternalPoint。這兩個靜態方法用起來可比matrix.rotate方便多了。不需要考慮注冊點的問題,也不需要把目標影片剪輯放到空的影片剪輯中。只可惜在Flex中沒有這個類。

?

如何在Flex中實現旋轉

Flex環境中沒有影片剪輯,它使用自己的一套組件,注冊點默認在左上角,不能調整注冊點的位置。我們如何實現組件的旋轉呢?

1)??使用rotation屬性。但是因不能調整組件的注冊點,所以只能讓組件繞左上角旋轉。

2)??使用spark.effects.Rotate類。可以通過設置autoCenterTransformtruefalse來控制組件是繞中心點旋轉還是繞左上角旋轉。

3)??使用matrix.rotate方法。通過控制組件的“自轉”和“公轉”來實現我們需要的旋轉。

調用matrix.rotate方法,會使目標對象同時進行“自轉”和“公轉”,這可以從上面的場景2和場景4中明顯看出。其實在場景1中和場景3中,目標對象也是同時進行了“自轉”和“公轉”,只是因為公轉的半徑為0,所以看不出來而已。

如果目標對象的初始位置不是(0,0)的話,如何實現目標對象的繞點旋轉呢?首先,對于旋轉目標的自轉,我們不需要做什么。因為自轉是必須的。而對于旋轉目標的公轉,我就需要做一些額外的操作了。因為公轉改變了旋轉目標的位置,這也是影響旋轉目標是否繞點旋轉的因素。調用matrix.rotate方法時,我們不能阻止旋轉目標的公轉,所以,解決辦法只能是:在調用matrix.rotate之前,取得旋轉中心點的位置,然后在旋轉后,再取得旋轉中心點的位置,然后計算點的位移,最后用matrix.translate方法將旋轉目標調整到“正確位置”。

下面兩組圖是兩個不同旋轉中心下的旋轉,旋轉之后,我們再通過matrix.translate方法把旋轉后的粉色的原點移動到它原始的狀態及可。見圖。


注冊點在左上角,繞中心旋轉。

?

?

注冊點在左上角,繞左上角旋轉。這種情況下,使用matrix.rotate方法顯然是多余的,因為簡單地使用displayObject.rotation屬性就可以實現想要的旋轉了。在這里我們使用matrix.rotate方法是為了更好地說明matrix.rotate方法的實現細節。

?

注冊點在中心,繞中心點旋轉。如果需要在Flash中用matrix.rotate方法實現旋轉,且不依賴父影片剪輯,則使用該方法。

?

注冊點在中心,繞左上角旋轉。

?

最后提供一段代碼,此代碼實現讓一個注冊點在左上角的對象繞它的中心點旋轉。代碼如下:

//旋轉之前獲取旋轉對象的中心點

var p1:Point = rotatedObject.localToGlobal(new Point(rotatedObject.width/2, rotatedObject.height/2));

//旋轉

var matrix1:Matrix = rotatedObject.transform.matrix;

matrix1.rotate(radian);

rotatedObject.transform.matrix = matrix1;

//旋轉后獲取旋轉對象的中心點

var p2:Point = rotatedObject.localToGlobal(new Point(rotatedObject.width/2, rotatedObject.height/2));

//位移

var matrix2:Matrix = rotatedObject.transform.matrix;

matrix2.translate(p1.x-p2.x,p1.y-p2.y);

rotatedObject.transform.matrix = matrix2;

?

?

2012-5-5補充:

更新一個新的旋轉方式。這個方法是MatrixTransformer類中rotateAroundInternalPoint靜態方法的做法。

假設有一個圖片A,我們希望將圖片繞O點旋轉。O點在圖片內部的坐標是(x,y)。我們可以先移動圖片,讓圖片的O點與父容器的(0,0)點重合,調用rotate方法進行旋轉,然后再將圖片移動回正確的位置。代碼如下:

?

var point:Point = new Point(x, y);

point = m.transformPoint(point);//將圖片內部的點轉換成父容器坐標的點

m.tx -= point.x;

m.ty -= point.y;

m.rotate(angleDegrees*(Math.PI/180));

m.tx += point.x;

m.ty += point.y;

?

MatrixTransformer類的另一個rotateAroundExternalPoint靜態方法的做法類似,但是因為是以“外部的點”為旋轉中心,所以代碼有些不同:

?

var point:Point = new Point(x, y);

m.tx -= point.x;

m.ty -= point.y;

m.rotate(angleDegrees*(Math.PI/180));

m.tx += point.x;

m.ty += point.y;

?

在這個方法中,“外部的點”是在父容器的坐標空間中,所以不需要再轉換該點了。

?

另一個旋轉方式:

這個方法是某Transform tool中的做法。注意,這個方法跟上邊補充的第一種方法不一樣。

anchor = new Point(width/2, height/2); //旋轉對象的坐標空間內旋轉對象的中心點

//?把旋轉對象的中心點轉換成父容器坐標空間中的點

var globalAnchor:Point = matrix.transformPoint(anchor);??

// calculates position

var m:Matrix = new Matrix(); //創建了一個新的matrix對象

//下面的操作是把這個matrix對象轉化成我們想要的

m.translate(-anchor.x, -anchor.y);//將目標的中心點移動到與父容器坐標系統的(0,0)重疊

m.rotate((rotation + angle)*Math.PI/180);//旋轉目標

m.translate(globalAnchor.x, globalAnchor.y);//將目標的中心點移動到合適的位置

為什么var globalAnchor:Point = matrix.transformPoint(anchor);能把旋轉對象的中心點的坐標轉換成旋轉對象的父容器的坐標呢?

?當旋轉對象放在父容器中,沒有應用任何matrix變形時,它的坐標系統和父容器的坐標系統是重疊的,也就是說,旋轉對象的中心點在父容器坐標系統中的坐標就是它的本地坐標。當旋轉對象發生matrix變形后,旋轉對象的中心點在父容器坐標系統的坐標發生了變化,而這個變化正是應用在旋轉對象上的matrix對象帶來變形效果。因此,matrixtransformPoint方法能把本地坐標轉換成父容器坐標。

左上角的圖形是變形前的,右邊的圖形是變形之后的。中心點1的本地坐標是(2,2),因為在沒有使用任何matrix效果時,它的本地坐標系統跟父容器的坐標系統是重疊的。因此它在父容器中的坐標也是(2,2)。這個點在經過matrix變形后,就變成了(9,5),也就是圖形中心點在父容器坐標系統中的新坐標。

解決方案就是把圖片放到父容器的(0,0)點進行旋轉,在平一會你想好要的位置;

?

public function draw( displayTarget : Sprite , point : Point , index : int ) : void { var graphics : Graphics = displayTarget.graphics ; var metrix : Matrix = new Matrix( 1.0 , 0.0 , 0.0 , 1.0 , 0 , 0 ); graphics.beginBitmapFill( this._image , metrix , false , true ); graphics.drawRect( 0,0, this.size, this.size); graphics.endFill();//求等腰三角形斜邊長 的一辦 var halfDiagonal : Number = (this.size/2)*Math.sqrt(2); var rotateAngle : Number = 0;displayTarget.rotation = angle;if(0 <= angle && angle < 45) { rotateAngle = (angle+45)* (Math.PI/180); displayTarget.x = point.x - Math.cos(rotateAngle)*halfDiagonal; displayTarget.y = point.y - Math.sin(rotateAngle)*halfDiagonal;}else if(45 <= angle && angle < 135) { rotateAngle = (angle - 45)* (Math.PI/180);displayTarget.x = point.x + (Math.sin(rotateAngle)*halfDiagonal); displayTarget.y = point.y - (Math.cos(rotateAngle)*halfDiagonal); } else if(135 <= angle && angle < 225) { rotateAngle = (angle - 135)* (Math.PI/180);displayTarget.x = point.x + (Math.cos(rotateAngle)*halfDiagonal); displayTarget.y = point.y + (Math.sin(rotateAngle)*halfDiagonal); } else if(225 <= angle && angle < 315) { rotateAngle = (angle - 225)* (Math.PI/180);displayTarget.x = point.x - (Math.sin(rotateAngle)*halfDiagonal); displayTarget.y = point.y + (Math.cos(rotateAngle)*halfDiagonal); } else if(315 <= angle && angle < 360) { rotateAngle = (angle - 315)* (Math.PI/180);displayTarget.x = point.x - (Math.cos(rotateAngle)*halfDiagonal); displayTarget.y = point.y - (Math.sin(rotateAngle)*halfDiagonal); }}

  

轉載于:https://www.cnblogs.com/youngKen/p/3430821.html

總結

以上是生活随笔為你收集整理的flex 图片旋转(解决公转和自转问题)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。