標籤的使用(圖形學初步?)

文中例子來源:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes,在這裏表示感謝。

由於Web課程的Demo想做iPone的購買界面,原因是我覺得蘋果的設計實在漂亮。就去學習,有用到Canvas標籤,這個蘋果引領起來的標籤實在強大。學習記錄在此。

用法

<canvas>標籤的用法是在<body>中放好位置,然後在js中進行配置。簡單的Demo代碼如下,忘記了看到可以儘快上手:

<head>
    <meta charset="UTF-8">
    <title>CanvasTest</title>

    <script type="text/javascript">
        function draw() {
            var canvas = document.getElementById("canvas");
            if(canvas.getContext)
            {
                var ctx = canvas.getContext("2d");

                ctx.fillStyle = "rgb(200, 0, 0)";   //顏色
                ctx.fillRect(10, 10, 55, 50);       //位置和大小

                ctx.fillStyle = "rgba(0, 0, 200, 0.5)";   //顏色,透明度
                ctx.fillRect (30, 30, 55, 50);            //位置和大小
            }
        }

    </script>

    <style type="text/css">
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body onload="draw()">
<canvas id="canvas" width="150" height="150">
//這裏存放替代內容,可以用文本與圖片
</canvas>
</body>

矩形繪製

矩形繪製有三種常用方法

fillRect(x, y, width, height)   //繪製一個填充的矩形
strokeRect(x, y, width, height) //繪製一個矩形的邊框
clearRect(x, y, width, height)  //清除指定矩形區域,讓清除部分完全透明。

繪製例子:

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.fillRect(25,25,100,100);
    ctx.clearRect(45,45,60,60);
    ctx.strokeRect(50,50,50,50);
  }
}

繪製矩形例子

另外還可以用react()函數繪製矩形。

rect(x, y, width, height)       //繪製一個左上角座標爲(x,y),寬高爲width以及height的矩形。

當該方法執行的時候,moveTo()方法自動設置座標參數(0,0)。也就是說,當前筆觸自動重置會默認座標。

繪製路徑

非基本的圖形可以由路徑繪製。繪製路徑是圖形繪製裏的一個基本內容。通俗的講就是爲想畫的圖形畫邊界。

用路徑繪製圖形步驟如下:

  1. 首先,你需要創建路徑起始點。
  2. 然後你使用畫圖命令去畫出路徑。
  3. 之後你把路徑封閉。
  4. 一旦路徑生成,你就能通過描邊或填充路徑區域來渲染圖形。

接下來是繪製圖形所用到的函數:

beginPath() //新建一條路徑,生成之後,圖形繪製命令被指向到路徑上生成路徑。(相當於 文件-新建)
closePath() //閉合路徑之後圖形繪製命令又重新指向到上下文中。
stroke()    //通過線條來繪製圖形輪廓。
fill()      //通過填充路徑的內容區域生成實心的圖形。填充時會自動閉合。

用路徑繪製一個三角形的例子:

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    ctx.beginPath();
    ctx.moveTo(75,50);
    ctx.lineTo(100,75);
    ctx.lineTo(100,25);
    ctx.fill();

  }
}

路徑繪製三角形例子

其中moveTo()函數是一個移動筆觸,用來將筆觸移動到指定座標上,十分有用。
lineTo是繪製直線的函數,繪製一條到座標位置的直線。

下面是一個靈活運用移動筆觸繪製笑臉的例子:

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    ctx.beginPath();
    ctx.arc(75,75,50,0,Math.PI*2,true); // 繪製
    ctx.moveTo(110,75);
    ctx.arc(75,75,35,0,Math.PI,false);   // 口(順時針)
    ctx.moveTo(65,65);
    ctx.arc(60,65,5,0,Math.PI*2,true);  // 左眼
    ctx.moveTo(95,65);
    ctx.arc(90,65,5,0,Math.PI*2,true);  // 右眼
    ctx.stroke();
  }
}

筆觸繪製笑臉

例子中的arc()方法用來繪製弧線。使用方法如下:

arc(x, y, radius, startAngle, endAngle, anticlockwise) //畫一個以(x,y)爲圓心的以radius爲半徑的圓弧(圓),從startAngle開始到endAngle結束,按照anticlockwise給定的方向(默認爲順時針)來生成。
arcTo(x1, y1, x2, y2, radius)                          //根據給定的控制點和半徑畫一段圓弧,再以直線連接兩個控制點(這個方法不推薦使用)。

arc()函數六個函數分別爲:橫縱座標、半徑、始末弧度、旋轉方向(正逆否順)
需要注意的是arc指的是弧度而不是角度,計算公式:radians=(Math.PI/180)*degrees

下面是12個不同角度與填充圓弧的例子:

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    for(var i=0;i<4;i++){
      for(var j=0;j<3;j++){
        ctx.beginPath();
        var x              = 25+j*50;               // x 座標值
        var y              = 25+i*50;               // y 座標值
        var radius         = 20;                    // 圓弧半徑
        var startAngle     = 0;                     // 開始點
        var endAngle       = Math.PI+(Math.PI*j)/2; // 結束點
        var anticlockwise  = i%2==0 ? false : true; // 順時針或逆時針

        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

        if (i>1){
          ctx.fill();
        } else {
          ctx.stroke();
        }
      }
    }
  }
}

弧度例子

貝塞爾曲線

貝塞爾曲線用來繪製複雜有規律的圖形,具體圖像參考維基百科:https://zh.wikipedia.org/wiki/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A
貝塞爾曲線的使用函數:

quadraticCurveTo(cp1x, cp1y, x, y)          //繪製二次貝塞爾曲線,cp1x,cp1y爲一個控制點,x,y爲結束點。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) //繪製三次貝塞爾曲線,cp1x,cp1y爲控制點一,cp2x,cp2y爲控制點二,x,y爲結束點。

貝塞爾曲線
上圖是兩種貝塞爾曲線的圖示。在圖中,藍點爲起始點,結束點(x, y),控制點(cpx, cpy)。

二次貝塞爾曲線

這個例子使用多個貝塞爾曲線來渲染對話氣泡。

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    // 二次貝爾賽曲線
    ctx.beginPath();
    ctx.moveTo(75,25);
    ctx.quadraticCurveTo(25,25,25,62.5);
    ctx.quadraticCurveTo(25,100,50,100);
    ctx.quadraticCurveTo(50,120,30,125);
    ctx.quadraticCurveTo(60,120,65,100);
    ctx.quadraticCurveTo(125,100,125,62.5);
    ctx.quadraticCurveTo(125,25,75,25);
    ctx.stroke();
  }
}

二次貝塞爾曲線用例

三次貝塞爾曲線

這個例子使用貝塞爾曲線繪製心形。

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    //三次貝塞爾曲線
    ctx.beginPath();
    ctx.moveTo(75,40);
    ctx.bezierCurveTo(75,37,70,25,50,25);
    ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
    ctx.bezierCurveTo(20,80,40,102,75,120);
    ctx.bezierCurveTo(110,102,130,80,130,62.5);
    ctx.bezierCurveTo(130,62.5,130,25,100,25);
    ctx.bezierCurveTo(85,25,75,37,75,40);
    ctx.fill();
  }
}

三次貝塞爾曲線用例

(根據向同學請教的經驗:貝塞爾曲線是用來畫曲線的,如果你想自己畫哪種曲線的畫,可以把起點終點確定,控制點靠試)

組合使用

這個是MDN上組合使用的例子,教程說實際上很簡單,你們隨意感受下……

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    roundedRect(ctx,12,12,150,150,15);
    roundedRect(ctx,19,19,150,150,9);
    roundedRect(ctx,53,53,49,33,10);
    roundedRect(ctx,53,119,49,16,6);
    roundedRect(ctx,135,53,49,33,10);
    roundedRect(ctx,135,119,25,49,10);

    ctx.beginPath();
    ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);
    ctx.lineTo(31,37);
    ctx.fill();

    for(var i=0;i<8;i++){
      ctx.fillRect(51+i*16,35,4,4);
    }

    for(i=0;i<6;i++){
      ctx.fillRect(115,51+i*16,4,4);
    }

    for(i=0;i<8;i++){
      ctx.fillRect(51+i*16,99,4,4);
    }

    ctx.beginPath();
    ctx.moveTo(83,116);
    ctx.lineTo(83,102);
    ctx.bezierCurveTo(83,94,89,88,97,88);
    ctx.bezierCurveTo(105,88,111,94,111,102);
    ctx.lineTo(111,116);
    ctx.lineTo(106.333,111.333);
    ctx.lineTo(101.666,116);
    ctx.lineTo(97,111.333);
    ctx.lineTo(92.333,116);
    ctx.lineTo(87.666,111.333);
    ctx.lineTo(83,116);
    ctx.fill();

    ctx.fillStyle = "white";
    ctx.beginPath();
    ctx.moveTo(91,96);
    ctx.bezierCurveTo(88,96,87,99,87,101);
    ctx.bezierCurveTo(87,103,88,106,91,106);
    ctx.bezierCurveTo(94,106,95,103,95,101);
    ctx.bezierCurveTo(95,99,94,96,91,96);
    ctx.moveTo(103,96);
    ctx.bezierCurveTo(100,96,99,99,99,101);
    ctx.bezierCurveTo(99,103,100,106,103,106);
    ctx.bezierCurveTo(106,106,107,103,107,101);
    ctx.bezierCurveTo(107,99,106,96,103,96);
    ctx.fill();

    ctx.fillStyle = "black";
    ctx.beginPath();
    ctx.arc(101,102,2,0,Math.PI*2,true);
    ctx.fill();

    ctx.beginPath();
    ctx.arc(89,102,2,0,Math.PI*2,true);
    ctx.fill();
  }
}

// 封裝的一個用於繪製圓角矩形的函數.

function roundedRect(ctx,x,y,width,height,radius){
  ctx.beginPath();
  ctx.moveTo(x,y+radius);
  ctx.lineTo(x,y+height-radius);
  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
  ctx.lineTo(x+width-radius,y+height);
  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
  ctx.lineTo(x+width,y+radius);
  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
  ctx.lineTo(x+radius,y);
  ctx.quadraticCurveTo(x,y,x,y+radius);
  ctx.stroke();
}

這裏寫圖片描述

Path2D 對象

Path2D對象用於記錄圖像,使圖像成爲一個對象,方便之後使用。之前的路徑方法都可以在Path2D中使用。

new Path2D();     // 空的Path對象
new Path2D(path); // 克隆Path對象
new Path2D(d);    // 從SVG建立Path對象

下面是一個Path2D的使用例子:

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    var rectangle = new Path2D();
    rectangle.rect(10, 10, 50, 50);

    var circle = new Path2D();
    circle.moveTo(125, 35);
    circle.arc(100, 35, 25, 0, 2 * Math.PI);

    ctx.stroke(rectangle);
    ctx.fill(circle);
  }
}

Path2D實例

SVG(Scalable Vector Graphics) path

可伸縮向量圖形(Scalable Vector Graphics)是另外一種繪製的方法,操作方法爲定點(Mx y)——水平移動(h x)——下移(v x)——左移(h x)——回到原點(z)。這將存儲爲一個SVG data path 供Path2D使用。例子如下:

var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章