Try   HackMD

Generating SVG Rounded-corner Rectangle paths

with variant redii values

To draw a rectangle with vaiant radii we need to use s combination od the SVG path commands:

  • MoveTo: M , m.
  • LineTo: L , l , H , h , V , v.
  • ClosePath: Z , z.
  • Elliptical Arc Curve: A , a.

Drawing arcs using the element is done using the A and a commands. Like with lines, the uppercase command (A) uses absolute coordinates for its endpoint, where the lowercase command (a) uses relative coordinates (relative to the start point). Here is an example:

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">

    <path d="M50,50
             A30,50 0 0,1 100,100"
          style="stroke:#660000; fill:none;"/>
</svg>

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

This example draws an arc from the point 50,50 to the point 100,100 (specified last in the A command).

The radius of the arc is set by the two first parameters set on the A command. The first parameter is rx (radius in x-direction) and the second is ry (radius in y-direction). Setting rx and ry to the same value will result in a circular arc. Setting rx and ry to different values will result in an elliptical arc. In the example above rx was set to 30 and ry to 50.

The third parameter set on the A command is the x-axis-rotation. This sets the rotation of the arc's x-axis compared to the normal x-axis. In the above example the x-axis-rotation is set to 0. Most of the time you will not need to change this parameter.

The fourth and fifth parameters are the large-arc-flag and sweep-flag parameters. The large-arc-flag determines whether to draw the smaller or bigger arc satisfying the start point, end point and rx and ry

Now it is time to combine the four previous path commands to draw a rounded corners rectangle:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

As the colored segments showing, the rectangle has been drawn segment by segment. Here are the drawing steps:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

The SVG path for the example:

<svg viewbox="-300 -10 1000 1000">
  <path d="M-90,0
  h380 
  a30,30 0 0 1 
  30,30
  v350
  a60,60 0 0 1 
  -60,60
  h-360 
  a80,80 0 0 1 
  -80,-80
  v-270 
  a90,90 0 0 1 
  90,-90 z"
        stroke="rgba(255, 122, 0, 0.8)" fill="rgb(255,255,255)" stroke-width="20"/>
</svg>

Here is a quick Python implementation doing the job:

class SVGRECT():

    def __init__(self, width, height, radii, start_coord):
        
        
        self.width = width
        self.height = height
        self.radii = radii
        self.x_1, self.y_1 = start_coord        
        self.r_1, self.r_2, self.r_3, self.r_4 = radii
    
    
    def get_svg_rect_path(self):


        d = f'''"M{self.x_1},{self.y_1}
          h{self.width - (self.r_4 + self.r_1)}
          a{self.r_1},{self.r_1} 0 0 1 {self.r_1},{self.r_1}
          v{self.height - (self.r_1 + self.r_2)}
          a{self.r_2},{self.r_2} 0 0 1 -{self.r_2},{self.r_2}
          h-{self.width - (self.r_2 + self.r_3)} 
          a{self.r_3},{self.r_3} 0 0 1 -{self.r_3},-{self.r_3}
          v-{self.height - (self.r_3 + self.r_4)}
          a{self.r_4},{self.r_4} 0 0 1 {self.r_4},-{self.r_4}
          z"'''
        d_removed_nl = re.sub('\n',' ',d)
        d_removed_extra_spaces = re.sub(' +',' ',d_removed_nl)
        return d_removed_extra_spaces
    
    def get_svg_rect_file(self):
        path = self.get_svg_rect_path()

        return f'''<svg xmlns="http://www.w3.org/2000/svg" viewBox= "{self.x_1-100} {self.y_1-100} 1000 1000" >
  <path d={path} stroke="rgba(255, 122, 0, 0.8)" fill="rgb(255,255,255)" stroke-width="20"/>
</svg>'''
    
    def save_svg(self, file_path, svg_content):
        open(file_path, 'w', encoding='utf-8').write(svg_content)

Example of use:


width, height = 500, 440
radii = (30, 60, 80, 90)
start_coord = (200, 200)

svg = SVGRECT(width, height, radii, start_coord)
svg_file_content = svg.get_svg_rect_file()
svg.save_svg('sample.svg', svg_file_content)

The code is hosted on Google Colab here. You can try it dirctly.