Canvas入門-利用canvas制作一個七巧板

簡介

<canvas> 是 HTML5 新增的元素之一,它允許腳本語言動態渲染位圖像。最初是由 Apple 引入,用于 Mac OS X 的儀表盤,后來又在 Safiri 和 Google Chrome 中被實現。 <canvas> 就像個神奇的畫布,你可以在上面畫出你想要的絢麗的效果。使用<canvas>元素之前,需要一些基本的 HTML 和 Javascript 知識。<canvas> 元素不被一些老的瀏覽器支持,但是主流的高級瀏覽器都支持。

基本用法

  1. <canvas> 元素
<canvas id = "canvas" width ="200px" height="200px“ style="border: 1px solid #0000ff; display: block; margin: 50px auto" >
您的瀏覽器不支持canvas!
</canvas>

如果沒有設置寬度和高度的時候,canvas 會默認設置寬為300px,高為150px。當瀏覽器不支持 canvas 時,會將中間的文字打印出來。上面代碼中,為了讓畫布更加明顯,添加了css 樣式便于查看。

  1. 渲染上下文
    canvas 元素創造了一個固定大小的畫布,并且公開了渲染上下文對象,它可以用來繪制和處理要展示的內容。Canvas API 定義在 context這個對象上,因此要用getContext方法來獲取這個對象。
var canas = document.getElementById("canvas");
// 繪制2D圖像的上下文環境
var context = canvas.getContext("2d");

上面代碼中,getContext方法指定參數‘2d’,表示該canvas對象繪制2d圖像,執行后的效果為下圖一個藍色邊框的舉重的矩形。


截圖.png
  1. 柵格
    在繪制圖像之前,我們要先了解什么是柵格,通常來說網格中的一個單元相當于canvas元素中的一像素。柵格的起點為左上角(坐標為(0,0))。所有元素的位置都相對于原點定位。所以圖中藍色方形左上角的坐標為距離左邊(Y軸)x像素,距離上邊(X軸)y像素(坐標為(x,y))。


    Canvas_default_grid.png
  2. 繪制圖像
    好,現在可以開始繪制圖像了,首先要了解下繪制 moveTo()這個方法。
  • 移動筆觸
moveTo(x, y)將筆觸移動到指定的坐標x以及y上。

這個方法實際上并不能畫出任何東西,它就是起到移動筆觸的作用,并且作為起始點。


  • 繪制直線,需要用到的方法lineTo()。
lineTo(x, y)繪制一條從當前位置到指定x以及y位置的直線。

該方法有兩個參數:x以及y ,代表坐標系中直線結束的點。開始點和之前的繪制路徑有關,之前路徑的結束點就是接下來的開始點,等等。。。開始點也可以通過moveTo()函數改變。

//繪制線條1
context.moveTo(0,0);
context.lineTo(100,100);
context.stroke();
line.png
  • 路徑
    圖形的基本元素是路徑。路徑是通過不同顏色和寬度的線段或曲線相連形成的不同形狀的點的集合。一個路徑,甚至一個子路徑,都是閉合的。使用路徑繪制圖形需要一些額外的步驟。
    首先,要創建路徑起始點,然后使用畫圖命令去畫出路徑,之后封閉路徑。一旦路徑生成,就能通過描邊或填充路徑區域來渲染圖形。
    常用到的函數:
beginPath()
新建一條路徑,生成之后,圖形繪制命令被指向到路徑上生成路徑。
closePath()
閉合路徑之后圖形繪制命令又重新指向到上下文中。
stroke()
通過線條來繪制圖形輪廓。
fill()
通過填充路徑的內容區域生成實心的圖形。

生成路徑的第一步叫做beginPath()。本質上,路徑是由很多子路徑構成,這些子路徑都是在一個列表中,所有的子路徑(線、弧形、等等)構成圖形。而每次這個方法調用之后,列表清空重置,然后我們就可以重新繪制新的圖形。
第二步就是調用函數指定繪制路徑,本文稍后我們就能看到了。
第三,就是閉合路徑closePath(),不是必需的。這個方法會通過繪制一條從當前點到開始點的直線來閉合圖形。如果圖形是已經閉合了的,即當前點為開始點,該函數什么也不做。
了解完這些后,我們就能夠開始作出我們要的七巧板了~

七巧板

首先,新建一個畫布

<canvas id="canvas" style="display: block; margin: 60px auto;"></canvas>

接著,為這個畫布添加事件

window.onload = function(){
            var canvas = document.getElementById("canvas");
            canvas.width = 600;
            canvas.height = 600;
            //繪制2d圖像的上下文環境
            var context = canvas.getContext("2d");

            //繪制左邊平行四邊形
            context.beginPath();
            context.lineWidth = 5;
            context.moveTo(150,450);
            context.lineTo(450,450);
            context.lineTo(300,600);
            context.lineTo(0,600);
            context.fillStyle = "#FF1493";
            context.strokeStyle = "#000000";
            context.fill();
            context.stroke();

            //繪制左邊的大三角形
            context.beginPath();
            context.lineWidth = 5;
            context.moveTo(0,0);
            context.lineTo(300,300);
            context.lineTo(0,600);
            context.fillStyle = "#0000ff";
            context.strokeStyle = "#000000";
            context.fill();
            context.stroke();

            //繪制右邊的大三角形
            context.beginPath();
            context.lineWidth = 5;
            context.moveTo(0,0);
            context.lineTo(300,300);
            context.lineTo(600,0);
            context.fillStyle = "#FFFF00";
            context.strokeStyle = "#000000";
            context.fill();
            context.stroke();

            //繪制中間三角形
            context.beginPath();
            context.lineWidth = 5;
            context.moveTo(300,300);
            context.lineTo(150,450);
            context.lineTo(450,450);
            context.fillStyle = "#FF7F50";
            context.strokeStyle = "#000000";
            context.fill();
            context.stroke();


            //繪制中間小矩形
            context.beginPath();
            context.lineWidth = 5;
            context.moveTo(450,150);
            context.lineTo(300,300);
            context.lineTo(450,450);
            context.lineTo(600,300);
            context.fillStyle = "#191970";
            context.strokeStyle ="#000000";
            context.fill();
            context.stroke();

            
            //繪制最右邊小三角形
            context.beginPath();
            context.lineWidth = 5;
            context.moveTo(600,0);
            context.lineTo(450,150);
            context.lineTo(600,300);
            context.fillStyle = "#A52A2A";
            context.strokeStyle = "#000000";
            context.fill();
            context.stroke();

            //繪制右邊大三角形
            context.beginPath();
            context.lineWidth = 5;
            context.moveTo(600,300);
            context.lineTo(300,600);
            context.lineTo(600,600);
            context.fillStyle = "#00FFFF";
            context.strokeStyle = "#000000";
            context.fill();
            context.stroke();

            //繪制最外圍的邊框
            context.beginPath();//開始繪制路徑
            context.lineWidth = 10;//設置線條的寬度
            context.moveTo(0,0);//移動筆觸
            context.lineTo(600,0);//繪制線條
            context.lineTo(600,600);
            context.lineTo(0,600);
            context.closePath();//封閉路徑
            context.stroke();//通過線條來繪制圖形輪廓
        };

優化版本:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>canvas</title>
</head>
<body>
    <!-- 優化七巧板,將模型數據用數據存儲起來,逐個取出并繪制。 -->
    <canvas id="canvas" style="border: 1 px solid #aaa; display: block; margin: 50px auto">
        當前瀏覽器不支持cnavas      
    </canvas>
    <script type="text/javascript">
    var tangram = [
        {
            f:[{x: 0,y: 0},{x: 800, y: 0},{x: 400, y: 400}],
            color: "#FEF734",
        },
        {
            f:[{x: 0,y: 0},{x: 400, y: 400},{x: 0, y: 800}],
            color: "#224AFB",
        },
        {
            f:[{x: 800,y: 0},{x: 600, y: 200},{x: 800, y: 400}],
            color: "#A82F24",
        },
        {
            f:[{x: 400,y: 400},{x: 600, y: 200},{x: 800, y: 400},{x: 600, y: 600}],
            color: "#141D71",
        },
        {
            f:[{x: 400,y: 400},{x: 200, y: 600},{x: 600, y: 600}],
            color: "#F17E4D",
        },
        {
            f:[{x: 200,y:  600},{x: 600, y: 600},{x: 400, y: 800},{x: 0, y: 800}],
            color: "##EC4F93",
        },
        {
            f:[{x: 800,y: 400},{x: 400, y: 800},{x: 800, y: 800}],
            color: "#6CF8FC",
        },
    ];
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = 800;
        canvas.height = 800;
        for(var i = 0; i< tangram.length; i++){
            ctx.beginPath();
            ctx.moveTo(tangram[i].f[0].x, tangram[i].f[0].y);
            for (var j= 1; j < tangram[i].f.length; j++){
                ctx.lineTo(tangram[i].f[j].x, tangram[i].f[j].y);
            }
            ctx.closePath();
            ctx.fillStyle = tangram[i].color;
            ctx.fill();
            ctx.lineWidth = 10;
            ctx.stroke();
        }
        //重繪最外層邊框
        ctx.lineWidth = 20;
        ctx.strokeRect(0,0,800,800);
    }

    </script>
</body>
</html>

一個簡單的七巧板就出來啦~


七巧板.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容