html 虚线_canvas2D绘制虚线

c33d7c2756d2ae8b4ff1014b71b849e8.png

要想在canvas 2D中绘制虚线有很多种方法,可以自己使用算法实现,也可以使用原生的API。

一、自己使用算法实现虚线绘制

大概思路是:

  • 求出虚线段的个数
  • 再逐一生成虚线段的路径

这里只使用了勾股定理这一个数学公式。

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>虚线绘制1</title>
</head>
<body>
    <canvas id="canvas" width="300" height="200"></canvas>

    <script>
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d');

        function drawDashedLine(x1, y1, x2, y2, dashLength = 5){
            let deltaX = x2 - x1;
            let deltaY = y2 - y1;
            // 求虚线段的个数
            let dashNums = Math.floor(
                Math.sqrt(deltaX*deltaX + deltaY*deltaY) / dashLength
            );
            // 生成虚线段的路径
            context.beginPath();
            for(let i = 0; i < dashNums; i++){
                let nextX = x1 + (deltaX / dashNums) * i;
                let nextY = y1 + (deltaY / dashNums) * i;
                if(i % 2 === 0){
                    context.moveTo(nextX, nextY);
                }else{
                    context.lineTo(nextX, nextY);
                }
            }
            
            context.stroke
            // 绘制虚线段
            context.stroke();
        }

        drawDashedLine(0, 0, canvas.width, canvas.height, 6);
    </script>
</body>
</html>

效果:

88d32374595c5bea2180060194254435.png

二、在绘图环境中扩展虚线API

如果能将上面自己实现的虚线绘制功能绑定到Canvas 2D的绘图环境对象中那不是更好吗?

可以使用元编程来完成!

由于虚线的起始点是通过调用moveTo()方法来确定的,所以在Canvas2D的绘图环境对象中增加一个生成虚线路径的函数的主要难点是:在这个函数中不能取得这个起始点的数据。

所以重点是确保生成虚线路径的函数中能访问到起始点数据。

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>虚线绘制2</title>
</head>
<body>
    <canvas id="canvas" width="300" height="200"></canvas>

    <script>
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d');

        // 另存一份moveTo函数
        const moveToFunction = CanvasRenderingContext2D.prototype.moveTo;
        // 在原型对象中开辟一个变量用于存储传入moveTo()的参数值
        CanvasRenderingContext2D.prototype.moveToLocation = {};
        // 重新定义moveTo方法
        CanvasRenderingContext2D.prototype.moveTo = function(x, y){
            moveToFunction.call(context, x, y); 
            this.moveToLocation.x = x;
            this.moveToLocation.y = y;
            console.log(1);
        }
        // 在绘图环境中扩展dashedLineTo()方法
        CanvasRenderingContext2D.prototype.dashedLineTo = function drawDashedLine(x, y, dashLength = 5){
            let deltaX = x - this.moveToLocation.x;
            let deltaY = y - this.moveToLocation.y;
            // 求虚线段的个数
            let dashNums = Math.floor(
                Math.sqrt(deltaX*deltaX + deltaY*deltaY) / dashLength
            );
            // 生成虚线段的路径
            let startX = this.moveToLocation.x;
            let startY = this.moveToLocation.y;
            for(let i = 0; i < dashNums; i++){
                let nextX = startX + (deltaX / dashNums) * i;
                let nextY = startY + (deltaY / dashNums) * i;
                if(i % 2 === 0){
                    context.moveTo(nextX, nextY);
                }else{
                    context.lineTo(nextX, nextY);
                }
            }
            this.moveTo(x, y);
        }

        context.moveTo(0, 0);
        context.dashedLineTo(canvas.width, canvas.height);
        context.stroke();
    </script>
</body>
</html>

效果:

d75fce48fdecfb483195ef64924e516a.png

三、使用原生API绘制虚线

canvas2D已经有原生API支持生成虚线路径了。

setLineDash(segments)方法用于指定在填充时使用虚线模式。

segments参数是一个数组,一组描述交替绘制线段和间距(坐标空间单位)长度的数字。 如果数组元素的数量是奇数, 数组的元素会被复制并重复。例如, [5, 15, 25]会变成[5, 15, 25, 5, 15, 25]。

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>虚线绘制3</title>
</head>
<body>
    <canvas id="canvas" width="300" height="200"></canvas>

    <script>
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext('2d');
        // 设置填充线时使用虚线模式
        context.setLineDash([5, 5]);
        context.moveTo(0, 0);
        context.lineTo(canvas.width, canvas.height);
        context.stroke();
    </script>
</body>
</html>

效果:

3ca86181d7034a71490976995bed87ed.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值