canvas画圆角矩形

1. 第一种方式:使用lineTo画直线和quadraticCurveTo(二次贝塞尔曲线)画圆弧

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>canvas demo</title>
</head>

<body>
    <canvas id="canvas" width="400" height="400"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        roundedRect(ctx, 0, 0, canvas.width, canvas.height, 20, 'black');

        // 绘制圆角矩形
        function roundedRect(ctx, x, y, width, height, radius, color) {
            ctx.strokeStyle = color;
            ctx.beginPath();
            ctx.moveTo(x+radius, y);
            ctx.lineTo(x+width - radius, y);
            ctx.quadraticCurveTo(x+width, y, x+width, y+radius); // 右上圆角
            ctx.lineTo(x+width, y+height - radius);
            ctx.quadraticCurveTo(x+width, y+height, x+width-radius, y+height); // 右下圆角
            ctx.lineTo(x+radius, y+height);
            ctx.quadraticCurveTo(x, y+height, x, y+height-radius); // 左下圆角
            ctx.lineTo(x, y+radius);
            ctx.quadraticCurveTo(x, y, x+radius, y); // 左上圆角
            ctx.stroke();
        }
    </script>
</body>

</html>

2. 第二种方式:使用SVG path

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>canvas demo</title>
</head>

<body>
    <canvas id="canvas" width="400" height="400"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        roundedRect(ctx, 0, 0, canvas.width, canvas.height, 20, 'black');

        // 绘制圆角矩形
        function roundedRect(ctx, x, y, width, height, radius, color) {
            ctx.strokeStyle = color;
            const mdWidth = width-2*radius;
            const mdHeight = height-2*radius;
            const path = new Path2D(
                `M${x+radius} ${y}
                h${mdWidth} q${radius} 0, ${radius} ${radius}
                v${mdHeight} q0 ${radius}, ${-radius} ${radius}
                h${-mdWidth} q${-radius} 0, ${-radius} ${-radius}
                v${-mdHeight}
                q0 ${-radius}, ${radius} ${-radius}`
             );
            ctx.stroke(path);
        }
    </script>
</body>

</html>

3. 效果

image

4. 分析

  • SVG path中,大写字母是绝对路径,小写字母是相对路径
  • M相当于moveTo,L是lineTo,Q是二次贝塞尔曲线(一个控制点和一个结束点)
  • 闭合命令Z和z不区分大小写
  • 命令后面可以紧跟坐标,也可空格,如M0 0和M 0 0是相等的
  • 一组坐标之间的x1和y1以空格隔开即可,如Mx1 y1
  • 多组坐标以逗号隔开,如Qx1 y1, x2 y2

image

5. 更多path命令

https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/d#路径命令

posted @ 2023-01-29 16:43  pangqianjin  阅读(912)  评论(0)    收藏  举报