Canvas从入门到放弃 (三)

在慕课网上学习了 Canvas绘图详解 这门教程,写了这篇canvas教程,想和大家分享学习的过程,希望和大家共同进步.=_=
前几天更新了第二篇,现在趁热打铁最后一点知识

效果展示.png

1. 绘制弧线

1.1 绘制一段弧

在画布上创建一段圆弧
参数说明:圆心x坐标,圆心y坐标,起始角度,结束角度,是否逆时针绘制

 context.arc( x, y, r, start, end, [anticlockwise])

默认情况下anticlockwise = false,即顺时针绘制

起始角度,和结束角度单位都是弧度

弧度.png

完整代码请戳Lesson3/demo1.html

 window.onload = function () {
    var canvas = document.getElementById("canvas");
    canvas.width = 1000;
    canvas.height = 500;
    var context = canvas.getContext("2d");

    context.lineWidth = 5;
    context.strokeStyle = "#005588";
     //第一行
    for (var i = 0; i < 10; i++) {
        context.beginPath();
        context.arc(50 + i * 100, 60, 40, 0, 2 * Math.PI*(i + 1) / 10);
        context.stroke();
    }
    //第二行
    for (var i = 0; i < 10; i++) {
        context.beginPath();
        context.arc(50+ i * 100, 180, 40, 0, 2 * Math.PI*(i + 1) / 10);
        context.closePath();
        context.stroke();
    }
    //第三行
    for (var i = 0; i < 10; i++) {
        context.beginPath();
        context.arc(50 + i * 100, 300, 40, 0, 2 * Math.PI*(i + 1) / 10,true);
        context.stroke();
     }
    //第四行
    for (var i = 0; i < 10; i++) {
        context.beginPath();
        context.arc(50+ i * 100, 420, 40, 0, 2 * Math.PI*(i + 1) / 10,true);
        context.closePath();
         context.stroke();
    }
 }
  • 这十段弧线是从 0 pi起始,绘制1/10段弧线,2/10段弧线,3/10段弧线......
  • 第一行弧线 顺时针绘制
  • 第二行弧线 顺时针绘制,并且使用了closePath(),使得首尾连接
  • 第三行弧线 逆时针绘制
  • 第四行弧线 逆时针绘制,并且使用了closePath(),使得首尾连接
绘制弧线.png
1.2 绘制圆角矩形

我们可以分为八部分绘制,如果设置左上角的圆心坐标为 (0,0),四个1/4圆的半径是r,那么圆心坐标如下:

圆角矩形.png

完整代码请戳Lesson3/demo2.html

     window.onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");

        strokeRoundRect(context, 200, 100, 300,200, 50)
    };

  //绘制圆角矩形
    function strokeRoundRect(cxt, x, y, width, height, r, lineWidth,strokeColor) {
        cxt.save();
        cxt.translate(x, y);

        pathRoundRect(cxt, width, height, r);

        cxt.lineWidth = lineWidth || 1;
        cxt.strokeStyle = strokeColor || '#005588';
        cxt.stroke();
        cxt.restore();
    }
  //绘制圆角矩形的路径
    function pathRoundRect(cxt, width, height, r) {
        cxt.beginPath();
        //右下的圆
        cxt.arc(width - r, height - r, r, 0,Math.PI / 2);
        //下面的线
        cxt.lineTo(r, height);
        //左下的圆
        cxt.arc(r, height - r, r, Math.PI / 2, Math.PI);
        //左边的线
        cxt.lineTo(0, r);
        //左上的圆
        cxt.arc(r, r, r, Math.PI, Math.PI * 3 / 2);
        //上边的线
        cxt.lineTo(width - r, 0);
        //右上的圆
        cxt.arc(width - r, r, r, Math.PI * 3 / 2, Math.PI * 2);
        //右边的线,用closePath来首尾连接
        cxt.closePath();
    }
1.3 绘制一个棋盘格

完整代码请戳Lesson3/demo3.html

     window.onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 1000;
        canvas.height = 600;
        var context = canvas.getContext("2d");
     //先填充一个大的圆角矩形
        fillRoundRect(context, 150, 50, 500,500, 10, "#bbada0");
        //在填充4行4列的小圆角矩形
        for(var i = 0; i< 4;i++) {
            for(j = 0;j< 4;j++) {
                fillRoundRect(context, 170+i*120, 70+j*120, 100,100, 6, "#ccc0b3");
            }
        }
    };
  //填充圆角矩形
    function fillRoundRect(cxt, x, y, width, height, r, fillColor) {
        cxt.save();
        cxt.translate(x, y);
        pathRoundRect(cxt, width, height, r);
        cxt.fillStyle = fillColor || '#005588';
        cxt.fill();
        cxt.restore();
    }
  //绘制圆角矩形的路径
    function pathRoundRect(cxt, width, height, r) {
        cxt.beginPath();
        //右下
        cxt.arc(width - r, height - r, r, 0,Math.PI / 2);
        //下面
        cxt.lineTo(r, height);
        //左下
        cxt.arc(r, height - r, r, Math.PI / 2, Math.PI);
        //左边
        cxt.lineTo(0, r);
        //左上
        cxt.arc(r, r, r, Math.PI, Math.PI * 3 / 2);
        //上边
        cxt.lineTo(width - r, 0);
        //右上
        cxt.arc(width - r, r, r, Math.PI * 3 / 2, Math.PI * 2);
        //右边
        cxt.closePath();
    }
2048棋盘格.png

2. 另一种绘制弧线的方法

arcTo() : 在画布上创建介于两个切线之间的弧

x1,y1是控制点,x2,y2是线条的结束点,r是弧线的半径

context.arcTo(x1, y1, x2, y2, r)
  • (x0,y0)是当前点的坐标
  • 这段圆弧与这两条线相切
  • (x0,y0)不一定是圆弧的起点,(x2,y2)不一定是圆弧的终点
  • 这段弧的终止点是与(x1,y1),(x2,y2)这条线相切的点
arcTo().png

完整代码请戳Lesson3/demo4.html

      window.onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 1000;
        canvas.height = 700;
        var context = canvas.getContext("2d");

        //用arcTo绘制弧线
        context.beginPath();
        context.moveTo(100, 100);
        context.arcTo(550, 100, 550, 550, 300);

        context.lineWidth = 3;
        context.strokeStyle = "#E5786E";
        context.stroke();

        context.closePath();

        //辅助线
        context.beginPath();
        context.moveTo(100, 100);
        context.lineTo(550, 100);
        context.lineTo(550, 550);

        context.lineWidth = 1;
        context.strokeStyle = "black";
        context.stroke();

        context.closePath();
    }
2.1 用arcTo()绘制一轮弯月
弯月.png
  • 月亮的外层 是一段用arc()绘制圆弧, 圆心H(400,400), 半径是300
  • 月亮的内层 是用arcTo()绘制的一段弧,设定参照点C(1200,400)
    arcTo()参数中(x1,y1),(x2,y2)分别对应C点,B点,半径(即OA的长度)则需要计算.可根据两点之间坐标公式可得AC 长度,再根据
    tan ACO来计算R(OA之间的距离).

完整代码请戳Lesson3/demo5.html

   window.onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 1000;
        canvas.height = 800;
        var context = canvas.getContext("2d");
        //圆心坐标(400,400),半径300,从0.5Pi到1.5Pi逆时针绘制一段圆弧
        context.arc(400, 400, 300, 0.5 * Math.PI, 1.5 * Math.PI, true);
    //将起始点移动到(400,100)
        context.moveTo(400, 100);
        //R = (AC*AH)/HC,其中AC用两点距离坐标来计算
        context.arcTo(1200, 400, 400, 700, (400 - 100) * dis(400, 100, 1200, 400) / (1200 - 400));
        context.stroke();
    };
  //计算两个坐标之间的距离
    function dis(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }
2.2 将绘制的弯月挂到星空上

完整代码请戳Lesson3/demo6.html

星空月亮.png

3. 二次贝塞尔曲线

它比arcTo()更加的实用,与arcTo()非常的相似

context.moveTo(x0,y0) 
context.quadraticCurveTo(x1,y1,x2,y2) 
  • 指定起始点(x0,y0)终止点(x2,y2)控制点(x1,y1)
  • 这里的起始点和终止点就是真正的起始点和终止点,所以画出的并不是真正的圆弧,而是曲线。

观察二次贝塞尔曲线的地址

二次贝塞尔曲线.png

3.1 用二次贝塞尔曲线画一轮弯月

完整代码请戳Lesson3/demo7.html

二次贝塞尔曲线.png

4.三次贝塞尔曲线

二次贝塞尔曲线很方便的绘制出曲线,但是不能满足更多的要求.三西贝塞尔曲线拥有两个控制点,可以绘制花瓣、波浪效果等 .

context.moveTo(x0,y0) 
context.bezierCurveTo(x1,y1,x2,y2,x3,y3) 
  • (x1,y1), (x2,y2)是控制点,(x3,y3)是结束点

观察三次贝塞尔曲线的地址

三次贝塞尔曲线.png

4.1 用三次贝塞尔曲线在星空图中画出草地

完整代码请戳Lesson3/demo8.html

星空草地.png

5. 绘制文字

  • font默认值:20px sans-serif
context.font = font-style | font-variant | font-weight | font-size | font-family
context.font = "bold 40px Arial";
context.fillText(string,x,y,[maxlen]);//有填充色的字
context.strokeText(string,x,y,[maxlen]);//有描边的字
  • font属性可以接受像css中font的样式
  • 第一个参数是书写的字符串,x,y指的是书写的位置
  • 可选参数maxlen 表示绘制这行文字可使用的最长宽度

完整代码请戳Lesson3/demo9.html

    window.onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 700;
        canvas.height = 400;
        var context = canvas.getContext("2d");

        context.font = "bold 30px Arial";

        //第一行字有填充色
        context.fillStyle = "#058";
        context.fillText("欢迎大家学习《Canvas从入门到放弃(三)》!", 40, 40);

        //第二行字描边
        context.strokeStyle = "#058";
        context.strokeText("欢迎大家学习《Canvas从入门到放弃(三)》!", 40, 100);

        //第三行字
        context.fillStyle = "#058";
        context.fillText("欢迎大家学习《Canvas从入门到放弃(三)》!", 40, 160,400);

        //第四行字
        context.strokeStyle = "#058";
        context.strokeText("欢迎大家学习《Canvas从入门到放弃(三)》!", 40, 210,400);

        //渐变颜色字
        var linearGrad = context.createLinearGradient(0, 0, 800, 0);
        linearGrad.addColorStop(0, '#efb164');
        linearGrad.addColorStop(0.25, '#f1ec5d');
        linearGrad.addColorStop(0.5, '#bde379');
        linearGrad.addColorStop(0.75, '#7bd3ab');
        linearGrad.addColorStop(1, '#b2c9e9');
        context.fillStyle = linearGrad;
        context.fillText("欢迎大家学习《Canvas从入门到放弃(三)》!", 40, 270);
    }
绘制文字.png

最终将文字加到星空图中

完整代码请戳Lesson3/demo10.html

星空.png

Canvas的入门知识教程到这里就完结了,要深入学习还需多看课程多实践,各位道友继续加油!

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

推荐阅读更多精彩内容

  • 转载请声明 原文链接 关注公众号获取更多资讯 这篇文章主要总结H5的一些新增的功能以及一些基础归纳,这里只是一个提...
    程序员poetry阅读 9,068评论 22 225
  • 来源: http://www.douban.com/group/topic/14820131/ 调整变量格式: f...
    MC1229阅读 6,911评论 0 5
  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,674评论 2 32
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    Looog阅读 3,940评论 3 40
  • (转自http://www.douban.com/group/topic/14820131/,转自人大论坛) 调整...
    f382b3d9bdb3阅读 10,342评论 0 8