canvas

小莊hua發表於2020-07-11

canvas

在渲染複雜的動效,把資料視覺化圖形顯示,遊戲場景等需求,都會用canvas技術,比dom操作效能更高

特點:

1.h5的新增圖形標籤,通過提供的javaScript函式繪製各種圖表或利用演算法是吸納非常華麗的動效

2,在以前是用flash實現,但不能和js互動

3,適合動態圖形繪製

缺點

是點陣圖,縮放會模糊。

svg意為可縮放向量圖形(Scalable Vector Graphics)。

  • SVG 指可伸縮向量圖形 (Scalable Vector Graphics)

  • SVG 用來定義用於網路的基於向量的圖形

  • SVG 使用 XML 格式定義圖形

  • SVG 影像在放大或改變尺寸的情況下其圖形質量不會有所損失

  • SVG 是全球資訊網聯盟的標準

  • SVG 與諸如 DOM 和 XSL 之類的 W3C 標準是一個整體

canvas:

預設的畫布是300*150;

<canvas width="500" height="500"></canvas>
<script>
    const oC=document.getElementsByTagName("canvas")[0];
    let ctx=oC.getContext("2d");//規定在2d的環境下;
    //繪製矩形
    // ctx.rect(100,100,200,200);
    //前面兩個值指的是二維座標,後面兩個值指的是寬度和高度;
    // ctx.stroke();
    // ctx.fill();
    // ctx.fillRect(100,100,200,200);複合寫法,相當於ctx.fill();和ctx.rect(100,100,200,200);的複合寫法;
    ctx.strokeRect(100,100,200,200);//同上原理。
    ctx.clearRect(100,100,50,50);

</script>
  • 繪製矩形:

    • rect(x,y,w,h) 繪製矩形,前兩個數值是二維座標,後兩個是寬度和高度。

    • fillRect(x,y,w,h)繪製填充實心矩形;

    • strokeRect(x,y,w,h)繪製空心矩形;

    • clearRect(x,y,w,h)清除矩形選區; 清除矩形,前兩個數值是二維座標,後兩個是寬度和高度。

  • 繪製方式

    • stroke() 以邊框線的方式繪製圖形,預設填充黑色。

    • fill( ) 以填充的方式繪製圖形,預設填充黑色。

  • 繪製樣式屬性

    • fillStyle 填充顏色

      ctx.fillStyle="rgba(255,255,0,.5)";//要寫在畫之前才會生效
      ctx.strokeRect(100,100,200,200);//同上原理。
      ctx.clearRect(100,100,50,50);
      
    • strokeStyle 觸筆顏色

      ctx.strokeStyle="hsl(255,50%,50%)";
      ctx.strokeRect(100,100,50,50);
      
      • 關於HSL

        HSL是一種將RGB色彩模型中的點在圓柱座標系中的表示法。這兩種表示法試圖做到比基於笛卡爾座標系的幾何結構RGB更加直觀。

        HSL即色相、飽和度、亮度(英語:Hue, Saturation, Lightness)。

        色相(H)是色彩的基本屬性,就是平常所說的顏色名稱,如紅色、黃色等。

        飽和度(S)是指色彩的純度,越高色彩越純,低則逐漸變灰,取0-100%的數值。

        明度(V),亮度(L),取0-100%。

    • lineWidth 觸筆粗細(線寬)

       ctx.lineWidth=10;
      
  • 繪製線條

    • moveTo(x,y); 從x,y開始繪製;
    • lineTo(x,y);繪製到x,y;
  • 注意

    <style>
        canvas{
            border:3px solid greenyellow;
            width: 1000px;
            height: 1000px;
        }
    </style>
    <body>
        <canvas width="500" height="500"></canvas>
    </body>
    <script>
    	const oC=document.getElementsByTagName("canvas")[0];
        let ctx=oC.getContext("2d");//規定在2d的環境下;
    	ctx.strokeRect(100,100,50,50);
    </script>
    

    此時在css內聯樣式中(style)將寬高度改變為canvas的二倍。此時,ctx.strokeRect(100,100,50,50);的前兩個屬性會擴大為二倍。及二維座標是從(200,200)開始的。

  • 圖形路徑

    • beginPath() 開始路徑

    • closePath() 結束路徑

<style>
    canvas{
        border:3px solid greenyellow;
        width: 1000px;
        height: 1000px;
    }
</style>
<body>
    <canvas width="500" height="500"></canvas>
</body>
<script>
    const oC=document.getElementsByTagName("canvas")[0];
    let ctx=oC.getContext("2d");//規定在2d的環境下;
    ctx.lineWidth=10;
   ctx.beginPath();
   ctx.moveTo(100,100);
   ctx.lineTo(200,200);
   ctx.lineTo(300,100);
   ctx.lineTo(100,100);
   ctx.closePath();
   ctx.stroke()

</script>
  • 圖形邊界樣式屬性

    lineJoin 邊界連線點樣式

    ​ miter (預設值)

    ​ round(圓角)

    ​ bevel(斜角)

            const oC=document.getElementsByTagName("canvas")[0];
            let ctx=oC.getContext("2d");//規定在2d的環境下;
            ctx.lineWidth=10;
            ctx.lineJoin="round";
            ctx.lineJoin="bevel";
           ctx.beginPath();
           ctx.moveTo(100,50);
           ctx.lineTo(200,50);
           ctx.lineTo(150,150);
           ctx.closePath();
           ctx.stroke()
    

    lineCap 端點樣式

    ​ butt(預設值)

    ​ round(圓角)

    ​ square(高度多出線寬一半)

    const oC=document.getElementsByTagName("canvas")[0];
        let ctx=oC.getContext("2d");//規定在2d的環境下;
        ctx.lineWidth=15;
        ctx.strokeStyle="lightgreen";
        ctx.moveTo(200,50);
        ctx.lineTo(200,200);
        ctx.stroke();
    
        ctx.beginPath();
        ctx.lineCap="round";
        ctx.moveTo(300,50);
        ctx.lineTo(300,200);
        ctx.stroke();
    

  • 三角函式

    • 1角度=1*Math.PI/180弧度。

    • 1弧度=1*180/Math.PI 角度

      arc(x,y,r,0,360,false)

      x,y圓心座標位置

      r圓半徑

      0,360從0度到360度所對應的弧度(弧度:角度值*Math.PI/180)

      true/false逆時針/順時針繪圖

獨立路徑 不影響上下文路徑

​ save() 儲存路徑

​ restore() 恢復路徑

小例子:用canvas畫出一張圖片

<canvas width='500' height='500'></canvas>

let oC=document.getElementByTagName('canvas')[0];
let ctx=oC.getContext('2d');
let img=new Image();
img.src='./1.jpg';
img.onload=function(){
    ctx.drawImage(img,100,100,400,200);
}

引入視訊

<video src='./f117bb.mp4' width='400' controls></video>
<canvas width='500' height='500'></canvas>

let oC=document.getElementByTagName('canvas')[0];
let ctx=oC.getContext('2d');
let video=document.getElementByTagName('video')[0];

play()
function play(){
    ctx.drawImage(video,0,0,500,500);
    requestAnimationFrame(play);
}

圖片平鋪

<canvas width='500' height='500'></canvas>

let oC=document.getElementByTagName('canvas')[0];
let ctx=oC.getContext('2d');
let img=new Image();
img.src='./1.jpg';
img.onload=function(){
	let bgi=ctx.creatPattern(img,'no-repeat');
	ctx.fillStyle=bgi;
    ctx.fillRect(0,0,500,500);
}

顏色漸變

線性漸變:createLinearGradient(x1,y1,x2,y2)

​ x1,y1起始座標點

​ x2,y2結束座標點

徑向漸變:creatRadialGradient(x1,y1,r1,x2,y2,r2)

​ x1,y1,r1內圓座標及半徑

​ x2,y2,r2外圓座標及半徑

addColorStop(位置,顏色)

​ 位置:漸變點 0-1之間 可多個

線性漸變例子:

 	let oC=document.getElementsByTagName('canvas')[0];
    let ctx=oC.getContext('2d');
    let color=ctx.createLinearGradient(0,0,500,500);
    color.addColorStop(.2,'green');
    color.addColorStop(.4,'orange');
    color.addColorStop(1,'pink');
    ctx.fillStyle=color;
    ctx.fillRect(0,0,500,500);

徑向漸變例子:

	let oC=document.getElementsByTagName('canvas')[0];
    let ctx=oC.getContext('2d');
    let color=ctx.createRadialGradient(250,250,30,250,250,150);
    color.addColorStop(.2,'yellow');
    color.addColorStop(.4,'orange');
    color.addColorStop(1,'lightblue');
    ctx.fillStyle=color;
    ctx.fillRect(0,0,500,500);

畫素操作

createImageData(sx,sy)

​ 建立新的空白的 ImageData物件

···getImageData(x1,y1,w,h)···

​ 返回ImageData物件,該物件為畫布上指定的矩形複製畫素資料

putImageData(img,x2,y2)

​ 把影像資料(從指定的ImageData物件)放回畫布上