Canvas

Canvas

1.概述

Canvas是HTML5中非常重要的一個(gè)更新亮點(diǎn),畫布薯蝎,替代Flash的!制作動(dòng)畫谤绳、制作游戲占锯。渲染效率非常的高,瀏覽器不需要安裝任何的插件就可以渲染這個(gè)動(dòng)畫缩筛。而Flash需要安裝Flash Player這個(gè)插件才行消略。

Canvas適合動(dòng)態(tài)圖形繪制。小的動(dòng)態(tài)效果也可以使用過渡或動(dòng)畫屬性animation歪脏。

echarts圖表使用Canvas繪制疑俭,https://echarts.apache.org/zh/index.html

1.1. Hello World

canvas是一個(gè)標(biāo)簽粮呢,有一個(gè)默認(rèn)的寬高,此時(shí)注意婿失,如果我們要設(shè)置寬度、高度啄寡,必須設(shè)置在HTML標(biāo)簽上面豪硅,而不能設(shè)置在CSS上。

注意:

  1. canvas本身布具有繪畫功能, 只是一個(gè)畫布標(biāo)簽, 但是H5提供給js的API具有繪畫功能
2.  IE9一下不兼容
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>

<body>
  <canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas挺物,請(qǐng)升級(jí)</canvas>
  <script>
    //僅僅獲取畫布對(duì)象
    let mycanvas = document.getElementById('canvas');
    //通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
    let ctx = mycanvas.getContext('2d');
    //繪制矩形路徑
    ctx.rect(50, 50, 50, 50);//距離畫布左上角50 50  寬高50 50懒浮,只是路徑看不到效果
    //描邊
    ctx.stroke();
    //填充
    // ctx.fill()
  </script>

2. 涉及的API

2.1 getContext()

get表示得到,context是上下文的意思。

canvas起初是空白的砚著。為了展示次伶,首先腳本需要找到渲染上下文,然后在它的上面繪制稽穆。<canvas> 元素有一個(gè)做 getContext() 的方法冠王,這個(gè)方法是用來獲得渲染上下文和它的繪畫功能。getContext()只有一個(gè)參數(shù)舌镶,上下文的格式柱彻。

// 首先獲取canvas 標(biāo)簽的dom對(duì)象
var mycanvas = document.querySelector("canvas");

// 獲取上下文對(duì)象() 參數(shù)是2d繪圖
var ctx = canvas.getContext('2d');

ctx對(duì)象,非常重要所有的繪制都是ctx的方法餐胀。canvas就是畫布,功能就是生產(chǎn)畫筆,

剩下所有的繪制都是有這支畫筆ctx對(duì)象的屬性來操作

//也就是說所有的繪制API都是ctx的事情哟楷,而不是canvas對(duì)象
ctx.fillStyle = "blue";
ctx.arc(300,300,100,0,Math.PI * 2,true);
ctx.fill();

2.2 繪制圓形 arc()

繪制圓形 arc(x,y,r,start, end, bol)

bol,是布爾值, 跟繪制圓弧有關(guān)

ctx.arc(300,300,100,0,Math.PI * 2,true);
<style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
  <script>
    //僅僅獲取畫布對(duì)象
    let mycanvas = document.getElementById('canvas');
    //通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
    let ctx = mycanvas.getContext('2d');
    console.log(ctx);
    //繪制一個(gè)圓
    ctx.arc(200, 200, 100, 0, Math.PI * 2, true);//繪制圓的路徑否灾,圓心位置 圓心位置 半徑 起始為0 終止為Math.PI*2 順時(shí)針繪制
    //描邊后才可以看到邊卖擅,之前只是路徑
    ctx.strokeStyle = 'blue';//改變描邊顏色
    ctx.stroke();
    //改變填充顏色,填充之前定義填充顏色
    ctx.fillStyle = 'red';
    ctx.fill()//填充
  </script>
2.3 繪制矩形 rect()

繪制矩形 rect(x,y,w,h)

ctx.rect(200, 200, 100, 100);
 <script>
    //僅僅獲取畫布對(duì)象
    let mycanvas = document.getElementById('canvas');
    //通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
    let ctx = mycanvas.getContext('2d');
    //繪制矩形路徑
    ctx.rect(50, 50, 50, 50);//距離畫布左上角50 50  寬高50 50墨技,只是路徑看不到效果
    //描邊
    ctx.stroke();
    //填充
    // ctx.fill()
  </script>
2.4 stroke()筆觸

繪制線條

ctx.stroke()
2.5 fill() 填充
ctx.fill()
2.6 可以合在一起寫
  1. strokeRect(x,y,w,h)

  2. fillRect(x,y,w,h)

    參數(shù):

    x,y 為起點(diǎn)的x,y坐標(biāo)

    w,h 為要繪制矩形的寬高

注意沒有strokeArc 和 fillArc 的寫法

    ctx.strokeRect(100,100,200,100)//通過描邊直接把矩形繪制出來
    ctx.fillRect(200,300,200,100)//填充的時(shí)候直接繪制一個(gè)矩形
2.7 清除 clearRect()

清除clearRect(x,y,w,h)

ctx.clearRect(250, 250, 30, 30);
ctx.clearRect(300,300,100,100)

清除在繪制有先后屬性之分

3. 筆觸和填充

Canvas中能夠產(chǎn)生顏色的是兩個(gè)東西磨镶,一個(gè)叫做筆觸(也叫做描邊),一個(gè)叫做填充健提。

3.1. 筆觸(描邊) strokeRect(x,y,w,h)

參數(shù),x,y 左上角起點(diǎn)坐標(biāo),w,h為繪制矩形的寬高

3.1.1 筆觸的使用:
//筆觸
ctx.strokeRect(100,100,300,40);

你會(huì)發(fā)現(xiàn)只有描邊沒有填充色

而我們剛學(xué)的 fillRect() API繪制的矩形是有填充色的

3.1.2 設(shè)置筆觸的顏色
// 設(shè)置筆觸顏色
ctx.strokeStyle = 'red';
// ctx.strokeStyle = 'hsl(250,50%,50%)'
// 繪制筆觸矩形
ctx.strokeRect(100,100,300,50);

此時(shí)你就會(huì)發(fā)現(xiàn)你繪制的是一個(gè)沒有填充色琳猫,只有紅色邊框的矩形

3.1.3 繪制筆觸的寬度
ctx.lineWidth = 20;   // 設(shè)置筆觸的寬為20
    //僅僅獲取畫布對(duì)象
    let mycanvas = document.getElementById('canvas');
    //通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
    let ctx = mycanvas.getContext('2d');
    console.log(ctx);
    //繪制一個(gè)圓
    ctx.arc(200, 200, 100, 0, Math.PI * 2, true);//繪制圓的路徑,圓心位置 圓心位置 半徑 起始為0 終止為Math.PI*2 順時(shí)針繪制
    //描邊后才可以看到邊私痹,之前只是路徑
    ctx.strokeStyle = 'blue';//改變描邊顏色
    ctx.lineWidth =20;
    ctx.stroke();

3.1.4 筆觸繪制線段

劃線之前你的先告訴瀏覽器怎么畫

moveTo() 繪制開始位置 lineTo() 畫筆移動(dòng)的下一個(gè)位置

ctx.moveTo(100,100);    //將畫筆移動(dòng)到一個(gè)位置(先移動(dòng)到開始點(diǎn)的位置)
ctx.lineTo(300,300);    //用畫筆畫脐嫂,此時(shí)是抽象的一個(gè)線,沒有顯示在畫布上(下一個(gè)點(diǎn)的位置)
ctx.stroke();           //劃線(告訴瀏覽器,我說完了,你畫吧)

我們可以多次使用lineTo:

告訴瀏覽器下一個(gè)點(diǎn)的位置,來繪制相鄰點(diǎn)之間的線段

ctx.moveTo(100,100);    // 將畫筆移動(dòng)到一個(gè)位置
ctx.lineTo(300,300);    // 準(zhǔn)備繪制從開始點(diǎn)到這個(gè)點(diǎn)的線紊遵,

ctx.lineTo(300,200);    // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線账千,
ctx.lineTo(430,180);    // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,

ctx.stroke();           // 正式開始劃線 
<body>
  <canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas暗膜,請(qǐng)升級(jí)</canvas>
  <script>
    //僅僅獲取畫布對(duì)象
    let mycanvas = document.getElementById('canvas');
    //通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
    let ctx = mycanvas.getContext('2d');
    ctx.lineWidth = 20;//筆觸寬度
    ctx.strokeStyle='red';
    //繪制線段
    //筆尖不在畫布上moveTo
    ctx.moveTo(100, 100)
    //筆尖落在畫布上lineTo繪制路徑
    ctx.lineTo(200, 200)
    ctx.lineTo(200, 300)
    ctx.lineTo(400, 300)
    //筆觸填充
    ctx.stroke()//繪制
  </script>
</body>
3.1.5 閉合路徑

而且我們還可以使用closePath() ,來閉合路徑

就是瀏覽器會(huì)自動(dòng)的在開始點(diǎn)moveTo的點(diǎn)和最后一個(gè)lineTo的結(jié)束點(diǎn)之間繪制一條線

ctx.beginPath();        // 開始準(zhǔn)備畫線
ctx.moveTo(100,100);    // 將畫筆移動(dòng)到一個(gè)位置
ctx.lineTo(300,300);    // 準(zhǔn)備繪制從開始點(diǎn)到這個(gè)點(diǎn)的線匀奏,
ctx.lineTo(300,200);    // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,
ctx.lineTo(430,180);    // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線学搜,

ctx.closePath();        // 閉合路徑(加上就閉合了)

ctx.stroke();           // 正式開始劃線 

繪制新的線段

<body>
  <canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas娃善,請(qǐng)升級(jí)</canvas>
  <script>
    //僅僅獲取畫布對(duì)象
    let mycanvas = document.getElementById('canvas');
    //通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
    let ctx = mycanvas.getContext('2d');
    ctx.lineWidth = 20;//筆觸寬度
    ctx.strokeStyle = 'red';
    //繪制線段
    //筆尖不在畫布上moveTo
    ctx.moveTo(100, 100)
    //筆尖落在畫布上lineTo繪制路徑
    ctx.lineTo(200, 200)
    //筆觸填充
    ctx.stroke()//繪制
    ctx.moveTo(300, 200)//繪制新的線條
    ctx.lineTo(200, 300)
    ctx.stroke()
  </script>
</body>
3.1.6 繪制新的線條開始(開始新的路徑)

可以使用beginPath() 表示開始一個(gè)新的路徑

ctx.beginPath()
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.stroke()

ctx.beginPath()
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.stroke()

<body>
  <canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
  <script>
    //僅僅獲取畫布對(duì)象
    let mycanvas = document.getElementById('canvas');
    //通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
    let ctx = mycanvas.getContext('2d');
    ctx.lineWidth = 20;//筆觸寬度
    ctx.strokeStyle = 'red';   
    ctx.beginPath()//開始一個(gè)新路徑beginPath() 一段路徑
    ctx.moveTo(100, 100)  
    ctx.lineTo(200, 200)   
    ctx.stroke()
    ctx.beginPath()//開始一個(gè)新路徑beginPath() 一段路徑
    ctx.moveTo(300, 200)
    ctx.lineTo(400, 300)
    ctx.stroke()
  </script>
</body>

可以使用lineWidth屬性設(shè)置線的寬度

ctx.beginPath();        
ctx.moveTo(100,100);    
ctx.lineTo(300,300);    
ctx.lineTo(300,200);    
ctx.lineTo(430,180);    

ctx.strokeStyle = 'red';// 繪制描邊的顏色
ctx.closePath();        // 閉合路徑
ctx.lineWidth = '10';   // 繪制線的寬度
ctx.stroke();   

ctx.filStyle = 'skyblue';// 繪制填充顏色
ctx.fill();             // 繪制填充色  
3.1.7 繪制線條的轉(zhuǎn)角

lineJoin : 邊界連接點(diǎn)樣式瑞佩,要在畫ctx.stroke()之前設(shè)置轉(zhuǎn)角

  1. miter(默認(rèn)值),
  2. round(圓角),
  3. bevel(平角)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);

ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.closePath()
ctx.strokeStyle = 'red';
ctx.lineWidth = 20;
ctx.lineJoin = 'round'
ctx.stroke()
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas聚磺,請(qǐng)升級(jí)</canvas>
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.beginPath();
    ctx.moveTo(100, 100);
    ctx.lineTo(300, 300);
    ctx.lineTo(300, 200);
    ctx.lineTo(430, 180);
    ctx.strokeStyle = 'red';
    ctx.closePath();
    ctx.lineWidth = '10';
    ctx.lineJoin = 'round'//線條轉(zhuǎn)角 
    ctx.stroke();
  </script>
</body>
3.1.8 端點(diǎn)樣式

lineCap: 端點(diǎn)樣式

  1. butt(默認(rèn)值),
  2. round(圓角) (寬度左右兩邊分別多出線高的一半)
  3. square(寬度左右兩邊分別多出線高的一半)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.strokeStyle = 'red';
ctx.lineWidth = 50;
ctx.lineCap = 'round'
ctx.stroke()
    ctx.beginPath();
    ctx.moveTo(490, 100);
    ctx.lineTo(490, 350);
    ctx.strokeStyle = 'blue';
    ctx.lineCap = 'butt'//默認(rèn)
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(450, 100);
    ctx.lineTo(450, 350);
    ctx.strokeStyle = 'blue';
    ctx.lineCap = 'round'//圓角,線段寬度左右兩端分別多出線高的一半
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(410, 100);
    ctx.lineTo(410, 350);
    ctx.strokeStyle = 'blue';
    ctx.lineCap = 'square'//平角炬丸,線段寬度左右兩端分別多出線高的一半
    ctx.stroke();   
3.2. 填充 fill()

還可以是用fill()給閉合路徑后的閉合區(qū)域填充顏色

ctx.beginPath();        // 開始準(zhǔn)備畫線
ctx.moveTo(100,100);    // 將畫筆移動(dòng)到一個(gè)位置
ctx.lineTo(300,300);    // 準(zhǔn)備繪制從開始點(diǎn)到這個(gè)點(diǎn)的線瘫寝,
ctx.lineTo(300,200);    // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,
ctx.lineTo(430,180);    // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,
ctx.closePath();        // 閉合路徑
ctx.stroke();           // 正式開始劃線 

ctx.fill();             // 繪制填充色
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>

<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas焕阿,請(qǐng)升級(jí)</canvas>
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.fillStyle = 'red';
    ctx.lineWidth = 10;

    ctx.moveTo(200, 200);
    ctx.lineTo(200, 400);
    ctx.lineTo(400, 400);
    ctx.lineTo(400, 200);
    // ctx.closePath()閉合路徑的方法之一  筆觸
    // ctx.stroke();
    ctx.fill()//使用填充會(huì)自動(dòng)閉合路徑
  </script>
</body>
3.2.1 繪制填充顏色 fillStyle

strokeStyle 屬性修改描邊顏色

fillStyle 屬性修改填充顏色

ctx.beginPath();        
ctx.moveTo(100,100);    
ctx.lineTo(300,300);    
ctx.lineTo(300,200);    
ctx.lineTo(430,180);    

ctx.strokeStyle = 'red';// 繪制描邊的顏色
ctx.closePath();        // 閉合路徑
ctx.stroke();   

ctx.filStyle = 'skyblue';// 繪制填充顏色
ctx.fill();             // 繪制填充色  

4.弧與圓形

1.1. 繪制弧度及圓形的公式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
參數(shù)
  1. x,y為圓心的坐標(biāo)
  2. radius 為圓形的半徑
  3. startAngle 為弧度的起始位置,0是正x軸的
  4. endAngle 為弧度的終點(diǎn)位置,
  5. anticlockwise 布爾值,true為逆時(shí)針繪制,false為順時(shí)針繪制
注意

canvas中的度數(shù)都是弧度制

弧和圓形也是筆觸(描邊),所以也需要以beginPath()開始

var ctx = mycanvas.getContext('2d');

ctx.beginPath();
ctx.arc(150,150,100,0,2*Math.PI,false);

ctx.arc(200,200,100,0,2,false);

ctx.arc(150,150,100,2,2,false);
ctx.fill();

ctx.beginPath();
ctx.arc(150,150,100,2,0,true);
ctx.strokeStyle= 'red';
ctx.lineWidth = 2;
ctx.stroke();
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>

<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas咪啡,請(qǐng)升級(jí)</canvas>
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');

    ctx.fillStyle = 'red';
    ctx.lineWidth = 10;

    ctx.beginPath();
    ctx.arc(250, 250, 100, 0, Math.PI * 0.5, false);
    ctx.stroke()

    ctx.beginPath();
    ctx.arc(450, 450, 100, Math.PI * 1.5, Math.PI * 0.5, false);
    ctx.stroke()
  </script>
</body>

5. 繪制曲線

5.1. 繪制弧度曲線

arcTo(x1,y1,x2,y2,r)
x1,y1 坐標(biāo)一 x2,y2坐標(biāo)二 r圓弧半徑

ctx.moveTo(100, 300)
ctx.arcTo(100, 100, 200, 100, 50)
ctx.stroke()
 <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.beginPath();
    ctx.lineWidth = 10;
    ctx.strokeStyle = 'red';
    ctx.moveTo(100, 300);
    ctx.arcTo(100, 100, 200, 100, 50);//弧線
    ctx.stroke()

    ctx.beginPath();
    ctx.moveTo(150, 200);
    ctx.arcTo(150, 100, 200, 100, 400);
    ctx.stroke()
  </script>
</body>
5.2. 繪制貝塞爾曲線
繪制公式
ctx.quadraticCurveTo(cp1x,cp1y,x,y)
參數(shù)
  1. cp1x, cp1y 為貝塞爾曲線的控制點(diǎn)
  2. x,y 為繪制曲線的終點(diǎn)
ctx.beginPath()
ctx.moveTo(100,100);
ctx.quadraticCurveTo(200,100,200,200)
ctx.stroke();
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas暮屡,請(qǐng)升級(jí)</canvas>
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.beginPath();
    ctx.lineWidth = 10;
    ctx.strokeStyle = 'red';
    ctx.moveTo(100,100);//起點(diǎn)
    //ctx.lineTo(300,100)//終點(diǎn)
    ctx.quadraticCurveTo(150,400,300,100)//一次貝塞爾曲線瑟匆,貝塞爾控制點(diǎn)(150,400),終點(diǎn)
    ctx.stroke()
5.3. 繪制二次貝塞爾曲線
繪制公式
ctx.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
參數(shù)
  1. cp1x, cp1y 為貝塞爾曲線的第一個(gè)控制點(diǎn)
  2. cp2x, cp3y 為貝塞爾曲線的第二個(gè)控制點(diǎn)
  3. x,y 為繪制曲線的終點(diǎn)
ctx.beginPath()
ctx.moveTo(100,100);
ctx.bezierCurveTo(200,120,50,150,200,200);
ctx.stroke();
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.beginPath();
    ctx.lineWidth = 10;
    ctx.strokeStyle = 'red';
    ctx.moveTo(100,100);//起點(diǎn)
    // ctx.bezierCurveTo(150,100,300,100,500,100)點(diǎn)都在一條線上的貝塞爾曲線
  
    ctx.bezierCurveTo(150,300,300,-50,500,100)//貝塞爾端點(diǎn)一  貝塞爾端點(diǎn)二 終點(diǎn)
    ctx.stroke()   
  </script>

6. canvas變換

6.1. translate(x,y)

坐標(biāo)基準(zhǔn)點(diǎn)偏移 : 從起始點(diǎn)為基準(zhǔn)栽惶,移動(dòng)到當(dāng)前位置

ctx.translate(100, 100)ctx.arc(100, 100, 50, 0, Math.PI * 2, true)ctx.strokeStyle = 'red';ctx.lineWidth = 5;ctx.stroke()
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas愁溜,請(qǐng)升級(jí)</canvas>
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.lineWidth=10;
    ctx.strokeStyle='red';
    
    ctx.translate(100,100);//可以理解為偏移基準(zhǔn)點(diǎn)
    ctx.arc(100, 100,50,0,Math.PI*2,true)//元素位置通過基準(zhǔn)點(diǎn)與參考點(diǎn)配合確定,調(diào)誰都可以
    ctx.stroke();
  </script>
</body>
6.2.rotate(弧度):

旋轉(zhuǎn) 弧度公式 :角度*PI/180

ctx.rotate(Math.PI / 180 * 30)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;

ctx.stroke()
 let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.lineWidth=10;
    ctx.strokeStyle='red';
    ctx.translate(100,100)//基準(zhǔn)點(diǎn)
        ctx.rotate(Math.PI/180 *80);//旋轉(zhuǎn)外厂,弧度值轉(zhuǎn)成角度值
    ctx.strokeRect(0,0,100,100)//參考點(diǎn)在自己中心位置
    ctx.strokeRect(-50,-50,100,100)//參考點(diǎn)在自己中心位置

6.3. scale(wb,hb)

縮放比例(縮放canvas繪制的圖片)

ctx.scale(1.5, 1.5)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;

ctx.stroke()

這里將寬冕象、高、圓心坐標(biāo)等比縮放

  let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.lineWidth=10;
    ctx.strokeStyle='red';
    ctx.scale(1,0.5);//縮放  基準(zhǔn)點(diǎn) 寬 高 線寬都等比例縮放
    ctx.strokeRect(200,200,50,100)

示例:

var can = document.getElementById("canvas");
ctx = can.getContext("2d");

ctx.beginPath();
ctx.translate(160,30);
ctx.fillStyle = "#00ff00";
ctx.fillRect(0,0,100,50);

for (var i=0;i<50 ;i++ ){
    ctx.translate(25,25);
    ctx.scale(0.9,0.9);//縮放汁蝶,針對(duì)后面要繪制的圖形進(jìn)行縮放(在前面繪制的那個(gè)圖形的基礎(chǔ)上進(jìn)行縮放)
    ctx.rotate(Math.PI/10);
    ctx.fillRect(0,0,100,50);
}

7. 保存與恢復(fù)路徑

7.1. 保存路徑 save()

保存之前的路徑狀態(tài)

7.2.恢復(fù)路徑 restore()
ctx.save()
ctx.scale(3, 2)
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 20)
ctx.restore()


ctx.beginPath()
ctx.fillRect(0, 50, 100, 20)

會(huì)封閉一個(gè)獨(dú)立路徑 不會(huì)對(duì)外邊的區(qū)域產(chǎn)生影響

  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      margin: 50px auto;
      background-color: #fff;
    }
  </style>
</head>

<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas渐扮,請(qǐng)升級(jí)</canvas>
  <script>
    let mycanvas = document.getElementById('canvas');
    let ctx = mycanvas.getContext('2d');
    ctx.strokeStyle = 'blue';
    ctx.beginPath();
    ctx.save()//保存之前的的路徑狀態(tài)
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 10;

    ctx.moveTo(100, 100);
    ctx.lineTo(300, 100);
    ctx.stroke()
    ctx.beginPath()
    ctx.restore() //恢復(fù)之前保存的路徑狀態(tài)
    ctx.moveTo(100, 200);
    ctx.lineTo(300, 200);
    ctx.stroke()
  </script>

8 繪制圖片

8.1. 繪制圖片
8.1.1 創(chuàng)建圖片對(duì)象,獲取圖片

圖片預(yù)加載,獲取圖片文件

const img = new Image();
img.src = '../1.jpg'
8.1.2 onload事件,當(dāng)圖片加載完成執(zhí)行繪制
img.onload = function(){}
8.1.3 圖片加載完成后將圖片繪制在畫布上

ctx.drawImage(image, dx, dy, dWidth, dHeight);

繪制圖片(圖片對(duì)象,畫布坐標(biāo)x,畫布坐標(biāo)y,繪制顯示圖片寬度,繪制顯示圖片高度)

const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
    ctx.drawImage(this, 0, 0, 100, 300)
}
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas掖棉,請(qǐng)升級(jí)</canvas>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    //加載圖片
    let img = new Image();//創(chuàng)建圖片對(duì)象
    img.src = './imgs/11.jpg';
    img.onload = function () {//加載就會(huì)觸發(fā)onload事件
      ctx.drawImage(this, 20, 20, 300, 300);//畫圖片
    }
  </script>
</body>
8.1.4 切圖

ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

參數(shù):

  1. image 繪制到上下文的元素

  2. sx 可選

    需要繪制到目標(biāo)上下文中的墓律,image的矩形(裁剪)選擇框的左上角 X 軸坐標(biāo)。

  3. sy 可選

    需要繪制到目標(biāo)上下文中的幔亥,image的矩形(裁剪)選擇框的左上角 Y 軸坐標(biāo)耻讽。

  4. sWidth 可選

    需要繪制到目標(biāo)上下文中的,image的矩形(裁剪)選擇框的寬度帕棉。

  5. sHeight 可選

    需要繪制到目標(biāo)上下文中的针肥,image的矩形(裁剪)選擇框的高度。

  6. dx

    image的左上角在目標(biāo)canvas上 X 軸坐標(biāo)香伴。

  7. dy

    image的左上角在目標(biāo)canvas上 Y 軸坐標(biāo)慰枕。

  8. dWidth 可選

    image在目標(biāo)canvas上繪制的寬度。

  9. dHeight 可選

    image在目標(biāo)canvas上繪制的高度即纲。 允許對(duì)繪制的image進(jìn)行縮放具帮。

const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
    ctx.drawImage(this, 50, 50, 500, 500, 100, 100, 100, 100)
}
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    //加載圖片
    let img = new Image();//創(chuàng)建圖片對(duì)象
    img.src = './imgs/11.jpg';
    img.onload = function () {//加載就會(huì)觸發(fā)onload事件
      ctx.drawImage(this, 20, 20, 300, 300);//畫圖片
      ctx.drawImage(this, 50, 50, 100, 100, 20, 350, 300, 300);//可以做放大鏡
    }
  </script>
</body>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      background-color: #f3f3f3;
    }

    #canvas {
      /*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
      display: block;
      /*變塊才能居中*/
      background-color: #fff;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas低斋,請(qǐng)升級(jí)</canvas>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    //加載圖片
    let img = new Image();//創(chuàng)建圖片對(duì)象
    img.src = './imgs/11.jpg';
    img.onload = function () {//加載就會(huì)觸發(fā)onload事件
      ctx.drawImage(this, 20, 20, 300, 300);//畫圖片
      canvas.onmousemove = function (e) {
        console.log(e);
        let sX = e.clientX - 50;
        let sY = e.clientY - 50;
        ctx.drawImage(img, sX, sY, 100, 100, 20, 350, 300, 300);
      }
    }
  </script>
</body>
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas蜂厅,請(qǐng)升級(jí)</canvas>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    //加載圖片
    let img = new Image();//創(chuàng)建圖片對(duì)象
    img.src = './imgs/11.jpg';
    img.onload = function () {//圖片加載就會(huì)觸發(fā)onload事件
      //創(chuàng)建背景圖片填充資源
      let bg = ctx.createPattern(this, 'repeat')
      ctx.fillStyle = bg;//填充背景資源
      ctx.fillRect(0, 0, 500, 500)//填充一個(gè)矩形
    }
  </script>
</body>
8.2. 填充背景
8.2.1 createPattern(img,平鋪方式)

參數(shù): 平鋪方式:repeat,repeat-x,repeat-y,no-repeat

const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
    const bg = ctx.createPattern(img, 'no-repeat');
    ctx.fillStyle = bg;
    ctx.fillRect(100, 100, 300, 200)
}
8.3. 顏色漸變
8.3.1 線性漸變:createLinearGradient(x1,y1,x2,y2)
x1,y1起始坐標(biāo)點(diǎn)

x2,y2結(jié)束坐標(biāo)點(diǎn)
8.3.2 徑向漸變:createRadialGradient(x1,y1,r1,x2,y2,r2)
x1,y1,r1內(nèi)圓坐標(biāo)及半徑

x2,y2,r2外圓坐標(biāo)及半徑
8.3.3 addColorStop(位置,顏色)
位置:漸變點(diǎn)  0-1之間 可多個(gè)

例子,

線性漸變

let color = ctx.createLinearGradient(0, 0, 500, 500);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')

ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    //加載圖片
    let color = ctx.createLinearGradient(0, 0, 500, 500)//漸變顏色對(duì)象
    color.addColorStop(0, 'red')//添加顏色
    color.addColorStop(.5, 'yellow')
    color.addColorStop(1, 'blue')
    ctx.fillStyle = color;//用漸變顏色填充
    ctx.fillRect(0, 0, 500, 500)
  </script>
</body>

徑向漸變

let color = ctx.createRadialGradient(200, 200, 100, 200, 200, 200);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')

ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas拔稳,請(qǐng)升級(jí)</canvas>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    //加載圖片
    let color = ctx.createRadialGradient(200,200,50,200,200,300)//漸變顏色對(duì)象
    color.addColorStop(0, 'red')//添加顏色
    color.addColorStop(.5, 'yellow')
    color.addColorStop(1, 'blue')
    ctx.fillStyle = color;//用漸變顏色填充
    // ctx.fillRect(0, 0, 500, 500)
    ctx.fillRect(0, 0, 100, 100)
  </script>
</body>

9.繪制文本

9.1. 繪制文本
  1. strokeText(文本,x,y); 繪制空心文本(描邊文字)
  2. fillText(文本,x,y); 繪制實(shí)心文本(填充文字)
  3. font = "font-size font-family" 注:尺寸 字體缺一不可
  4. textAlign = "";文本左右對(duì)齊方式 (參考文字坐標(biāo)點(diǎn)對(duì)齊)
    start center end left right
  5. textBaseline文本上下對(duì)齊方式
    alphabetic 默認(rèn)葛峻。文本基線是普通的字母基線锹雏。
    top 文本基線是 em 方框的頂端巴比。。
    hanging 文本基線是懸掛基線。
    middle 文本基線是 em 方框的正中轻绞。
    ideographic 文本基線是表意基線采记。
    bottom 文本基線是 em 方框的底端。
let str = 'wuwei'
ctx.font = '50px 宋體'
ctx.textAlign = 'center'
ctx.textBaseline = 'top'
ctx.strokeText(str, 100, 100)
ctx.fillText(str, 100, 200)
9.2. 繪制陰影
  1. shadowOffsetX,shadowOffsetY x軸政勃、y軸偏移
  2. shadowBlur 陰影模糊度
  3. shadowColor 陰影顏色
    默認(rèn)顏色:rgba(0,0,0,0)
ctx.shadowOffsetX = '10'
ctx.shadowOffsetY = '10'
ctx.shadowBlur = '3'
ctx.shadowColor = 'red'

案例:

body {
    background-color: #000;
}
canvas {
    display: block;
    margin: 100px auto 0;
    border: 1px solid skyblue;
    background-color: #fff;
}
.box{
    width: 360px;
    margin: 10px auto;
}
input{
    width: 50px;
    height: 20px;
    text-align: center;
}
<canvas width="500" height="500"></canvas>
<div class="box">
    <input type="color" id='colorList'>
    <button id='color'>隨機(jī)顏色</button>
    <input type="text" value='2px' id='storke'>
    <button id='add'>筆觸增加</button>
    <button id='reduce'>筆觸減小</button>
    <button id="clear">清屏</button>
</div>
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');

var strokeColor = '#000000';
var lineWidth = 2;

colorList.onchange = function () {
    strokeColor = colorList.value;
}

color.onclick = function () {
    strokeColor = '#' + Math.random().toString(16).slice(2, 8);
    colorList.value = strokeColor;
}
add.onclick = function () {
    if (lineWidth >= 10) return;
    lineWidth += 2;
    storke.value = lineWidth + 'px'

}
reduce.onclick = function () {
    if (lineWidth <= 2) return;
    lineWidth -= 2;
    storke.value = lineWidth + 'px'
}



canvas.onmousedown = function (ev) {
    ev = ev || window.event;
    var This = this;
    var x = ev.clientX - this.offsetLeft;
    var y = ev.clientY - this.offsetTop;
    ctx.strokeStyle = strokeColor;
    ctx.lineWidth = lineWidth;
    ctx.beginPath();
    ctx.moveTo(x, y);
    document.onmousemove = function (ev) {
        ev = ev || window.event;
        var x = ev.clientX - This.offsetLeft;
        var y = ev.clientY - This.offsetTop;
        ctx.lineTo(x, y);
        ctx.stroke();

    }
    document.onmouseup = function () {
        this.onmousemove = null;
        this.onmouseup = null
    }
}
clear.onclick = function () {
    console.log(1)
    ctx.clearRect(0, 0, 500, 500)

}
<body>
  <canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas唧龄,請(qǐng)升級(jí)</canvas>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    let str = 'hello world';
    ctx.font = '50px 微軟雅黑'
    ctx.textAlign = 'left'
    ctx.textBaseline = 'top'
    ctx.shadowOffsetX = '10'//水平偏移
    ctx.shadowOffsetY = '10'//垂直偏移
    ctx.shadowBlur = '3'//模糊
    ctx.shadowColor = 'red'//顏色
    ctx.strokeText(str, 50, 200)//空心文字

    let str2 = '你好呀';
    ctx.font = '50px 微軟雅黑'
    ctx.textAlign = 'left'
    ctx.textBaseline = 'middle'
    ctx.fillText(str2, 400, 200)//實(shí)心文字
  </script>
</body>

10.API使用總結(jié)

10.1. canvas標(biāo)簽
<canvas width="" height="" id="">
    您的瀏覽器不支持canvas,請(qǐng)更換瀏覽器奸远!
</canvas>

默認(rèn)寬度300px既棺,默認(rèn)高度 150px

10.2. canvas繪圖環(huán)境設(shè)置
getContext("2d"); 目前支持2d繪圖環(huán)境
10.3. 繪圖路徑:
  1. beginPath() :開始路徑
  2. closePath():閉合路徑
  3. moveTo(x,y):將觸筆移動(dòng)到x,y點(diǎn)
  4. lineTo(x,y):繪制到x,y點(diǎn)
  5. stroke(): 觸筆方法 畫線 默認(rèn)為黑色
  6. fill():填充方法
  7. rect(x,y,w,h):矩形路徑
  8. save():保存路徑
  9. restore():恢復(fù)路徑
10.4. 繪制矩形:
  1. fillRect(x,y,w,h) 填充實(shí)心矩形
  2. strokeRect(x,y,w,h) 繪制空心矩形
  3. clearRect(x,y,w,h) 清除矩形選區(qū)
10.5. 設(shè)置繪圖樣式:
  1. fillStyle: 填充顏色
  2. strokeStyle: 觸筆顏色
  3. lineWidth: 觸筆寬度(線寬)
10.6. 圖形邊界樣式:
  1. lineJoin : 邊界連接點(diǎn)樣式
    miter(默認(rèn)值),round(圓角),bevel(斜角)
  2. lineCap: 端點(diǎn)樣式
    butt(默認(rèn)值),round(圓角),square(高度多出線寬一半)
10.7. 繪制圓形:
  1. arc(x,y,r,0,360,false)
    x,y 圓心坐標(biāo)位置
    r 圓半徑
    0,360 從0度到360度 繪制一個(gè)圓形(用弧度公式)
    true/false 逆時(shí)針/順時(shí)針繪圖
10.8. 繪制曲線
  1. arcTo(x1,y1,x2,y2,r)
    x1,y1 坐標(biāo)一 x2,y2坐標(biāo)二 r圓弧半斤
  2. quadraticCurveTo(dx,dy,x1,y1)
    貝塞爾曲線:dx,dy控制點(diǎn) x1,y1結(jié)束坐標(biāo)
  3. bezierCurveTo(dx1,dy1,dx2,dy2,x1,y1)
    貝塞爾曲線:dx1,dy1 控制點(diǎn)一 dx2,dy2控制點(diǎn)二
    x1,y1結(jié)束坐標(biāo)
10.9. canvas變換
  1. translate(x,y)
    坐標(biāo)基準(zhǔn)點(diǎn)偏移 : 從起始點(diǎn)為基準(zhǔn),移動(dòng)到當(dāng)前位置
  2. rotate(弧度): 旋轉(zhuǎn) 弧度公式 :角度*PI/180
  3. scale(wb,hb)縮放比例(縮放canvas繪制的圖片)
10.10. 繪制圖片
  1. 圖片預(yù)加載懒叛,獲取圖片文件
  2. onload事件,監(jiān)聽圖片是否加載完畢,如果加載完畢執(zhí)行第三步
  3. drawImage(img,x,y,w,h);繪制圖片(圖片,坐標(biāo)x,坐標(biāo)y,寬度,高度)
10.11.設(shè)置背景
  1. createPattern(img,平鋪方式)
    平鋪方式:repeat,repeat-x,repeat-y,no-repeat
10.12. 顏色漸變
  1. 線性漸變:createLinearGradient(x1,y1,x2,y2)
    x1,y1起始坐標(biāo)點(diǎn)
    x2,y2結(jié)束坐標(biāo)點(diǎn)
  2. 徑向漸變:createRadialGradient(x1,y1,r1,x2,y2,r2)
    x1,y1,r1內(nèi)圓坐標(biāo)及半徑
    x2,y2,r2外圓坐標(biāo)及半徑
  3. addColorStop(位置,顏色)
    位置:漸變點(diǎn) 0-1之間 可多個(gè)
10.13. 繪制文本
  1. strokeText(文本,x,y); 繪制空心文本
  2. fillText(文本,x,y); 繪制實(shí)心文本
  3. font = "font-size font-family" 注:尺寸 字體缺一不可
  4. textAlign = "";文本左右對(duì)齊方式
    start center end left right
  5. textBaseline文本上下對(duì)齊方式
    alphabetic 默認(rèn)丸冕。文本基線是普通的字母基線。
    top 文本基線是 em 方框的頂端薛窥。胖烛。
    hanging 文本基線是懸掛基線。
    middle 文本基線是 em 方框的正中诅迷。
    ideographic 文本基線是表意基線佩番。
    bottom 文本基線是 em 方框的底端。
10.14. 陰影
  1. shadowOffsetX,shadowOffsetY x軸罢杉、y軸偏移
  2. shadowBlur 陰影模糊度
  3. shadowColor 陰影顏色
  4. 默認(rèn)顏色:rgba(0,0,0,0)
畫板例子
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      background-color: #000;
    }

    canvas {
      display: block;
      margin: 10px auto 0;
      border: 1px solid skyblue;
      background-color: #fff;
    }

    .box {
      width: 500px;
      margin: 10px auto;
    }

    input {
      width: 50px;
      height: 20px;
      text-align: center;
    }
  </style>
</head>
<body>
  <canvas width="600" height="400"></canvas>
  <div class="box">
    <input type="color" id='colorList'>
    <!--type類型為color表示顏色選擇器 -->
    <button id='color'>隨機(jī)顏色</button>
    <input type="text" value='2px' id='storke' disabled> <!-- input 的阻止頁面上手動(dòng)編輯 disabled -->

    <button id='add'>筆觸增加</button>
    <button id='reduce'>筆觸減小</button>
    <button id="clear">清屏</button>
  </div>
  <script>
    //獲取canvas
    let canvas = document.getElementsByTagName('canvas')[0];
    // 獲取上下文對(duì)象(畫筆)
    let ctx = canvas.getContext('2d');
    //信號(hào)量 定義初始畫筆的顏色和大小
    let strokeColor = '#000000';//筆觸顏色信號(hào)量
    let lineWidth = 2;//筆觸大小信號(hào)量
    //清屏
    clear.onclock = function () {
      ctx.clearRECT(0, 0, 600, 400)
    }
    // 顏色選擇
    colorList.onchange = function () {
      strokeColor = this.value;
    }
    //隨機(jī)顏色
    color.onclick = function () {
      strokeColor = '#' + Math.random().toString(16).substr(2, 6);
      colorList.value = strokeColor//滑條顏色與隨機(jī)顏色保持一致
    }
    //加減筆觸
    add.onclick = function () {
      lineWidth += 2;      //畫筆值與頁面顯示保持一致
      storke.value = lineWidth + 'px';
    }
    reduce.onclick = function () {
      lineWidth -= 2;
      storke.value = lineWidth + 'px';
    }
    //繪制
    canvas.onmousedown = function (ev) {
      ev = ev || window.event//事件對(duì)象做兼容
      //獲取鼠標(biāo)按下時(shí)距離畫布左上端點(diǎn)的距離 x 有
      let x = ev.clientX - this.offsetLeft;//事件對(duì)象距離瀏覽器左邊的距離減去canvas距離瀏覽器左邊的距離
      let y = ev.clientY - this.offsetTop;
      //繪制
      ctx.strokeStyle = strokeColor;
      ctx.lineWidth = lineWidth;
      //開啟新路徑
      ctx.beginPath();
      ctx.moveTo(x, y);//鼠標(biāo)按下 繪制的坐標(biāo)就移動(dòng)到x y位置

      document.onmousemove = function (ev) {
        //使用外部this方法一 let This = this;定義一個(gè)大This趟畏,將外部this傳給里面的This
        //使用外部this方法二 .bind(this)
        //使用外部this方法三 箭頭函數(shù) (ev)=>{} 箭頭函數(shù)沒有this,只能向上找this
        ev = ev || window.event;
        let x = ev.clientX - this.offsetLeft;
        let y = ev.clientY - this.offsetTop;
        ctx.lineTo(x, y);
        ctx.stroke();
      }.bind(this)
      //現(xiàn)在的線段是由鼠標(biāo)拖出來的
      document.onmouseup = function () {//清理事件滩租。鼠標(biāo)抬起說明畫完了拱镐,清理默認(rèn)事件.onmousedown事件是入口不清理
        this.onmousemove = null;
        this.onmouseup = null;
      }
    }
  </script>
</body>

</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市持际,隨后出現(xiàn)的幾起案子沃琅,更是在濱河造成了極大的恐慌,老刑警劉巖蜘欲,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件益眉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡姥份,警方通過查閱死者的電腦和手機(jī)郭脂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澈歉,“玉大人展鸡,你說我怎么就攤上這事“D眩” “怎么了莹弊?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵涤久,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我忍弛,道長(zhǎng)响迂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任细疚,我火速辦了婚禮蔗彤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疯兼。我一直安慰自己然遏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布吧彪。 她就那樣靜靜地躺著啦鸣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪来氧。 梳的紋絲不亂的頭發(fā)上诫给,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音啦扬,去河邊找鬼中狂。 笑死扑毡,一個(gè)胖子當(dāng)著我的面吹牛勋又,可吹牛的內(nèi)容都是我干的楔壤。 我是一名探鬼主播蹲嚣,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了言询?” 一聲冷哼從身側(cè)響起倍试,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤县习,失蹤者是張志新(化名)和其女友劉穎躁愿,沒想到半個(gè)月后沪蓬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跷叉,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡梆砸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年沸枯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绑榴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缔逛。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡褐奴,死狀恐怖于毙,靈堂內(nèi)的尸體忽然破棺而出敦冬,到底是詐尸還是另有隱情唯沮,我是刑警寧澤堪遂,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布萌庆,位于F島的核電站溶褪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏践险。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦搔啊、人聲如沸坯癣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惩猫。三九已至,卻和暖如春蚜点,著一層夾襖步出監(jiān)牢的瞬間轧房,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工绍绘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奶镶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓陪拘,卻偏偏與公主長(zhǎng)得像厂镇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子左刽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Canvas是什么捺信,可以用來做什么 HTML中的 元素通常用于中Web頁面上繪圖 是一個(gè)容器,其中的圖像需要使用J...
    qlcola閱讀 824評(píng)論 0 0
  • ECharts欠痴,一個(gè)使用 JavaScript 實(shí)現(xiàn)的開源可視化庫迄靠,可以流暢的運(yùn)行在 PC 和移動(dòng)設(shè)備上秒咨,兼容當(dāng)前...
    程序員小白養(yǎng)成記閱讀 7,428評(píng)論 0 2
  • fabric.js簡(jiǎn)介 眾所周知,canvas的api繁雜掌挚,對(duì)一般的前端er來說不太友好雨席,加上平時(shí)一般也不會(huì)自己手...
    韭菜的故事閱讀 9,512評(píng)論 4 3
  • 一:canvas簡(jiǎn)介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,683評(píng)論 2 32
  • 一吠式、canvas簡(jiǎn)介 1.1 什么是canvas陡厘?(了解) 是HTML5提供的一種新標(biāo)簽 Canvas是一個(gè)矩形區(qū)...
    Looog閱讀 3,942評(píng)論 3 40