H5 canvas 繪圖


H5的canvas繪圖技術

 

canvas元素是HTML5中新添加的一個元素,該元素是HTML5中的一個亮點。Canvas元素就像一塊畫布,通過該元素自帶的API結合JavaScript代碼可以繪制各種圖形和圖像以及動畫效果。

 

1.1 瀏覽器不兼容問題

  • ie9以上才支持canvas, 其他chrome、firefox、蘋果瀏覽器等都支持
  •  只要瀏覽器兼容canvas,那么就會支持絕大部分api(個別最新api除外)
  •  移動端的兼容情況非常理想,基本上隨便使用
  •  2d的支持的都非常好,3d(webgl)ie11才支持,其他都支持
  •  如果瀏覽器不兼容,最好進行友好提示,提示內容只有在瀏覽器不支持時才顯示。
 //例如:
<canvas id="cavsElem">
        你的瀏覽器不支持canvas,請升級瀏覽器
    </canvas>

 瀏覽器不兼容,也可以使用flash等手段進行優雅降級

1.2 創建畫布

在頁面中創建canvas元素與創建其他元素一樣,只需要添加一個<canvas>標記即可。該元素默認的寬高為300*15,可以通過元素的width屬性和height屬性改變默認的寬高。

注意:

  •  不能使用CSS樣式控制canvas元素的寬高,否則會導致繪制的圖形拉伸。

 

  • 重新設置canvas標簽的寬高屬性會導致畫布擦除所有的內容。

 

  • 可以給canvas畫布設置背景色

1.3 canvas坐標系

在開始繪制任何圖像之前,我們先講一下canvas的坐標系。canvas坐標系是以左上角0,0處為坐標原點,水平方向為x軸,向右為正;垂直方向為y軸,向下為正。如下圖所示:

1.4 繪制線徑

  1. 獲取上下文對象(CanvasRenderingContext2D)

首先,獲取canvas元素,然后調用元素的getContext(“2d”)方法,該方法返回一個CanvasRenderingContext2D對象,使用該對象就可以在畫布上繪圖了。

 

var mcanvas  = document.getElementById("mcanvas");
var mcontext = mcanvas.getContext("2d");

  2.設置繪制起點(moveTo)

//語法:
ctx.moveTo(x, y); 

* 解釋:設置上下文繪制路徑的起點。相當於移動畫筆到某個位置。

* 參數:x,y 都是相對於 canvas坐標系的原點(左上角)。

* 注意: 繪制線段前必須先設置起點,不然繪制無效。如果不進行設置,就會使用lineTo的坐標當作moveTo

3.繪制直線(lineTo)

//語法:
ctx.lineTo(x, y);

* 解釋:從上一步設置的繪制起點繪制一條直線到(x, y)點。

* 參數:x,y 目標點坐標。

4.路徑的開始和閉合

//開始路徑:
ctx.beginPath();
//閉合路徑:
ctx.closePath();

* 解釋:如果繪制路徑比較復雜,必須使用路徑開始和結束。閉合路徑會自動把最后的線頭和開始的線頭連在一起。

* beginPath: 核心的作用是將不同繪制的形狀進行隔離,每次執行此方法,表示重新繪制一個路徑,跟之前的繪制的墨跡可以進行分開樣式設置和管理。

5.繪制圖形(stroke)

//語法:
ctx.stroke();

* 解釋:根據路徑繪制線。路徑只是草稿,真正繪制線必須執行stroke

 

在繪制之前,還可以對畫筆的顏色和粗細進行設置進行設置,方法如下:

//語法:
ctx.strokeStyle = “#ff0000”;
ctx.lineWidth = 4;  //值為不帶單位的數字,並且大於0

6.填充圖形(fill)

//語法:
ctx.fill();

* 解釋:對已經畫好的圖形進行填充顏色。

 

在填充之前,同樣可以對所填充的顏色進行設置,方法如下:

//語法:
ctx.fileStyle = “#0000ff”;

7.canvas繪制的基本步驟:

 

第一步:獲得上下文 =>canvasElem.getContext('2d');

 

第二步:開始路徑規划 =>ctx.beginPath()

 

第三步:移動起始點 =>ctx.moveTo(x, y)

 

第四步:繪制線(線條、矩形、圓形、圖片...) =>ctx.lineTo(x, y)

 

第五步:閉合路徑 =>ctx.closePath();

 

第六步:繪制描邊 =>ctx.stroke();

 

案例:通過上面所學的方法繪制一個三角形。

復制代碼
    <canvas id="mcanvas">你的瀏覽器不支持canvas,請升級瀏覽器</canvas>
    <script>
        
        var mcanvas  = document.getElementById("mcanvas");    //獲得畫布

        var mcontext = mcanvas.getContext("2d");    //獲得上下文

        mcanvas.width = 900;     //重新設置標簽的屬性寬高
        mcanvas.height = 600;    //千萬不要用 canvas.style.height

        mcanvas.style.border = "1px solid #000";    //設置canvas的邊

        //繪制三角形
        mcontext.beginPath();        //開始路徑
        mcontext.moveTo(100,100);    //三角形,左頂點
        mcontext.lineTo(300, 100);   //右頂點
        mcontext.lineTo(300, 300);   //底部的點
        mcontext.closePath();        //結束路徑
        mcontext.stroke();           //描邊路徑

    </script>
復制代碼

案例:理解canvas基於狀態的繪圖

 

<canvas id="mcanvas">你的瀏覽器不支持canvas,請升級瀏覽器</canvas>
    <script>
        
        var mcanvas  = document.getElementById("mcanvas");    //獲得畫布

        var mcontext = mcanvas.getContext("2d");    //獲得上下文

 

復制代碼
mcanvas.width = 900;     //重新設置標簽的屬性寬高
        mcanvas.height = 600;    //千萬不要用 canvas.style.height

        mcanvas.style.border = "1px solid #000";    //設置canvas的邊

        mcontext.strokeStyle = "#ff0000";    //設置畫筆的顏色
        mcontext.lineWidth = 2;                //設置畫筆的粗細
        mcontext.fillStyle = "#00ff00";        //設置填充圖形的顏色

        //繪制三角形
        mcontext.beginPath();        //開始路徑
        mcontext.moveTo(100,100);    //三角形,左頂點
        mcontext.lineTo(300, 100);   //右頂點
        mcontext.lineTo(300, 300);   //底部的點
        mcontext.closePath();        //結束路徑
           mcontext.stroke();           //描邊路徑       
        //mcontext.fill();             //填充圖形

        //繪制矩形
        mcontext.beginPath();    //開啟了一個新狀態(新線徑),
                              //新狀態可以繼承之前狀態的樣式,
                              //但是當前狀態設置的所有樣式只能用於當前狀態。
       
 //mcontext.strokeStyle = "#00ff00";//為當前狀態設置的樣式
        mcontext.moveTo(500,100);    //起始點
        mcontext.lineTo(800,100);    //上邊
        mcontext.lineTo(800,300);    //右邊
        mcontext.lineTo(500,300);    //下邊
        mcontext.closePath();
        mcontext.stroke();
復制代碼

1.5 繪制矩形

  1. 快速創建矩形rect()方法

 

語法:ctx.rect(x, y, width, height);

 

* 解釋:x, y是矩形左上角坐標, width和height都是以像素計

* rect方法只是規划了矩形的路徑,並沒有填充和描邊。

2.創建描邊矩形

 

 

 

語法:ctx.strokeRect(x, y, width, height);

 

參數跟rect(x, y, width, height)相同,注意此方法繪制完路徑后立即進行stroke繪制。

3.創建填充矩形

語法:ctx.fillRect(x, y, width, height);

參數跟rect(x, y, width, height)相同, 此方法執行完成后,立即對當前矩形進行fill填充。

4.清除矩形(clearReact)

 

語法:ctx.clearRect(x, y, width, hegiht);

 

* 解釋:清除某個矩形內的繪制的內容,相當於橡皮擦。

 

復制代碼
<canvas id="mcanvas">你的瀏覽器不支持canvas,請升級瀏覽器</canvas>
    <script>
        
        var mcanvas  = document.getElementById("mcanvas");    //獲得畫布

        var mcontext = mcanvas.getContext("2d");    //獲得上下文

        mcanvas.width = 900;     //重新設置標簽的屬性寬高
        mcanvas.height = 600;    //千萬不要用 canvas.style.height

        //rect方法只是規划了矩形的路徑,並沒有填充和描邊,需要單獨描邊或填充。
        mcontext.rect(20,20,300,200);
        mcontext.stroke();

        //快速創建一個描邊的矩形
        mcontext.strokeRect(400,20,300,200);

        //快速創建一個填充的矩形
        mcontext.fillRect(20,300,300,200);

        //在畫布上創建一個矩形區域,該矩形區域中的圖形都會被清除
        mcontext.clearRect(120,350,100,100);

    </script>
復制代碼

1.6 繪制圓形

arc() 方法用於創建弧線(用於創建圓或部分圓)。

 

語法:ctx.arc(x, y, r, startAngle, endAngle, counterclockwise);

 

復制代碼
解釋:
x,y:圓心坐標。
r:半徑大小。
sAngle:繪制開始的角度。 圓心到最右邊點是0度,順時針方向弧度增大。
eAngel:結束的角度,注意是弧度。
counterclockwise:是否是逆時針,默認是false。true是逆時針,false:順時針

注意:弧度和角度的轉換公式: rad = deg*Math.PI/180;
復制代碼

繪制圓形和餅圖

復制代碼
<canvas id="mcanvas">你的瀏覽器不支持canvas,請升級瀏覽器</canvas>
    <script>
        
        var mcanvas  = document.getElementById("mcanvas");    //獲得畫布
        var mcontext = mcanvas.getContext("2d");    //獲得上下文
        mcanvas.width = 900;     
        mcanvas.height = 600;  

        //繪制圓形  
        mcontext.beginPath();
        mcontext.arc(200,200,100,0,360*Math.PI/180);
        mcontext.closePath();
        mcontext.stroke();

        // 通過數據進行繪制餅圖
        var data = [{
            "value": .2,
            "color": "red",
            "title": "應屆生"
        },{
            "value": .3,
            "color": "blue",
            "title": "社會招生"
        },{
            "value": .4,
            "color": "green",
            "title": "老學員推薦"
        },{
            "value": .1,
            "color": "#ccc",
            "title": "公開課"
        }];

        var tempAngle = -90;
        var x0 = 600, y0 = 300;
        var raduis = 200;

        for(var i = 0; i < data.length; i++) {
            mcontext.beginPath();
            mcontext.moveTo(x0, y0);
            var angle = data[i].value * 360;
            var startAngle = tempAngle*Math.PI/180;
            var endAngle  = (tempAngle+angle)*Math.PI/180;
            mcontext.fillStyle = data[i].color;
            mcontext.arc(x0, y0, raduis, startAngle, endAngle);
            mcontext.closePath();
            mcontext.fill();
            tempAngle += angle;
        }

    </script>
復制代碼

三角函數的補充:

Math.sin(弧度); //夾角對面的邊 和 斜邊的比值

Math.cos(弧度); //夾角側邊與斜邊的比值

圓形上面的點的坐標的計算公式

x =x0 + Math.cos(rad) * R;//x0和y0是圓心點坐標

y =y0 + Math.sin(rad) * R;//注意都是弧度 

1.7 繪制文字

canvas 提供了兩種方法來渲染文本:

 

fillText(text, x, y [, maxWidth])

 

在指定的(x,y)位置填充指定的文本,繪制的最大寬度是可選的.

 

strokeText(text, x, y [, maxWidth])

 

在指定的(x,y)位置繪制文本邊框,繪制的最大寬度是可選的.

 

示例1

 

文本用當前的填充方式被填充:

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

 ctx.font = "48px serif";
 ctx.fillText("Hello world", 10, 50);

示例2

文本用當前的邊框樣式被繪制:

 var ctx = document.getElementById('canvas').getContext('2d');
  ctx.font = "48px serif";
  ctx.strokeText("Hello world", 10, 50);

文本樣式

font = value: 當前我們用來繪制文本的樣式. 這個字符串使用和 CSS font 屬性相同的語法. 默認的字體是 10px sans-serif。

textAlign = value: 文本對齊選項. 可選的值包括:start, end, left, right or center. 默認值是 start。

 

textBaseline = value:  基線對齊選項. 可選的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默認值是 alphabetic。

 

代碼示例:

復制代碼
<canvas id="mcanvas">你的瀏覽器不支持canvas,請升級瀏覽器</canvas>
    <script>
        
        var mcanvas  = document.getElementById("mcanvas");    //獲得畫布
        var mcontext = mcanvas.getContext("2d");    //獲得上下文
        mcanvas.width = 900;     
        mcanvas.height = 600;  

        mcontext.fillStyle = "#0000ff";
        mcontext.font = "italic 30px 微軟雅黑";
        mcontext.textAlign = "start";
        mcontext.textBaseline = "top";
        mcontext.fillText("你好", 200, 0, 100);

        mcontext.font = "italic 30px 微軟雅黑";
        mcontext.textAlign = "left";
        mcontext.textBaseline = "top";
        mcontext.fillText("你好", 200, 50, 100);

        mcontext.font = "bold 30px 黑體";
        mcontext.textAlign = "center";
        mcontext.textBaseline = "top";
        mcontext.strokeText("你好", 200, 100, 100);

        mcontext.font = "bold 30px 黑體";
        mcontext.textAlign = "right";
        mcontext.textBaseline = "top";
        mcontext.strokeText("你好", 200, 150, 100);

        mcontext.font = "bold 30px 黑體";
        mcontext.textAlign = "end";
        mcontext.textBaseline = "top";
        mcontext.strokeText("你好", 200, 200, 100);

    </script>
復制代碼

1.8繪制圖像

1.基本繪制圖片的方式

 

context.drawImage(img,x,y);

 

參數說明: x,y 繪制圖片左上角的坐標, img是繪制圖片的dom對象。

2.在畫布上繪制圖像,並規定圖像的寬度和高度

context.drawImage(img,x,y,width,height);  

參數說明:width 繪制圖片的寬度,  height:繪制圖片的高度

如果指定寬高,最好成比例,不然圖片會被拉伸

設置高 = 原高度 * 設置寬/ 原寬度;

3.圖片裁剪,並在畫布上定位被裁剪的部分

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

參數說明:

    sx,sy 裁剪的左上角坐標,

    swidth:裁剪圖片的高度。 sheight:裁剪的高度

其他同上

4.用javascript創建img對象

 

上面提供的3個方法,都需要一個Image對象作為參數,下面介紹了幾種創建Image對象的方式。需要注意的是,為Image的src屬性賦值后,Image對象會去裝載指定圖片,但這種裝載是異步的,如果圖片太大或則圖片來自網絡,且網絡傳輸速度慢,Image對象裝載圖片就會需要:一定的時間開銷。為了保證圖片裝載完成后才去繪制圖片,可以監聽Image對象的onload回調事件,然后在事件處理函數中繪制圖片,如下所示:

 

第一種方式:

  var img = document.getElementById("imgId");
    img.onload = function(){  //圖片加載完成后,執行此方法
      mcontext.drawImage(img, 10, 10);
    }

第二種方式:

var img = document.createElement("img");
        img.src = "img/a.jpg";
        img.alt = "誰笑誰是小狗";
        img.onload = function(){  //圖片加載完成后,執行此方法
            mcontext.drawImage(img, 10, 10);
        }

第三種方式:

var img = new Image();//這個就是 img標簽的dom對象
    img.src = "imgs/arc.gif";
    img.alt = "誰笑誰是小狗";
    img.onload = function() {  //圖片加載完成后,執行此方法
        
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM