Canvas從入門到改行

0x001 Canvas是啥?


說白了Canvas就是一塊畫布,可以使用js當畫筆在上面繪畫的畫布,可以顯示在網頁上的畫布,同時也是通過期中考的關鍵技術。

0x002 Canvas坐標圖


Paste_Image.png

0x003 Canvas使用方式


    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>canvas測試</title>
      </head>
      <body>
        <!-- 建立了一個高300px,寬300px的的畫布 -->
        <canvas id="canvas" width="300" height="300"></canvas>
      </body>
    </html>
Paste_Image.png

0x004 Canvas替代內容


如果不支持就用文本代替,不過如今大多數(shù)瀏覽器已經可以支持了,所以我也找不到瀏覽器測試是否可以用一張圖片代替。

 <canvas id="canvas" width="300" height="300">
小傻逼瀏覽器不支持Canvas</canvas>

0x005 Canvas和CSS


canvas元素和其他html元素一樣,可以使用css來改變canvas的一些樣式。

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>canvas測試</title>
        <style media="screen">
          #canvas{
            width: 200px;
            height: 300px;
            margin: 10px;
            border: 5px solid red;
          }
        </style>
      </head>
      <body>
        <canvas id="canvas"></canvas>
      </body>
    </html>
Paste_Image.png

但是這樣是有問題的看以下案例,它將會繪制一條對角線
但是這樣其實是有問題的,因為canvas的默認高度是300*150,所以,如果使用css為canvas設置width和height會導致canvas繪制的圖像被壓縮。所以還是使用屬性來設置canvas的寬高吧

0x006 canvasAPI

canvas頁面,我們將再紅色方框的canvas內繪制:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>canvas測試</title>
        <style media="screen">

        </style>
      </head>
      <body>
        <canvas id="canvas" width="500" height="500" style="border: 5px solid red"></canvas>
      </body>
      <script type="text/javascript">
      </script>
    </html>
Paste_Image.png

繪制一條直線

- 代碼:
        // 獲取canvas元素
        var canvas=document.getElementById("canvas");
        // 獲取canvas上下文
        var context=canvas.getContext('2d');
        // 繪制直線
        context.beginPath();//開始繪制路徑
        context.moveTo(0,500);//設置開始點
        context.lineTo(500,0);//設置結束點并連接開始點和結束點
        context.stroke();//將圖像繪制出來
  • 效果


    Paste_Image.png

路徑

- 代碼

            // 獲取canvas元素
          var canvas=document.getElementById("canvas");
          // 獲取canvas上下文
          var context=canvas.getContext('2d');
          // 繪制直線
          context.beginPath();
          context.moveTo(0,0);
          context.lineTo(0,100);

          context.lineTo(0,100);
          context.lineTo(100,100);

          context.lineTo(100,200);

          context.lineTo(200,200);

          context.lineTo(200,300);

          context.lineTo(300,300);

          context.lineTo(300,400);

          context.lineTo(400,400);

          context.lineTo(400,500);

          context.lineTo(500,500);
          context.stroke();
  • 效果:
Paste_Image.png

繪制一棵樹

  • 代碼:

                  // 獲取canvas元素
          var canvas=document.getElementById("canvas");
          // 獲取canvas上下文
          var context=canvas.getContext('2d');
          // 繪制直線
          context.beginPath();
    
          context.moveTo(100,100);
          context.lineTo(50,200);
          context.lineTo(90,200);
          context.lineTo(40,300);
          context.lineTo(80,300);
          context.lineTo(30,400);
          context.lineTo(70,400);
          context.lineTo(70,500);
          context.lineTo(130,500);
          context.lineTo(130,400);
          context.lineTo(170,400);
          context.lineTo(120,300);
          context.lineTo(160,300);
          context.lineTo(110,200);
          context.lineTo(150,200);
          context.closePath();
          context.stroke();
    
  • 效果

Paste_Image.png

修改樣式

  • 代碼:

            // 獲取canvas元素
            var canvas=document.getElementById("canvas");
            // 獲取canvas上下文
            var context=canvas.getContext('2d');
            // 繪制直線
            context.beginPath();
    
            context.moveTo(100,100);
            context.lineTo(50,200);
            context.lineTo(90,200);
            context.lineTo(40,300);
            context.lineTo(80,300);
            context.lineTo(30,400);
            context.lineTo(70,400);
            context.lineTo(70,500);
            context.lineTo(130,500);
            context.lineTo(130,400);
            context.lineTo(170,400);
            context.lineTo(120,300);
            context.lineTo(160,300);
            context.lineTo(110,200);
            context.lineTo(150,200);
            
            context.lineWidth=8;
            context.lineJoin='round';
            context.strokeStyle='#663300';
            context.closePath();
            context.stroke();
    
  • 效果:

Paste_Image.png

填充

  • 代碼 :

            context.fillStyle="red";
            context.fill();
    
  • 效果:

Paste_Image.png

繪制正方形

  • 代碼

        var canvas=document.getElementById("canvas");
        // 獲取canvas上下文
        var context=canvas.getContext('2d');
        context.fillStyle="red";
        //前兩個參數(shù)數(shù)位置x、y,后兩個參數(shù)是寬、高
        context.fillRect(100,100,100,100);
        context.stroke();
    
  • 效果

Paste_Image.png

繪制曲線

  • 說明:
Paste_Image.png
  • 代碼:

                 var canvas=document.getElementById("canvas");
        // 獲取canvas上下文
        var context=canvas.getContext('2d');
    
        //指定起點
        context.moveTo(250,0);
        //前兩個是控制點,后兩個是終點
        context.quadraticCurveTo(250,250,500,250);
        context.strokeStyle="red";
        context.lineWidth=20;
        context.stroke();
    
  • 效果

Paste_Image.png

圓形:

  • 代碼:

    // 獲取canvas元素
    var canvas=document.getElementById("canvas");
    // 獲取canvas上下文
    var context=canvas.getContext('2d');
    
    context.beginPath();
    // 前兩個分別是圓心的x、y坐標,
    //第三個是圓的半徑,
    //第四第五個是繪制弧線的開始弧度和結束弧度 1*Math.PI是半圓,2*Math.PI則是一個圓
    context.arc(100,100,100,0,2*Math.PI);
    context.stroke();
    context.closePath();
    //弧度的開始是從3點鐘位置開始
    context.beginPath();
    context.arc(300,300,100,0,0.1*Math.PI);
    context.stroke();
    
  • 效果

Paste_Image.png

漸變

  • 代碼:
    // 獲取canvas元素
    var canvas=document.getElementById("canvas");
    // 獲取canvas上下文
    var context=canvas.getContext('2d');
    //前兩個參數(shù)指定開始的點的x、y坐標,后兩個是結束的點的x、y坐標
    var lg=context.createLinearGradient(0,0,100,0);
    lg.addColorStop(0,"#ff0000");
    lg.addColorStop(0.5,"#00ff00");
    lg.addColorStop(1,"#0000ff");
    context.fillStyle=lg;
    context.fillRect(0,0,175,50);

    //注意漸變色相對位置是context,不是rect
    //如果繪制的圖像超出了漸變色的坐標
    //將會使用最后設置的顏色來填充
    var lg=context.createLinearGradient(0,0,100,0);
    lg.addColorStop(0,"#ff0000");
    lg.addColorStop(0.5,"#00ff00");
    //使用藍色填充
    lg.addColorStop(1,"#0000ff");
    context.fillStyle=lg;
    context.fillRect(200,200,100,100);
    
    //如果漸變 線是斜的, 那么最后填充的漸變也是斜的
    var lg=context.createLinearGradient(200,200,400,400);
    lg.addColorStop(0,"#ff0000");
    lg.addColorStop(0.5,"#00ff00");
    //使用藍色填充
    lg.addColorStop(1,"#0000ff");
    context.fillStyle=lg;
    context.fillRect(200,200,200,200);
    
    //徑向漸變
    var lg=context.createRadialGradient(50,450,0,80,500,100);
    lg.addColorStop(0,"#ff0000");
    lg.addColorStop(0.5,"#00ff00");
    //使用藍色填充
    lg.addColorStop(1,"#0000ff");
    context.fillStyle=lg;
    context.fillRect(0,400,200,200);
    
  • 效果:

Paste_Image.png

大項目:繪制一堆不斷變大變小的隨機移動的氣泡

  • 效果:
GIF.gif
  • html文件:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>氣泡變化</title>
    </head>
    <body>
    <canvas id="canvas" width="1200px" height="800px">
    </canvas>
    </body>
    <script src="main.js">
    
    </script>
    </html>
    
  • 獲取context

        var canvas=document.querySelector('canvas'),
          context=canvas.getContext('2d');
      // 這個數(shù)組用于保存畫布上出現(xiàn)的所有球
      var balls = [];
    
  • 構建一個氣泡對象

        // 用于表示球的所有細節(jié)的Ball函數(shù)
      // x、y分別是氣泡初始化的位置
      //radius是氣泡的半徑-隨機
      //strokeColor 繪制顏色 -隨機
      //填充顏色-隨機
      //flag半徑變大還是變小
      //flagx x增大還是減小
      //flagy y增加還是減少
      function Ball(x, y) {
          this.x = x;
          this.y = y;
          this.radius = Math.round(Math.random()*10)*10;
          this.strokeColor = 'rgba('+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+',0)';
          this.fillColor = 'rgba('+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)*25+','+Math.round(Math.random()*10)/10+')';
          this.flag=1;
          this.flagx=1;
          this.flagy=1;
      }
    
  • 向數(shù)組添加小球

      function addBall() {
          // 小球半徑
          var radius = Math.round(Math.random()*10)*10;
          var x=0,y=0;
          
          if (x<200||x>1000){
              x=Math.round(Math.random()*10)*100;
          }
          if (y<200||x>600){
              y=Math.round(Math.random()*10)*60;
          }
          // 創(chuàng)建新的ball對象
          var ball = new Ball(x,y);
          // 將其保存在balls數(shù)組中
          balls.push(ball);
      }
    
  • 繪制圖像并且在20ms后再次繪制

    function drawFrame() {
        // 清除畫布
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        // 循環(huán)所有的球,并重新定義他們的位置和大小

        for(var i=0; i<balls.length; i++) {
            if (balls[i].flagx==1){
                balls[i].x++;
                if (balls[i].x>=800){
                    balls[i].flagx=0;
                }
            }else if(balls[i].flagx==0){
                balls[i].x--;
                if (balls[i].x<=0){
                    balls[i].flagx=1;
                }
            }

            if (balls[i].flagy==1){
                balls[i].y++;
                if (balls[i].y>=600){
                    balls[i].flagy=0;
                }
            }else if(balls[i].flagy==0){
                balls[i].y--;
                if (balls[i].y<=0){
                    balls[i].flagy=1;
                }
            }


            if (balls[i].flag==1){
                balls[i].radius++;

                balls[i].y++;
                if (balls[i].radius>=100){
                    balls[i].flag=0;
                }
            }else if (balls[i].flag==0){
                balls[i].radius--;
                balls[i].x--;
                balls[i].y--;
                if (balls[i].radius<=0){
                    balls[i].flag=1;
                }
            }
            var ball = balls[i];
            context.beginPath();
            context.fillStyle = balls[i].fillColor;
            context.strokeStyle=balls[i].strokeColor;
            // 繪制球
            context.arc(balls[i].x, balls[i].y, balls[i].radius, 0, Math.PI*2);
            context.lineWidth = 0;
            context.fill();
            context.stroke();
        }
        // 20毫秒后繪制下一幀
        setTimeout(drawFrame, 20);
    }
  • 調用并且初始化小球

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

推薦閱讀更多精彩內容

  • 1. Canvas繪制五環(huán) 2.Canvas繪制餅狀圖以及繪制文字 3. Canvas繪制一堆不斷變大變小的隨機移...
    LiLi原上草閱讀 1,324評論 0 7
  • 一:canvas簡介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標簽 ②:HTML5 ...
    GreenHand1閱讀 4,704評論 2 32
  • 一、基礎介紹和畫直線 大多數(shù)現(xiàn)代瀏覽器都是支持Canvas的,比如 Firefox, safari, chrome...
    空谷悠閱讀 855評論 0 1
  • 一、canvas簡介 1.1 什么是canvas?(了解) 是HTML5提供的一種新標簽 Canvas是一個矩形區(qū)...
    Looog閱讀 3,949評論 3 40
  • 一、圖形的組合方式 globalAlpha是一個介于0和1之間的值(包括0和1),用于指定所有繪制的透明度。默認值...
    空谷悠閱讀 1,299評論 0 0