Canvas从入门到放弃 (三)

作者: 爱可不可爱_90845 | 来源:发表于2017-07-18 11:31 被阅读0次

    在慕课网上学习了 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的入门知识教程到这里就完结了,要深入学习还需多看课程多实践,各位道友继续加油!

    相关文章

      网友评论

        本文标题:Canvas从入门到放弃 (三)

        本文链接:https://www.haomeiwen.com/subject/ytlihxtx.html