Html5 canvas坐標變換解析


轉載    http://jo2.org/html5-canvas-translate-scale-rotate/

 

首先說在前頭,大家要千萬注意標題,是“畫面”的位移,縮放和旋轉,而畫布。畫布是指canvas,但畫面是指canvas的Context2d對象,他們千萬不能混淆。

畫面的位移縮放和旋轉,即畫布不變,而把畫布上的那一層“畫”給進行變化。

首先是位移:translate

大家應該了解canvas有個“原點”,即坐標(0,0)的位置,一般是畫布的左上角。translate的作用就是把這個“原點”到處移動,他的語法是我們很熟悉的translate(x,y)形式,但他和moveTo方法毫無相同。當原點變化時,畫面的一切都會發生偏移。

初看這個方法好像讓人莫名其妙,為什么我要移動原點呢?

這里我只說一個很簡單的例子:我要在(300,100)處畫4個同心圓。

先看不translate的方法:

ctx. arc ( 300 , 100 , 30 , 0 ,Math. PI * 2 )
. arc ( 300 , 100 , 40 , 0 ,Math. PI * 2 )
. arc ( 300 , 100 , 50 , 0 ,Math. PI * 2 )
. arc ( 300 , 100 , 60 , 0 ,Math. PI * 2 )
. stroke ( ) ;

以上代碼使用了XtendCanvas.js

大家可以看到,代碼中有好幾個(300,100)坐標值,但如果我們把原點移動到(300,100)的位置,就不用再寫這些坐標了:

ctx. translate ( 300 , 100 )
. arc ( 0 , 0 , 30 , 0 ,Math. PI * 2 )
. arc ( 0 , 0 , 40 , 0 ,Math. PI * 2 )
. arc ( 0 , 0 , 50 , 0 ,Math. PI * 2 )
. arc ( 0 , 0 , 60 , 0 ,Math. PI * 2 )
. stroke ( ) ;

這里我們首先就把原點移動到了目標坐標(300,100),此時,畫面的原點(0,0)就不再是左上角了,而是新的(300,100)。所以我們直接在這個所謂的”原點”處開始畫,實際上卻是在(300,100)處開始畫的。

注意,translate移動的距離其實是“相對”的,也就是說他是在當前的原點坐標基礎上進行偏移,比如默認原點坐標是(0,0),那么此時的translate(300,100)就是在(0,0)的基礎上進行x軸300的偏移,y軸100的偏移。如果本來原點坐標已經變了,比如變成了(10,20),那同樣的translate(300,100)就會把原點變到(10+300,20+100)的位置。

如何把原點再次移回到(0,0)的位置?可以translate(0,0),網友糾正,應該是translate(-300,-100),即剛才移動的坐標取負。也可以通過前幾章講的save,restore方法,建議使用后面的方面,可以避免去找之前移動坐標的負值.

縮放scale

縮放是很容易理解的概念,但在canvas中縮放要記住:縮放是基於“原點”進行的。scale也經常與translate搭配使用。

scale接受兩個參數,依次是水平方向的縮放和垂直方向的縮放。參數可以是小數,如果小於1就是縮小,大於1則是放大——等於1則什么都不做,懂吧?

我們試着用translate和scale結合,來畫一個橢圓,假設此橢圓寬60高80.

var w  =  60 ,=  80 ,= h /w ;
ctx. translate ( 300 , 100 ). scale ( 1 ,b )
. arc ( 0 , 0 ,w / 2 , 0 ,Math. PI * 2 )
. stroke ( ) ;

其中的b變量,就是高度與寬的比,這個比例很容易得出,然后我們保持水平不縮放,但把垂直方向放大至b的值,最后就能得到這樣一個橢圓

當然你也可以讓b=w/h,然后垂直不縮放而縮放水平,最終效果也是一樣的。

旋轉rotate

旋轉也是一個很好理解的概念,而且旋轉也是基於原點進行的。

rotate接受一個表示度數的參數——而且是弧度

讓我們用rotate把上面的橢圓來旋轉一個角度:

var w  =  60 ,=  80 ,= h /w ;
ctx. translate ( 300 , 100 ). rotate (Math. PI / 9 ). scale ( 1 ,b )
. arc ( 0 , 0 ,w / 2 , 0 ,Math. PI * 2 )
. stroke ( ) ;

結果如圖所示:

但是,使用rotate一定要注意我前面說的:旋轉是基於原點的!假如我們把上面的代碼稍稍改一下:

ctx. rotate (Math. PI / 9 ). translate ( 300 , 100 ). scale ( 1 ,b )
. arc ( 0 , 0 ,w / 2 , 0 ,Math. PI * 2 )
. stroke ( ) ;

我們只是把translate和rotate的位置調換了一下,但結果就會是這樣:

此時要知道橢圓的確切坐標,就很難了。因為我們旋轉的時候,原點還是(0,0),但之后又變成了(300,100)

后記:

scale,translate和rotate經常在一起使用,而且他們都基於原點,所以我把它們放在一起講了。如果大家想更深入的了解,可以搜索一下canvas畫時鍾的例子。

另外,他們都可以通過save,restore進行保存或還原。

同時,他們也是先定義后起作用的方法。也就是說,只有先scale,translate和rotate之后畫的路徑才會有相應變化,不能先畫出路徑,再企圖進行位移或旋轉縮放什么的。

本文鏈接: Html5 canvas畫圖教程14:畫面的位移translate,縮放scale,旋轉rotate.轉載請保留.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM