• canvas学习总结四:绘制虚线


    上一章节我们说到,线性路径的绘制,主要利用movoTo(),lineTo()等方法,当然 Canvas 2D API 也提供了虚线的绘制方法,CanvasRenderingContext2D.setLineDash();

    下面我们就来看看虚线的绘制方法

    语法

    ctx.setLineDash(segments);

    参数 segments:

    一个Array数组。

    一组描述交替绘制线段和间距(坐标空间单位)长度的数字。

    如果数组元素的数量是奇数, 数组的元素会被复制并重复。例如, [5, 15, 25] 会变成 [5, 15, 25, 5, 15, 25]。

    这里最后一句话有可能我们没有看明白,没关系我们继续往下看。

    我们先绘一条简单的虚线

    function drawDashed(){
      cxt.lineWidth = 4;
      cxt.strokeStyle = 'green';
      cxt.beginPath();
      cxt.setLineDash([5, 15]);
      cxt.moveTo(20, 20);
      cxt.lineTo(400, 20);
      cxt.stroke();
    }

    因此绘制虚线也是非常简单,我们试着改变setLineDash()方法的参数看看结果有什么不同

    function drawDashed(){
      cxt.lineWidth
    = 4; cxt.strokeStyle = 'green'; cxt.beginPath(); cxt.setLineDash([5]); cxt.moveTo(0, 60); cxt.lineTo(400, 60); cxt.stroke(); cxt.lineWidth = 4; cxt.strokeStyle = 'red'; cxt.beginPath(); cxt.setLineDash([]); cxt.moveTo(0, 100); cxt.lineTo(400, 100);
      cxt.stroke();
    }


    从这个例子我们可以看出当我们的参数数组只有一个元素时我们的 “线段与间隔” 是相等的,当参数数组的元素为空时,我们绘制的是一条实线。

    我们在来看几个例子

    function drawDashed(){
        cxt.lineWidth = 4;
    
        cxt.strokeStyle = 'blue';
        cxt.beginPath();
        cxt.setLineDash([20, 5]);
        cxt.moveTo(20, 40);
        cxt.lineTo(380, 40);
        cxt.stroke();
    
        cxt.strokeStyle = 'green';
        cxt.beginPath();
        cxt.setLineDash([10, 20, 30]);
        cxt.moveTo(20, 80);
        cxt.lineTo(380, 80);
        cxt.stroke();
    
        cxt.strokeStyle = 'red';
        cxt.beginPath();
        cxt.setLineDash([10, 20, 30, 40]);
        cxt.moveTo(20, 120);
        cxt.lineTo(380, 120);
        cxt.stroke();
    }

    有上图几个例子我们可以看出,setLineDash()方法是根据参数中的元素在 “线段与间隔” 之间形成组,然后进行循环,进而绘制出虚线。

    但是第二个例子当中我们传入的参数的元素个数是基数,看起来和参数元素为偶数时有点区别,它会复制元素并重复,

    这就是我们开始所说的 如果参数 segments元素的数量是奇数, 数组的元素会被复制并重复。[10, 20, 30] 会变成 [10, 20, 30, 10, 20, 30]。

    getLineDash 方法


    有setLineDash的方法去设置虚线的线段与间距,相应的有个方法是获取虚线的线段和间距的方法。

    ctx.getLineDash()

    该方法返回一个 Array数组。一组描述交替绘制线段和间距(坐标空间单位)长度的数字。如果数组元素的数量是奇数,数组元素会被复制并重复。 例如, 设置线段为 [5, 15, 25] 将会得到以下返回值 [5, 15, 25, 5, 15, 25]。

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    ctx.setLineDash([5, 15]);
    ctx.beginPath();
    ctx.moveTo(0,100);
    ctx.lineTo(400, 100);
    ctx.stroke();
    console.log(ctx.getLineDash()); // [5, 15]

    扩展CanvasRenderingContext2D  绘制虚线

    我们不仅可以利用 canvas API 绘制虚线,我们还可以扩展一个自己绘制虚线的方法。
    扩展思路:
    1. 获取起点坐标
    2. 计算虚线的总长度,计算虚线包含多少短线然后循环绘制

    话不多说,我们直接上代码

    var canvas = document.getElementById('canvas');
    var cxt = canvas.getContext('2d');
    var moveToFunction = CanvasRenderingContext2D.prototype.moveTo;
    CanvasRenderingContext2D.prototype.moveToLocation = {};
    // 重新定义moveTo方法
    CanvasRenderingContext2D.prototype.moveTo = function (x, y){
        this.moveToLocation.x = x;
        this.moveToLocation.y = y;
        moveToFunction.apply(this, [x, y]);
    };
    CanvasRenderingContext2D.prototype.dashedLineTo = function(x, y, dashedLength){
        dashedLength = dashedLength === undefined ? 5 : dashedLength;
        var startX = this.moveToLocation.x;
        var startY = this.moveToLocation.y;
        var deltaX = x - startX;
        var deltaY = y - startY;
        var numberDash = Math.floor(Math.sqrt(deltaX*deltaX + deltaY*deltaY)/dashedLength);
        for(var i=0; i < numberDash; i++){
            this[i%2 === 0 ? 'moveTo' : 'lineTo'](startX + (deltaX/numberDash)*i, startY + (deltaY/numberDash)*i); //等同于this.moveTo(x, y)或者 this.LineTo(x, y)
        }
        this.moveTo(x, y); //连续绘制虚线时,起点从当前点开始
    };
    //绘制虚线
    cxt.lineWidth = 3;
    cxt.strokeStyle = 'green';
    cxt.moveTo(20, 20);
    cxt.dashedLineTo(200, 200);
    cxt.dashedLineTo(300, 100, 10);
    cxt.dashedLineTo(400, 300);
    cxt.stroke();

     

    总结:

    我们可以通过setLineDash()方法绘制虚线,该方法会以参数的元素个数为 的形式去进行 循环 绘制,但是要注意传入方法是参数的元素个数

    我们还可以自定义扩展绘制虚线的方法,主要就是获取起点进而计算线段数进行循环绘制

    对canvas绘制图形感兴趣的同学,请持续关注后续更新,如有不对的地方也请指出并多多交流。

    如需转载,还请注明出处,非常感谢!

  • 相关阅读:
    149. Max Points on a Line(js)
    148. Sort List(js)
    147. Insertion Sort List(js)
    146. LRU Cache(js)
    145. Binary Tree Postorder Traversal(js)
    144. Binary Tree Preorder Traversal(js)
    143. Reorder List(js)
    142. Linked List Cycle II(js)
    141. Linked List Cycle(js)
    140. Word Break II(js)
  • 原文地址:https://www.cnblogs.com/beevesnoodles/p/7061426.html
Copyright © 2020-2023  润新知