滑鼠拖動時旋轉 多個節點以同一點旋轉

2021-09-01 15:30:45 字數 1660 閱讀 7758

示例以raphaeljs在操作

在旋轉時要搞明白乙個問題,相對於誰在旋轉?

這裡有乙個節點,x為170,y為160,width為150,height為50,沒有旋轉此時它的matrix為(1,0,0,1,0,0),

此時我們呼叫rotate(90,235,185)會使它以軸心圓心90度

旋轉之後結果:

這個時候也不管什麼matrix,x,y如果此時我想以左上角為圓心來旋轉此節點,應該怎麼操作?

聰明的同學肯定相到了,直接rotate(90,170,160+50)就可以了,那麼為什麼這樣就可以了呢?

左上角在直接座標系中的座標是(210,110)根據圓心所在位置很簡單就可以算出來或者根據matrix來計算

x =170 * 0 -(160+50) + 430 = 210 (x = matrix['a'] * x + matrix['c']*y+e)

y=170*1- 210*0 - 60=110(y = matrix['b'] * x + matrix['d']*y+f)

在大部分情況下我知道節點此時的左上角座標為(210,110)為什麼我不能用rotate(90,210,110)而要用rotate(90,170,210),它們的區別在那裡?

第一種做法肯定是對的,那麼第二種錯在那?

問題的根源在這裡,這裡有兩個座標系,乙個是畫布的直接座標系,乙個是節點本身的座標系,節點旋轉時是以其本身的座標系來計算圓心的,乙個節點不管你怎麼旋轉它的x,y是不會變化的(相對於它自己),此時根據它來計算對應的旋轉座標。

如果直接指定畫布座標系的座標給節點rotate,那麼節點會認為這是我本身的座標系,於是就出錯了。

那麼在知道畫布座標的情況下,怎麼計算出相對於節點的座標,比如說這裡有(210,110)怎麼算出其相對節點為(170,210)?

一般情況下,在節點旋轉後我們會根據matrix*(x,y)得出實際座標,那麼在知道實際座標後除以matrix就能得出相對於節點的座標了,根據實際座標*matrix的反置矩陣即可算出來

matrixproto.invert = function () ;
所以關鍵點在於旋轉是以節點本身的座標係為依準的。

明白了這一點,那麼處理多個節點旋轉就很方便了。

獲取到旋轉中心後,分別計算此中心相對於各節點的座標就ok了

/**

* 旋轉時是相對於旋轉系裡面的座標來定的,比如說乙個節點以500,0來旋轉,

* 這個500,0是相對於節點本身的座標系,對節點來說是500,0,對直角座標系來說

* 就要乘以matrix才是真正的座標,

* 現在己知旋轉的圓心在直角座標系中的圓心,要計算出相對於節點的座標系的座標

* 即要除以matrix才是直正的座標

* * 多個節點相對於一點旋轉,就要計算出這點相對於節點的做標

*/var matrix = selectednode.getmatrix().invert();

var ncx = matrix['a'] * cx + matrix['c'] * cy + matrix['e'];

var ncy = matrix['b'] * cx + matrix['d'] * cy + matrix['f'];

selectednode.rotate( offsetangle, ncx, ncy );

乙個HTML元素有多個class時,以哪個為主

當乙個html元素中有多個class,而多個class中又有相同的屬性不同的屬性值,到底以哪個為主?比如 class tab layui tab content div 其中tab是自定義的類,layui tab content是layui的類,其中有乙個padding屬性,我想把layui tab...

同一伺服器部署多個tomcat時的埠號修改詳情

同一伺服器部署多個tomcat時,存在埠號衝突的問題,所以需要修改tomcat配置檔案server.xml,以tomcat7為例。其中8080為http埠,8443為https埠 8005為遠端停服務埠 8009為ajp埠,apache能過ajp協議訪問tomcat的8009埠。1.http埠,預設...

同一伺服器部署多個tomcat時的埠號修改詳情

同一伺服器部署多個tomcat時,存在埠號衝突的問題,所以需要修改tomcat配置檔案server.xml,以tomcat7為例。其中8080為http埠,8443為https埠 8005為遠端停服務埠 8009為ajp埠,apache能過ajp協議訪問tomcat的8009埠。1.http埠,預設...