HTML5----canvas

如何創造一個畫布呢?javascript

首先在html頁面中聲明html

<canvas id='canvas'></canvas>java

而後再js中獲取這個標籤canvas

var canvas = document.getElementById('canvas');ide

var context =canvas.getContext('2d');函數

//使用context進行繪製spa

 

1.首先從繪製直線說提及code

canvas.htmlhtm

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>canvas詳解</title>
    <script src="canvas.js"type="text/javascript"></script>
</head>
<body>
<canvas id="canvas" style="border:1px solid black;margin:300px"></canvas>
</body>
</html>

canvas.jsblog

/**
 * Created by Administrator on 2016/9/26.
 */
window.onload=function(){
    var canvas = document.getElementById('canvas');

    canvas.width = 500;
    canvas.height = 500;
    var context = canvas.getContext('2d');
    context.moveTo(100,100);
    context.lineTo(400,400);
    context.lineWidth =5;
    context.strokeStyle ='#058'
    context.stroke();
}

canvas是一種基於狀態的繪製,因此先設置狀態

    context.moveTo(100,100);設置從哪裏開始繪製
    context.lineTo(400,400);//設置繪製到什麼位置
    context.lineWidth =5;線段的寬度
    context.strokeStyle ='#058'設置繪製的顏色
context.stroke()繪製線段;

如何畫折線

    context.moveTo(100,100);
    context.lineTo(400,400);
    context.lineTo(400,100);//多加一條就能夠畫出折線,這時會鏈接(400,400)到(400,100)
    context.lineWidth =5;
    context.strokeStyle ='#058'
    context.stroke();

在看下面的一個例子

    context.moveTo(100,200);  
    context.lineTo(300,400);
    context.lineTo(100,600);

    context.moveTo(300,200);
    context.lineTo(500,400);
    context.lineTo(300,600);

    context.moveTo(500,200);
    context.lineTo(700,400);
    context.lineTo(500,600);
    context.lineWidth =5;
    context.strokeStyle ='#058'
    context.stroke();

結果:

moveTo表示的是把畫筆放在什麼位置,lineTo表示畫到什麼位置

 

canvas陷阱

 

   context.moveTo(100,200);
    context.lineTo(300,400);
    context.lineTo(100,600);
    context.strokeStyle ='red'
    context.stroke();
    
    context.moveTo(300,200);
    context.lineTo(500,400);
    context.lineTo(300,600);
    context.strokeStyle ='blue'
    context.stroke();

    context.moveTo(500,200);
    context.lineTo(700,400);
    context.lineTo(500,600);
    context.lineWidth =5;
    context.strokeStyle ='green'
    context.stroke();

這個時候繪製的不是三條不一樣顏色的線,而是三種顏色相同的線段,由於canvas是基於狀態的繪製,因此每次stroke時都會把以前因此的狀態繪製一邊,因此最後的顏色是green

如何解決這個bug呢

此時就要引入beginPath(),這個表示的是重新開始繪製,此時開始一條新的路徑

context.beginPath()
    context.moveTo(100,200);
    context.lineTo(300,400);
    context.lineTo(100,600);
    context.lineWidth =5;
    context.strokeStyle ='red'
    context.stroke();

    context.beginPath()
    context.moveTo(300,200);
    context.lineTo(500,400);
    context.lineTo(300,600);
    context.lineWidth =5;
    context.strokeStyle ='blue'
    context.stroke();

    context.beginPath()
    context.moveTo(500,200);
    context.lineTo(700,400);
    context.lineTo(500,600);
    context.lineWidth =5;
    context.strokeStyle ='green'
    context.stroke();

此時繪製的是三條不一樣顏色的線段

還有注意一下beginPath()下面的moveTo能夠改成lineTo

 

如何實現封閉線

    context.beginPath();
    context.lineTo(100,350);
    context.lineTo(500,350);
    context.lineTo(500,200);
    context.lineTo(700,400);
    context.lineTo(500,600);
    context.lineTo(500,450);
    context.lineTo(100,450);
    context.lineTo(100,350);
    context.lineWidth =5;
    context.strokeStyle ="#58";
    context.stroke();

這樣就連成一條封閉的圖形

可是放大後能夠看出最後鏈接處有點小瑕疵

如何避免這種問題呢

其實若是要繪製封閉的圖形,最標準的方法是最後還要加上context.closePath(),這樣就會把鏈接處的問題處理掉。

此外如何你用了closePath()的話,最有一句lineTo()寫不寫無所謂的,由於他會自動幫你封閉起來。

 

填充色

如何給封閉的圖形填充顏色呢?

    context.lineWidth =10;
    context.strokeStyle ="#58";
    context.fillStyle ='yellow';
    context.fill();
    context.stroke();

經過fillStyle ,fill()就能夠給封閉的圖形填充相應的顏色,此外,千萬要注意一點就是,若是咱們把fill()寫在stroke()的後面的話,此時邊框雖然爲10px可是內部的5px被填充色給覆蓋了,因此要將stroke放在fill後面

 

編寫繪製矩形的函數

 var canvas = document.getElementById('canvas');
    canvas.width = 800;
    canvas.height = 800;
    var context = canvas.getContext('2d');
    DrawRect(context,100,100,300,300,10,'red','blue')
    function DrawRect(txt,x,y,width,height,strokeWidth,strokeStyle,fillStyle){
        txt.beginPath()
        txt.lineTo(x,y);
        txt.lineTo(x+width,y);
        txt.lineTo(x+width,y+height);
        txt.lineTo(x,y+height);
        txt.closePath();

        txt.strokeStyle =strokeStyle;
        txt.fillStyle =fillStyle;
        txt.lineWidth = strokeWidth;
        txt.fill();
        txt.stroke();
    }

其實canvas中有專門的繪製矩形的藉口

rect(x,y,width,height);//這一句話是給出了矩形的狀態,至關於

        txt.lineTo(x,y);
        txt.lineTo(x+width,y); txt.lineTo(x+width,y+height); txt.lineTo(x,y+height);

        txt.beginPath()
        txt.rect(x,y,width,height);
        txt.closePath();

        txt.strokeStyle =strokeStyle;
        txt.fillStyle =fillStyle;
        txt.lineWidth = strokeWidth;
        txt.fill();
        txt.stroke();
還有兩種方法:fillRect(x,y,width,height);strokeRect(x,y,width,height);
這兩種方法不只定義了狀態了實現了繪製。
        txt.strokeStyle =strokeStyle;
        txt.fillStyle =fillStyle;
        txt.lineWidth = strokeWidth;
        txt.fillRect(x,y,width,height);
        txt.strokeRect(x,y,width,height);

  

 

線條的屬性

對於線條的屬性:lineWidth就是其中一個,其次接着講lineCap字面的意思是線條的帽子,也就是線條結尾處和開始出的形狀(即便是折線也只會在整個線段的開始和結尾處添加,折線處不會)

lineCap有三個取值:butt(default) , round(圓形), square(正方形),注意對於round和square來講,是在原來的基礎上添加的,也就是線段會變長。

 

小小例子-----繪製五角星

如何繪製一個小小的五角星來着

如何實現狀態的鏈接呢?

function DrawStar(txt,R,r,x,y,rot){
    txt.beginPath()
    for(var i=0;i< 5;i++){
        txt.lineTo(Math.cos((18 + 72*i - rot)/180 * Math.PI ) * R + x,
            -Math.sin((18+ 72 * i - rot)/180 * Math.PI) * R+ y);
        txt.lineTo(Math.cos((54 + 72 * i - rot)/180 * Math.PI) * r + x,
            -Math.sin((54+ 72*i  - rot)/180 * Math.PI) * r + y);
    }
    txt.closePath();
}

這樣就能夠實現

具體代碼

window.onload=function(){
    var canvas = document.getElementById('canvas');
    canvas.width = 800;
    canvas.height = 800;
    var context = canvas.getContext('2d');
    context.lineWidth =5;
    DrawStar(context,300,150,400,400,30);
    context.stroke();
}

function DrawStar(txt,R,r,x,y,rot){
    txt.beginPath()
    for(var i=0;i< 5;i++){
        txt.lineTo(Math.cos((18 + 72*i - rot)/180 * Math.PI ) * R + x,
            -Math.sin((18+ 72 * i - rot)/180 * Math.PI) * R+ y);
        txt.lineTo(Math.cos((54 + 72 * i - rot)/180 * Math.PI) * r + x,
            -Math.sin((54+ 72*i  - rot)/180 * Math.PI) * r + y);
    }
    txt.closePath();
}

 

 

線條屬性之lineJoin

這個屬性表示的線條鏈接時的狀態

默認有三個取值(miter,bevel,round)默認值是miter表示尖角,會一直延伸到兩條先交到一塊兒。

還有一個屬性miterLimit,這個屬性只有當lineJoin選擇miter的時候纔有效,表示的是鏈接線的內接點與外接點的距離。

 

fillStyle屬性:注意這個屬性不光光能夠設置顏色,還能夠設置漸變色,如何設置漸變色呢?(漸變色分爲線性漸變色,和徑向漸變色)

首先以線性漸變色爲例子來講

第一步:var grd =context.createLinearGradient(xstart,ystart,xend,yend);

第二步:grd.addColorStop(stop,color);其中stop表示的是位置(值取0-1之間);

   var linearGrad = context.createLinearGradient(0,0,800,800);
    linearGrad.addColorStop(0.0,'#FFF');
   linearGrad.addColorStop(1.0,'#000');
   context.fillStyle =linearGrad;

其中

 addColorGradient能夠取不少,此外若是沒有在整個畫布內漸變的話,剩餘的部分會以最後的顏色填充。此外咱們開始漸變的位置和結束的位置能夠超出畫布的部分

2, 徑向漸變

步驟一:var grd = context.createRadiaGradient(x,y,r1,x,y,r2);

步驟二: grd.addColorStop(0.0,'white');

             grd.addColorStop(0.25,'yellow');

             grd.addColorStop(0.5,'green');

             grd.addColorStop(0.75,'blue');

             grd.addColorStop(1.0,'block')

             context.fillStyle = grd;

漸變色在第一個圓與第二個圓之間漸變。

 

3.重點注意

createPattern(img,repeat-style);

repeat-style:no-repeat;

                   repeat-x;

                   repeat-y;

                    repeat

具體實現:

var backgroundImage =new Image();

backgroundImage.src ='1.jpg';

backgroundImage.onload = function(){
    var pattern = context.createPattern(backgroundImage,'repeat');
    context.fillStyle = pattern;

    context.fillRect(0,0,800,800);

}

此外createPattern(canvas,repeat-style)不只能夠引入圖片,也可讓另一個畫布做爲背景);

還能夠creatPattern(video,repeat-style);

 

 

繪製圓弧

context.arc(centerX,centerY,radius,startingAngle,endindAngle,anticlockwise=false)

參數的意思:圓心的X座標,Y座標,起點角度,終點角度,是否順時針(默認狀況下是順時針);

此時不管是順時針仍是逆時針,角度都是不變的,好比逆時針的話,0.5pi是在下面的那個位置如圖所示,而不是上面的1.5pi位置

第二種繪製弧線的方法:arcTo(x1,y1,x2,y2,radius);

 

這個方法是如何繪製弧線的呢?

其實他是以最近的moveTo或者lineTo爲起點,而後鏈接(x1,y1)和點(x2,y2)造成一個折線,而後以(x0,y0)爲起點,相切於這兩條線的弧線就是咱們要繪製的弧線,此外,弧線的終點不必定是(x2,y2);此外(x0,y0)也不必定是切點,千萬要注意了。

二次貝塞爾曲線其實貝塞爾曲線跟arcTo差很少,可是也有區別首先也是以最近的一個moveTo或者lineTo爲起點開始的,context.moveTo(x0,y0);context.quadraticCurveTo(x1,y1,x2,y2);區別在於曲線是以(x0,y0)爲起點的,以(x2,y2)爲重點的,而且相切於這兩個點。三次貝塞爾曲線,context.move(x0,y0)context.bezierCurveTo(x1,y1,x2,y2,x3,y3);此時原理仍是同樣,只不過這時候控制點就是(x1,y1),(x2,y2);
相關文章
相關標籤/搜索