在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ Ch16 矩陣變換
Ch22 最后的API
Ch14 旋轉(zhuǎn)變換
Ch19 全局陰影與圖像合成
Ch12 三次貝塞爾曲線
Ch4 多線條組成圖形
Ch7 填充顏色
Ch6 線條的屬性
Ch20 裁剪和繪制圖像
CANVAS——Draw on the Web
Ch18 文本對齊與度量
Ch8 填充樣式
Ch15 縮放變換
Ch9 繪制標準圓弧
Ch2 開始前的準備
Ch16 矩陣變換
Ch3 從線段開始
Ch10 使用切點繪制圓弧
Ch21 非零環(huán)繞原則
Ch11 二次貝塞爾曲線
Ch5 繪制矩形
Ch17 文本顯示與渲染
Ch1 HTML5簡介
Ch13 平移變換

Ch16 矩陣變換

變換矩陣

之前三節(jié)所說的坐標變換的三種方式——平移translate(),縮放scale(),以及旋轉(zhuǎn)rotate()都可以通過transform()做到。

在介紹矩陣變換transform()前,我們來說一說什么是變換矩陣。

變換矩陣

以上是Canvas中transform()方法所對應(yīng)的變換矩陣。而此方法正是傳入圖中所示的六個參數(shù),具體為context.transform(a,b,c,d,e,f)。

各參數(shù)意義對應(yīng)如下表:

參數(shù) 意義
a 水平縮放(1)
b 水平傾斜(0)
c 垂直傾斜(0)
d 垂直縮放(1)
e 水平位移(0)
f 垂直位移(0)

當我們把對應(yīng)的0或1代入進矩陣,可以發(fā)現(xiàn)這是一個單位矩陣(水平和垂直縮放默認值是1,代表縮放1倍,即不縮放)。該方法使用一個新的變化矩陣與當前變換矩陣進行乘法運算,然后得到各種變化的效果。

這里簡單說一下,當我們想對一個圖形進行變換的時候,只要對變換矩陣相應(yīng)的參數(shù)進行操作,操作之后,對圖形的各個定點的坐標分別乘以這個矩陣,就能得到新的定點的坐標。

而Canvas繪圖中,就給咱們提供了一個函數(shù)來改變這個變換矩陣,那就是transform()。

矩陣變換transform()

注:以下三個變換的轉(zhuǎn)換結(jié)論轉(zhuǎn)自張雯的博客,童鞋們可以戳進去看看詳情。

平移變換

平移變換

如上圖所示: x’ = x + dx, y’ = y + dy。

也即是說可以使用 context.transform (1,0,0,1,dx,dy)代替context.translate(dx,dy)。 也可以使用 context.transform(0,1,1,0,dx,dy)代替。

縮放變換

同理可以使用 context.transform(sx,0,0,sy,0,0)代替context.scale(sx, sy);

也可以使用context.transform(0,sy,sx,0,0,0);

旋轉(zhuǎn)變換

旋轉(zhuǎn)變換 如上圖圖所示:

B點是通過A點逆時針旋轉(zhuǎn)θ得到, x = r * cosa, y = r * sina

x’=r*cos(a+θ)=x*cosθ-y*sinθy’=r*sin(a+θ)=x*sinθ+y*cosθ

也即是 變換矩陣

綜上: context.transform(Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180), -Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180),0,0)可以替代context.rotate(θ)。

也可以使用 context.transform(-Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180), Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180),0,0)替代。


以上結(jié)論引自張雯的博客,很好的說明了矩陣變換的過程,但是結(jié)論過于復(fù)雜,建議使用transform()的時候,可以在如下幾個情況下使用:

  1. 使用context.transform (1,0,0,1,dx,dy)代替context.translate(dx,dy)
  2. 使用context.transform(sx,0,0,sy,0,0)代替context.scale(sx, sy)
  3. 使用context.transform(0,b,c,0,0,0)來實現(xiàn)傾斜效果(最實用)。

不用再使用它去實現(xiàn)旋轉(zhuǎn)了,另外也沒有也不用全記這些結(jié)論,直接記下abcdef六個參數(shù)的意義,效果是一樣的。

下面我們看一個代碼,熟悉一下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>矩陣變換</title>
    <style>
        body { background: url("./images/bg3.jpg") repeat; }
        #canvas { border: 1px solid #aaaaaa; display: block; margin: 50px auto; }
    </style>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas">
        你的瀏覽器居然不支持Canvas?!趕快換一個吧??!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");
        context.fillStyle = "#FFF";
        context.fillRect(0,0,800,600);

        context.fillStyle = "yellow";
        context.strokeStyle = "#00AAAA";
        context.lineWidth = 5;

        context.save();
        //平移至(300,200)
        context.transform(1,0,0,1,300,200);
        //水平方向放大2倍,垂直方向放大1.5倍
        context.transform(2,0,0,1.5,0,0);
        //水平方向向右傾斜寬度10%的距離,垂直方向向上傾斜高度10%的距離
        context.transform(1,-0.1,0.1,1,0,0);
        context.fillRect(0,0,200,200);
        context.strokeRect(0,0,200,200);
        context.restore();
    };
</script>
</body>
</html>

演示 16-1

運行結(jié)果:

transform

setTransform()方法

transform()方法的行為相對于由 rotate(),scale(), translate(), or transform() 完成的其他變換。例如:如果我們已經(jīng)將繪圖設(shè)置為放到兩倍,則 transform() 方法會把繪圖放大兩倍,那么我們的繪圖最終將放大四倍。這一點和之前的變換是一樣的。

但是setTransform()不會相對于其他變換來發(fā)生行為。它的參數(shù)也是六個,context.setTransform(a,b,c,d,e,f),與transform()一樣。

這里我們通過一個例子來說明: 繪制一個矩形,通過 setTransform() 重置并創(chuàng)建新的變換矩陣,再次繪制矩形,重置并創(chuàng)建新的變換矩陣,然后再次繪制矩形。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>矩陣變換</title>
    <style>
        body { background: url("./images/bg3.jpg") repeat; }
        #canvas { border: 1px solid #aaaaaa; display: block; margin: 50px auto; }
    </style>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas">
        你的瀏覽器居然不支持Canvas?!趕快換一個吧?。?    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");
        context.fillStyle = "#FFF";
        context.fillRect(0,0,800,600);

        context.fillStyle="yellow";
        context.fillRect(200,100,250,100)

        context.setTransform(1,0.5,-0.5,1,30,10);
        context.fillStyle="red";
        context.fillRect(200,100,250,100);

        context.setTransform(1,0.5,-0.5,1,30,10);
        context.fillStyle="blue";
        context.fillRect(200,100,250,100);
    };
</script>
</body>
</html>

演示 16-2

運行結(jié)果:

setTransform

解釋一下過程:每當我們調(diào)用 setTransform() 時,它都會重置前一個變換矩陣然后構(gòu)建新的矩陣,因此在下面的例子中,不會顯示紅色矩形,因為它在藍色矩形下面。

這一節(jié)的內(nèi)容有些難和多,但是除了傾斜其他并不實用,所以童鞋們盡量了解一下就好,能夠掌握就更好啦!至此,所有的圖形變換我們已經(jīng)上完了,基本的三大變化——平移變換、旋轉(zhuǎn)變換、縮放變換,以及萬能的矩陣變換。大家都以及完全掌握了嗎?如果不熟練,要回頭多看看,并且多加練習(xí)。稍作休息,下一節(jié)開始,就是新的航程!我們繼續(xù)前進!