萌新的Canvas笔记(四)

前言

今天我的小伙伴硬是怼出了一个坦克大战秀给我看,让我亚历山大,更加坚定了发愤图强的决心。。。TI6在即,然而也没有多少时间看胖头鱼吹牛了。

关于曲线的绘制


arc(x, y, radius, startAngle, endAngle, anticlockwise =false)

用于绘制一个圆弧,参数依次表示:x坐标 y坐标 半径 圆弧开始位置 圆弧结束位置 最后一个参数默认表示顺时针方向,如果为true 则为逆时针

画一个圆角矩形

在CSS中,可以用border-radius属性来让矩形的四个角变成圆角。其实也可以用canvas实现。
这里写图片描述

通过简单分析,可以知道绘制这样一个圆角矩形需要的参数是:
宽度,高度,小圆的半径,以及绘制的位置和context。
实现方法,从右下角开始(也可以从左上角),找到右下角圆心,顺时针绘制一个四分之一圆弧,再绘制一条直线到左下角,再绘制一个四分之一圆弧,再绘制一条直线到左上角……以此类推;
代码:

    function drawRoundRect(cxt, x, y, width, height, radius,/*option*/linewidth, /*option*/linecolor){
                cxt.save();

                cxt.translate(x, y);
                pathRoundRect(cxt, width, height, radius);

                cxt.lineWidth = linewidth || 1;
                cxt.strokeStyle = linecolor ||"black";
                cxt.stroke();
                cxt.restore();
            }

    function pathRoundRect(cxt, width, height, radius){
                cxt.beginPath();

                cxt.arc(width - radius, height - radius, radius, 0, Math.PI/2);
                cxt.lineTo(width - radius, height); 

                cxt.arc(radius, height - radius, radius, Math.PI/2, Math.PI);
                cxt.lineTo(0, radius);

                cxt.arc(radius, radius, radius, Math.PI, Math.PI/2 * 3);    
                cxt.lineTo(width - radius, 0);

                cxt.arc(width - radius, radius, radius, Math.PI/2 * 3, Math.PI * 2);

                cxt.closePath();

            }

流程:
先平移坐标轴到指定位置,再开始绘制路径。绘制路径函数为pathRoundRect();
主要为这两个函数,稍微修改一下,就可以绘制2048游戏的矩形图。

代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>绘制圆角矩形</title>
    </head>
    <body>
        <canvas id="canvas" width="" height="">
            您的浏览器不支持canvas
        </canvas>
    </body>
    <script type="text/javascript">
            var canvas = document.getElementById("canvas");
            var context = canvas.getContext("2d");
            canvas.width = 800;
            canvas.height = 800;

            //drawRoundRect(context, 100, 100, 600, 500, 50);

            fillRoundRect(context, 150, 150, 500, 500, 10, "#bbada0");

            for(var i = 0; i < 4; i ++){
                for(var j = 0; j < 4; j ++){
                    fillRoundRect(context, 170 + i * 120, 170 + j * 120, 100, 100, 6, "#ccc0b3");

                }
            }
            function drawRoundRect(cxt, x, y, width, height, radius,/*option*/linewidth, /*option*/linecolor){
                cxt.save();

                cxt.translate(x, y);
                pathRoundRect(cxt, width, height, radius);

                cxt.lineWidth = linewidth || 1;
                cxt.strokeStyle = linecolor ||"black";
                cxt.stroke();
                cxt.restore();
            }

            function fillRoundRect(cxt, x, y, width, height, radius, /*option*/fillcolor){
                cxt.save();

                cxt.translate(x, y);
                pathRoundRect(cxt, width, height, radius);

                cxt.fillStyle = fillcolor || "black";
                cxt.fill();
                cxt.restore();
            }

            function pathRoundRect(cxt, width, height, radius){
                cxt.beginPath();

                cxt.arc(width - radius, height - radius, radius, 0, Math.PI/2);
                cxt.lineTo(width - radius, height); 

                cxt.arc(radius, height - radius, radius, Math.PI/2, Math.PI);
                cxt.lineTo(0, radius);

                cxt.arc(radius, radius, radius, Math.PI, Math.PI/2 * 3);    
                cxt.lineTo(width - radius, 0);

                cxt.arc(width - radius, radius, radius, Math.PI/2 * 3, Math.PI * 2);

                cxt.closePath();

            }


    </script>
</html>

效果:
这里写图片描述
其中小方块的位置需要计算一下,也不复杂。注意间隔为20个像素,小方块长宽为100,圆角半径为6. 知道这些参数以后就可以轻易计算出每个的位置。

一个不好用的函数 arcTo

同样的是用来绘制一段弧,与arc不同的是,所需要的参数不一样,绘制原理也不一样。简单来说,这玩意就是 
    以当前的点为初始值,以参数中的第一个点连接,第一个点与第二个点连接。
    绘制一条半径为radius的与这两条线段相切的弧

有点晕?
来看代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>arcTo--一个不怎么好用的函数。。</title>
    </head>
    <body>
        <canvas id="canvas" width="" height=""></canvas>
    </body>
    <script type="text/javascript">
    //arcTo(x1, y1, x2, y2, radius)   
    //以当前的点为初始值,以参数中的第一个点连接,第一个点与第二个点连接。
    //绘制一条半径为radius的与这两条线段相切的弧
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        canvas.width = 800;
        canvas.height = 800;

        context.save();
        context.beginPath();

        context.moveTo(150, 150);
        context.arcTo(650, 150, 650, 650, 300);

        context.lineWidth = 6;
        context.strokeStyle = "red";
        context.stroke();

        context.closePath();
        context.restore();

        context.beginPath();

        context.moveTo(150, 150);
        context.lineTo(650, 150);
        context.lineTo(650, 650);

        context.stroke();

        context.closePath();

    </script>
</html>

效果:
这里写图片描述
就是这样,会以这两条线段为切线,作一段半径为radius的弧。
起始位置是当前的画笔位置,而不是切线位置。
当然,如果起始位置过劲,则会反向寻找切点。所以线段的长度并不重要。

重头戏-贝塞尔曲线

贝塞尔曲线是一种应用广泛的曲线。能够绘制出任意的、不规则的弧。

函数:
context.quadraticCurveTo(x1, y1, x2, y2);

与arcTo不同的是,他不需要指定弧的半径,而且起始点与终止点就是弧的起始点与终止点。

与arcTo相同的是,他的起始点都是当前画笔所在的点。
例:

        context.beginPath();
        context.moveTo(100, 100);
        context.quadraticCurveTo(400, 400, 100, 500);
        context.stroke();

效果:
这里写图片描述

附上视频中推荐的贝塞尔曲线的交互式网址 http://tinvurl.com/html5quadratic
反正我是打不开。

贝塞尔三次曲线

与二次曲线的区别是,三次曲线拥有两个控制点,而二次曲线只有一个控制点。
这使得贝塞尔三次曲线可以更加灵活的绘制弧。

        context.beginPath();
        context.moveTo(100, 100);
        context.bezierCurveTo(150, 50, 200, 150, 250, 100);

效果:
这里写图片描述

至于具体的计算。。学过图形学的应该会,反正我不会,到时候慢慢调试就好。

以上~

PS:陆陆续续终于把曲线的部分结束了,接下来就是文字的渲染和高级内容了,加油~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值