Canvas从入门到放弃 (一)

在慕课网上学习了 Canvas绘图详解 这门教程,写了这篇canvas教程,想和大家分享学习的过程,希望和大家共同进步.=_=

1.基础必备

在HTML中创建Canvas画布

<canvas id="canvas"></canvas>

在Js文件中获取Canvas画布,以及绘图环境

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

2.绘制线条

2.1 画一条直线

moveTo(), lineTo() 进行状态的设置
stroke(); 进行实际的绘制

Canvas是基于状态的设置,不是基于对象的设置(并没有创建一个线条对象来设置线条的属性,而是设置context的属性)
完整代码请戳Lesson1/demo1.html

 //假设有个笔尖移动到 (100,100)这个位置
 context.moveTo(100, 100);
 //创建到达位置 (400,100) 的一条线
 context.lineTo(400, 100);
 //进行线条粗细设置
 context.lineWidth = 5;
 //进行线条样式设置
 context.strokeStyle = "#058";
 //绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
 context.stroke();

![一条直线.png](http://upload-images.jianshu.io/upload_images/3474771-7a34f7269150129c.png?

Canvas-三角形.png

imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.2 画多条直线

  • 使用lineTo()画出首尾连接的图形

完整代码请戳Lesson1/demo2.html

//画一个三角形
//假设有个笔尖移动到 (100,100)这个位置
context.moveTo(100, 100);
context.lineTo(300, 300);
context.lineTo(100, 300);
context.lineTo(100, 100);

context.lineWidth = 5;
context.strokeStyle = "#058";
context.stroke();
多条直线.png
  • 使用moveTo()画出组合图形

完整代码请戳Lesson1/demo3.html

    //画一个组合图形
    context.moveTo(100, 100);
    context.lineTo(300, 300);
    context.lineTo(100, 500);

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

    context.moveTo(300, 100);
    context.lineTo(500, 300);
    context.lineTo(300, 500);
组合图形.png

那么问题来了,如果想要绘制不同状态的线条呢?

2.3 beginPath()

开始一条路径
完整代码请戳Lesson1/demo4.html

    //开始一条路径
    context.beginPath();
    context.moveTo(100, 100);
    context.lineTo(300, 300);
    context.lineTo(100, 500);
    context.lineWidth = 5;
    context.strokeStyle = "#058";
    context.stroke();
    
    //开始一条路径
    context.beginPath();
    context.moveTo(200, 100);
    context.lineTo(400, 300);
    context.lineTo(200, 500);
    context.lineWidth = 5;
    context.strokeStyle = "#ffcc99";
    context.stroke();
    
    //开始一条路径
    context.beginPath();
    context.moveTo(300, 100);
    context.lineTo(500, 300);
    context.lineTo(300, 500);
    context.lineWidth = 5;
    context.strokeStyle = "#ff99cc";
    context.stroke();
beginPath.png

2.4 closePath()

创建从当前点到开始点的路径.
完整代码请戳Lesson1/demo5.html

  • 以demo2为例,比较用lineTo()和closePath()实现封闭的区别.
  • (在lineWidth小的情况下可能看不出区别,但大的情况就有明显的区别)
  • 要绘制封闭的多边形,使用成对的beginPath(), closePath()
    //画一个三角形
    context.beginPath();
    context.moveTo(100, 100);
    context.lineTo(300, 300);
    context.lineTo(100, 300);
    context.closePath();

    context.lineWidth = 5;
    context.strokeStyle = "#058";
    context.stroke();
closePath.png

对比.png

2.5 填充样式,矩形

  • 填充样式主要用到 fillStyle(),** fill()**方法

完整代码请戳Lesson1/demo6.html

    context.beginPath();
    context.moveTo(100, 100);
    context.lineTo(300, 300);
    context.lineTo(100, 300);
    context.closePath();
 
    context.lineWidth = 5;
    context.fillStyle = "#058";
    context.fill();
填充.png
  • 绘制矩形可以用 rect()方法
  • 或用 fillRect()strokeRect()

完整代码请戳Lesson1/demo7.html

rect() 方法规划矩形的路径
fillRect(), strokeRect() 不止规划路径,还绘制出矩形

//使用rect()方法
function drawRect(cxt, x, y, width, height, borderWidth, borderColor, fillColor) {
        cxt.beginPath();
        cxt.rect(x, y, width, height);
        cxt.closePath();

        cxt.lineWidth = borderWidth;
        cxt.strokeStyle = borderColor;
        cxt.fillStyle = fillColor;

        cxt.fill();
        cxt.stroke();
    }
//使用fillRect(), strokeRect()方法
function drawRect2(cxt, x, y, width, height, borderWidth, borderColor, fillColor) {
        cxt.lineWidth = borderWidth;
        cxt.strokeStyle = borderColor;
        cxt.fillStyle = fillColor;

        cxt.fillRect(x, y, width, height);
        cxt.strokeRect(x, y, width, height);
    }
矩形.png

2.6 线条属性

  • lineWidth 设置线条的宽度
  • lineCap 设置线条末端线帽的样式。

lineCap属性值:
buff 默认。向线条的每个末端添加平直的边缘。
round 向线条的每个末端添加圆形线帽。
square 向线条的每个末端添加正方形线帽。
完整代码请戳Lesson1/demo8.html

        //buff 线条的末端平直的边缘。
        context.beginPath();
        context.moveTo(100, 100);
        context.lineTo(400, 100);
        context.lineCap = "butt";
        context.stroke();

        //round 线条的末端圆形线帽
        context.beginPath();
        context.moveTo(100, 200);
        context.lineTo(400, 200);
        context.lineCap = "round";
        context.stroke();

        //square 线条的末端正方形线帽。
        context.beginPath();
        context.moveTo(100, 300);
        context.lineTo(400, 300);
        context.lineCap = "square";
        context.stroke();

        //参照线 baseLine
        context.lineWidth = 2;
        context.strokeStyle = "#555";

        context.beginPath();
        context.moveTo(100, 60);
        context.lineTo(100, 350);
        context.stroke();

        context.beginPath();
        context.moveTo(400, 60);
        context.lineTo(400, 350);
        context.stroke();
lineCap.png

3. 实战--绘制五角星

可以写定五角星的10个坐标点,但是这里为了复用五角星的绘制函数,寻找各坐标点之间的规律,动态的生成五角星各个坐标点.

我们将五角星外侧的五个顶点看作在一个大圆中,内侧的五个顶点看做在一个同心的小圆中

五角星.png
18°.png
54°.png

大圆上的五个角平分一个圆,每个角的度数:360° / 5 = 72°
图中表示的较小角:90° - 72° = 18°
图中表示的较大角:72° / 2 + 18° = 54°

那么重点来了,这10个坐标点该如何表示呢?
先复习一下三角函数 & 弧度制
正弦值——对边/斜边 即sin()
余弦值——邻边/斜边 即cos()
角度转弧度——弧度 = 角度*π / 180

坐标表示.png

R 表示大圆半径
r 表示小圆半径
x 表示横坐标偏移量(即圆心横坐标)
y 表示纵坐标偏移量(即圆心纵坐标)
大圆和小圆上的顶点,后一个比前一个的角度大72度(逆时针)
完整代码请戳Lesson1/demo9.html

//调用函数drawStar
 drawStar(context, 200, 100, 250, 250);
==============================================
     function drawStar(cxt, R, r, x, y) {
        cxt.beginPath();
        for (var i = 0; i < 5; i++) {
            //绘制大圆上的五个坐标点
            cxt.lineTo(Math.cos((18 + i * 72) / 180 * Math.PI) * R + x,
                    -Math.sin((18 + i * 72) / 180 * Math.PI) * R + y);
            //绘制小圆上的五个坐标点
            cxt.lineTo(Math.cos((54 + i * 72) / 180 * Math.PI) * r + x,
                    -Math.sin((54 + i * 72) / 180 * Math.PI) * r + y);
        }
        cxt.closePath();
        cxt.stroke();
    }
五角星.png

=====================  华 丽 的 分 割 线   ==================

如果觉得我写的还不错,请继续关注下一节教程
下节预告:绘制一片星空,图形的变换,填充样式(渐变色,使用图片,canvas等)

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

推荐阅读更多精彩内容

  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,604评论 2 32
  • 在慕课网上学习了 Canvas绘图详解 这门教程,写了这篇canvas教程,想和大家分享学习的过程,希望和大家共同...
    爱可不可爱_90845阅读 742评论 3 8
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    Looog阅读 3,856评论 3 40
  • 书中代码示例效果展示:Core HTML5 Canvas Examples 基础知识 canvas元素 canva...
    szu_bee阅读 2,700评论 2 28
  • 入夜,突然发现,好久好久没感受到这么安静的夜了,没有人声,没有车声,连客厅里冰箱的声音都静止了,唯一的声音就是我翻...
    拂晓听雪阅读 538评论 0 2