zoukankan      html  css  js  c++  java
  • 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绘制图形感兴趣的同学,请持续关注后续更新,如有不对的地方也请指出并多多交流。

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

  • 相关阅读:
    List内存分配
    《深入理解JAVA虚拟机》笔记1
    oracle(三)
    常见排序算法
    C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
    C++ Primer 有感(异常处理)(四)
    C++ Primer 有感(异常处理)(三)
    C++ Primer 有感(异常处理)(二)
    C++ Primer 有感(异常处理)
    C++ Primer 有感(多重继承与虚继承)
  • 原文地址:https://www.cnblogs.com/beevesnoodles/p/7061426.html
Copyright © 2011-2022 走看看