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替代内容


如果不支持就用文本代替,不过如今大多数浏览器已经可以支持了,所以我也找不到浏览器测试是否可以用一张图片代替。

 <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";
        //前两个参数数位置x、y,后两个参数是宽、高
        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');
    //前两个参数指定开始的点的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');
      // 这个数组用于保存画布上出现的所有球
      var balls = [];
    
  • 构建一个气泡对象

        // 用于表示球的所有细节的Ball函数
      // 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;
      }
    
  • 向数组添加小球

      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;
          }
          // 创建新的ball对象
          var ball = new Ball(x,y);
          // 将其保存在balls数组中
          balls.push(ball);
      }
    
  • 绘制图像并且在20ms后再次绘制

    function drawFrame() {
        // 清除画布
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        // 循环所有的球,并重新定义他们的位置和大小

        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();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • 1. Canvas绘制五环 2.Canvas绘制饼状图以及绘制文字 3. Canvas绘制一堆不断变大变小的随机移...
    LiLi原上草阅读 1,261评论 0 7
  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,607评论 2 32
  • 一、基础介绍和画直线 大多数现代浏览器都是支持Canvas的,比如 Firefox, safari, chrome...
    空谷悠阅读 772评论 0 1
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    Looog阅读 3,862评论 3 40
  • 一、图形的组合方式 globalAlpha是一个介于0和1之间的值(包括0和1),用于指定所有绘制的透明度。默认值...
    空谷悠阅读 1,187评论 0 0