一篇文章掌握常見的canvas屬性和前端使用canvas完成的常見功能

一、什麼是canvas?

h5新增屬性,使用js畫圖功能

二、如何使用canvas?

2.1 創建畫布

一個畫布在網頁中是一個矩形框,通過 元素來繪製,標籤通常需要指定一個id屬性 (腳本中經常引用), width 和 height 屬性定義的畫布的大小, 默認情況下 <canvas> 元素沒有邊框和內容。

<canvas id="myCanvas" width="500" height="150" style="border: 1px solid red"></canvas>

2.2 使用js-api繪製圖形

首先,找到 <canvas> 元素;然後,創建 context 對象;最後,調相應API;

var c = document.getElementById('myCanvas')
var cvsCtx = c.getContext('2d')
//繪製圖形
cvsCtx.fillStyle = "pink";

getContext("2d") 對象是內建的 HTML5 對象,擁有多種繪製路徑、矩形、圓形、字符以及添加圖像的方法。
附:部分2d的相關API
(本來準備整理完的,但是好麻煩啊,遂卒。。一起來站在巨人肩上,直接參考:MDN中的canvas文檔

繪製類型 API 效果 使用方式
矩形 fillRect(x, y, width, height) 實心矩形 cvsCtx.fillRect(0, 0, 150, 75);
矩形 strokeRect(x, y, width, height) 矩形邊框 cvsCtx.strokeRect(0, 0, 150, 75);
矩形 clearRect(x, y, width, height) 清除範圍內的所有矩形 cvsCtx.clearRect(0, 0, 150, 75);
文字 fillText(‘Text’, x軸起始, y軸結束, [max-width]) 實心文字 cvsCtx.fillText(‘第一個字體’, , 10);
文字 strokeText(‘Text’, x軸起始, y軸結束 [max-width]) 虛心文字 cvsCtx.strokeText(‘第一個字體’, 0, 20);
文字 measureText(‘Text’) 測量文字長度,返回文本尺寸對象 var data = cvsCtx.measureText(‘第一個字體’);
字體樣式 .font = ‘[style], [weight,] size, family’; 文字樣式,默認“10px sans-serif ” cvsCtx.font = ‘bold 48px serif’;
字體樣式 .textAlign =“left”/ “right” /“center”/ “start(默認)”/“end”; 水平對齊方式(基線爲準) cvsCtx.textAlign = ‘center’;
字體樣式 .direction=“ltl”/ “rtl” /“inherit”(默認)" 向左對齊/右對齊/繼承 cvsCtx.direction = ‘rtl’
內部樣式 .fillStyle = “#f00/pink”; 內部形狀的顏色,可以是16位rgb,也可以是字符串,默認爲#000 cvsCtx.fillStyle = “pink”;
邊框樣式 .strokeStyle = “#f00/pink”; 形狀邊框的顏色,可以是16位rgb,也可以是字符串,默認爲#000 cvsCtx.strokeStyle = “pink”;

注意點:

  1. x與y指定了在canvas畫布上所繪製的矩形的左上角(相對於原點)的座標。width和height設置矩形的尺寸。
  2. 參數中使用方括號[…]:代表可選參數

三、canvas基礎練習

3.1使用canvas繪製矩形

在這裏插入圖片描述

<canvas id="myCanvas" width="800" height="200" style="border: 1px solid red"></canvas>
<script>
    var c = document.getElementById('myCanvas')
    var cvsCtx = c.getContext('2d')
    // 繪製實心矩形(起始橫座標,起始縱座標,寬,高)
    cvsCtx.fillStyle = "pink";
    cvsCtx.strokeStyle = "blue";
    cvsCtx.fillRect(0, 0, 150, 75);
    // 繪製虛心矩形(起始橫座標,起始縱座標,寬,高)
    cvsCtx.strokeRect(100, 10, 150, 80);
    // 清除
    // cvsCtx.clearRect(0, 0, 200, 100);
</script>

3.2使用canvas寫字

在這裏插入圖片描述

<canvas id="myCanvas" width="800" height="200" style="border: 1px solid red"></canvas>
<script>
    var c = document.getElementById('myCanvas')
    var cvsCtx = c.getContext('2d')
    // 繪製填充文字(文字,起始橫座標,起始縱座標),樣式要寫在前面,不然不起作用
    cvsCtx.font = '50px serif';
    cvsCtx.fillStyle = "pink";
    cvsCtx.textBaseline = 'top';
    cvsCtx.direction = 'rtl'
    cvsCtx.fillText('實線', 130, 60);
    cvsCtx.strokeText('虛線', 200, 10);
    // measureText--查詢字段信息
    // var metrics = cvsCtx.measureText('第一個canvas');
    // console.log(metrics);
</script>

3.3 使用canvas畫線組成一個三角形

在這裏插入圖片描述

<canvas id="myCanvas" width="800" height="200" style="border: 1px solid red"></canvas>
<script>
    var c = document.getElementById('myCanvas')
    var cvsCtx = c.getContext('2d')
    // 繪製顏色
    cvsCtx.strokeStyle = "pink";
    // 繪製寬度
    cvsCtx.lineWidth = 10;
    // 清空之前的路徑新建路徑
    cvsCtx.beginPath();
    // 起點
    cvsCtx.moveTo(20, 20);
    // 終點
    cvsCtx.lineTo(200, 20);
    // 拐點1
    cvsCtx.lineTo(100, 100);
    cvsCtx.lineTo(16, 16);
    // 將線回到起點重新開始
    cvsCtx.closePath();
    cvsCtx.lineTo(400, 100);
    //  進行線的着色,這時整條線才變得可見
    cvsCtx.stroke();

</script>

3.4 使用canvas畫個圓(西瓜)

在這裏插入圖片描述

<canvas id="myCanvas" width="800" height="200" style="border: 1px solid red"></canvas>
<script>
    var c = document.getElementById('myCanvas')
    var cvsCtx = c.getContext('2d')
    // 繪製樣式
    cvsCtx.strokeStyle = "red";
    cvsCtx.fillStyle = "chartreuse";
    cvsCtx.lineWidth = 10;
    cvsCtx.beginPath();
    // cvsCtx.arc(圓心x, 圓心y, 半徑, 弧度開始(正右爲0), 弧度結束(1 * Math.PI = 180°), [false]/是否爲逆時針);
    cvsCtx.arc(100, 100, 50, 0, 1 * Math.PI, false);
    //  邊框着色
    cvsCtx.stroke();
    // 內部着色
    cvsCtx.fill();
</script>

3.5 使用canvas畫個弧線

在這裏插入圖片描述

<canvas id="myCanvas" width="800" height="200" style="border: 1px solid red"></canvas>
<script>
    var c = document.getElementById('myCanvas')
    var cvsCtx = c.getContext('2d')
    // 繪製樣式
    cvsCtx.strokeStyle = "red";
    cvsCtx.lineWidth = 5;
    // 畫線開始
    cvsCtx.beginPath();
    cvsCtx.moveTo(230, 30);
    cvsCtx.arcTo(0, 150, 50, 50, 0);
    cvsCtx.lineTo(50, 50);
    //  邊框着色
    cvsCtx.stroke();
    // 曲線二
    cvsCtx.beginPath();
    cvsCtx.strokeStyle = "pink";
    cvsCtx.moveTo(230, 30);
    cvsCtx.arcTo(350, 150, 450, 50, 90);
    cvsCtx.lineTo(450, 50);
    cvsCtx.stroke();
</script>

根據代碼理解一下曲線屬性.arcTo(x1, y1, x2, y2, 半徑),紅色爲曲線一,粉色爲曲線二,灰虛線爲輔助理解線;

曲線一從點(230, 30)開始到 點(0, 150),最終到點(50,50),畫了一個半徑爲0的圓!
曲線二從點(230, 30)開始到 點(350, 150),最終到點(450,50),畫一個半徑爲50px的圓,曲線二與兩個虛線線段相切。
.arcTo(x1, y1, x2, y2, 半徑)中的(x1,y1)就是這兩個切線的頂點,這個屬性目的是使這三個點過度平滑。

3.6 使用canvas畫個橢圓

在這裏插入圖片描述

<canvas id="myCanvas" width="800" height="200" style="border: 1px solid red"></canvas>
<script>
    var c = document.getElementById('myCanvas')
    var cvsCtx = c.getContext('2d')
    // 繪製樣式
    cvsCtx.strokeStyle = "red";
    cvsCtx.lineWidth = 5;
    // 畫線開始
    cvsCtx.beginPath();
    // cvsCtx.ellipse(圓心x, 圓心Y, 主軸半徑, 短軸半徑, 旋轉角度, 開始角度, 結束角度,[是否逆時針]);
    cvsCtx.ellipse(100, 100, 50, 75, Math.PI / 4, 0, 2 * Math.PI);
    cvsCtx.stroke();
</script>

3.7 使用canvas畫個圖片或切割圖片

在這裏插入圖片描述
頭像爲例,把眼睛部分單獨截取出來放置到canvas裏~這裏圖片失真了就可以看出來,canvas是和像素有關的!

<img id="myImg" src="img/img.jpg">
<canvas id="myCanvas" width="500" height="200" style="border: 1px solid red"></canvas>
 
<script>
    var c = document.getElementById('myCanvas')
    var img = document.getElementById('myImg')
    var cvsCtx = c.getContext('2d')
    img.onload = function () {
		// cvsCtx.drawImage(圖片,[源圖片截取x,起始y,截取寬度w,截取高度h],目標x, 目標y, [放置Width, 放置Height]);
		// 設置圖片像素 low/high/medium
		cvsCtx.imageSmoothingQuality = 'high';
        cvsCtx.drawImage(img, 50, 10, 100, 60, 10, 10, 480, 180);
    }
</script>

3.8 合併圖層——使用canvas完成彩色背景鏤空文字

上面的練習只是單純的畫出圖,但是實際運用的時候可能會有一層疊在一層的情況,這裏練習一下合併圖層。

代碼:

<img id="myImg" src="img/img.jpg">
<canvas id="myCanvas" width="500" height="200" style="border: 1px solid red"></canvas>
<script>
    var c = document.getElementById('myCanvas')
    var cvsCtx = c.getContext('2d')
    cvsCtx.fillStyle = 'blue';
    cvsCtx.fillRect(130, 25, 300, 150);
    cvsCtx.globalCompositeOperation = type;
    cvsCtx.font = '150px serif';
    cvsCtx.fillStyle = 'red';
    cvsCtx.fillText('JCat', 60, 150);
</script>

這裏粉色代表canvas畫布,藍色代表圖層1,紅色字代表圖層2,頭像是圖片,因爲對canvas使用了定位,所以畫布在頭像上,因爲globalCompositeOperation屬性代表將一個新圖層(源圖像)放置到已有的(目標圖像)圖層,其相關參數專門說明一下:

  • source-over默認值:在目標圖像上顯示源圖像。
    在這裏插入圖片描述
  • source-in:在目標圖像中顯示源圖像。只顯示目標圖像內的源圖像的部分,目標圖像不顯示。
    在這裏插入圖片描述
  • source-atop:在目標圖像上顯示源圖像重合的部分。
    在這裏插入圖片描述
  • source-out:在目標圖像之外顯示源圖像。只會顯示目標圖像之外源圖像部分,目標圖像是透明的。
    在這裏插入圖片描述
  • destination-over:在源圖像上方顯示目標圖像。
    在這裏插入圖片描述
  • destination-atop:在源圖像頂部顯示目標圖像。源圖像之外的目標圖像部分不會被顯示。
    在這裏插入圖片描述
  • destination-in: 在源圖像中顯示目標圖像。只有源圖像內的目標圖像部分會被顯示,源圖像是透明的。
    在這裏插入圖片描述
  • destination-out:在源圖像外顯示目標圖像。只有源圖像外的目標圖像部分會被顯示,源圖像是透明的。
    在這裏插入圖片描述
  • lighter:這個值與順序無關,如果源與目標重疊,就將兩者的顏色值相加(紅+藍=紫cat)。如果得到的顏色值的最大取值爲255,重疊部分就爲白色。
    在這裏插入圖片描述
  • copy:只繪製源圖像,忽略目標圖像。
    在這裏插入圖片描述
  • xor:這個值與順序無關,只繪製出不重疊的源與目標區域。所有重疊的部分都變成透明。
    在這裏插入圖片描述

3.9 使用canvas做視頻!

在這裏插入圖片描述
同步更新的視頻,同樣使用的是drawImage屬性

<!DOCTYPE html>
<html>

    <body>
        <p>要使用的視頻:</p>
        <video id="video1" controls width="270" autoplay src="sintel.mp4"></video>
        <p>畫布(每 20 毫秒,代碼就會繪製視頻的當前幀):</p>

        <canvas id="myCanvas" width="270" height="135"></canvas>
    </body>
    <script>
        var avi = document.getElementById("video1");
        var c = document.getElementById("myCanvas");
        ctx = c.getContext('2d');

        avi.addEventListener('play', function() {
            var i = window.setInterval(function() {
                ctx.drawImage(avi, 0, 0, 270, 135)
            }, 20);
        }, false);
    </script>

</html>

四、canvas進化——隨機驗證碼功能

在這裏插入圖片描述
隨機生成6位驗證碼,點擊看不清換一張更換。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>demo</title>
  </head>
  <body>
  <canvas id="canvas" width="200" height="80"></canvas>
  <a href="#" id="changeImg">看不清,換一張</a>
  <script>
    /**生成一個隨機數**/
    function randomNum(min,max){
      return Math.floor( Math.random()*(max-min)+min);
    }
    /**生成一個隨機色**/
    function randomColor(min,max){
      var r = randomNum(min,max);
      var g = randomNum(min,max);
      var b = randomNum(min,max);
      return "rgb("+r+","+g+","+b+")";
    }
    drawPic();
    document.getElementById("changeImg").onclick = function(e){
      e.preventDefault();
      drawPic();
    }
 
    /**繪製驗證碼圖片**/
    function drawPic(){
      var canvas=document.getElementById("canvas");
      var width=canvas.width;
      var height=canvas.height;
      var ctx = canvas.getContext('2d');
      ctx.textBaseline = 'bottom';
 
      /**繪製背景色**/
      ctx.fillStyle = randomColor(180,240); //顏色若太深可能導致看不清
      ctx.fillRect(0,0,width,height);
      /**繪製文字**/
      var str = 'ABCEFGHJKLMNPQRSTWXY123456789';
      for(var i=0; i<6; i++){
        var txt = str[randomNum(0,str.length)];
        ctx.fillStyle = randomColor(50,160);  //隨機生成字體顏色
        ctx.font = randomNum(30,45)+'px SimHei'; //隨機生成字體大小
        var x = 10+i*25;
        var y = randomNum(25,45);
        var deg = randomNum(-45, 45);
        //修改座標原點和旋轉角度
        ctx.translate(x,y);
        ctx.rotate(deg*Math.PI/180);
        ctx.fillText(txt, 10,20);
        //恢復座標原點和旋轉角度
        ctx.rotate(-deg*Math.PI/180);
        ctx.translate(-x,-y);
      }
      /**繪製干擾線**/
      for(var i=0; i<8; i++){
        ctx.strokeStyle = randomColor(40,180);
        ctx.beginPath();
        ctx.moveTo( randomNum(0,width), randomNum(0,height) );
        ctx.lineTo( randomNum(0,width), randomNum(0,height) );
        ctx.stroke();
      }
      /**繪製干擾點**/
      for(var i=0; i<100; i++){
        ctx.fillStyle = randomColor(0,255);
        ctx.beginPath();
        ctx.arc(randomNum(0,width),randomNum(0,height), 1, 0, 2*Math.PI);
        ctx.fill();
      }
    }
  </script>
  </body>
</html>

五、canvas超進化 —— 實現一個刮刮樂的效果!

在這裏插入圖片描述

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>使用canvas做視頻</title>
  <style>
    #canvas {
      border: 1px solid red;
      background: url('./img/img.jpg') repeat;
      background-size: cover;
    }
  </style>
</head>

<body>
  <canvas id="canvas" width="500" height="400"></canvas>
  <script>
    // 繪製一張畫布
    var c = document.getElementById('canvas')
    var cvsCtx = c.getContext('2d')
    // 首先畫一個灰色蒙版
    cvsCtx.fillStyle = '#eee';
    cvsCtx.fillRect(0, 0, 500, 400);
    // 給鼠標經過綁定事件
    c.onmousemove = function (e) {
      // 座標爲:鼠標座標-canvas相對body左邊緣距離
      let x = e.pageX - c.offsetLeft;
      let y = e.pageY - c.offsetTop;
      // 使用合併圖層--destination-out 只有源圖像外的目標圖像部分會被顯示,源圖像是透明的。
      cvsCtx.globalCompositeOperation = 'destination-out';
      // 設置源目標消除點
      cvsCtx.arc(x, y, 20, 0, 360, false);
      cvsCtx.fill();
      cvsCtx.closePath();
    }
  </script>
</body>

</html>

六、canvas究極進化——完成拖動方塊校驗功能!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章