Day 11: How to Draw Quadratic Bézier Curves with SVG

The path element becomes really powerful when we start using curves, such as the quadratic Bezier curve. For a curve, we also have to set a control point apart from the endpoint.

The control point is an invisible coordinate to which the line is bending. Drag the coordinates below to see how it works.

A smile is a simple image we can create using a quadratic Bezier curve. Look at this happy face! Hover over the curve below to see the invisible control point.

In this image, we also introduce a new element, the ellipse. An ellipse behaves like a circle, except it has not one but two radiuses: a horizontal one and a vertical one.

-100, -100
0, 0 -25, -25 25, -25 -40, 30 0, 60 40, 30 0, 0 -25, -25 25, -25 -40, 30 0, 60 40, 30
200, 200
<svg 
  width="200"
  height="200"
  viewBox="-100 -100 200 200"
>
  <circle
    cx="0"
    cy="0"
    r="90"
    fill="none"
    stroke="black"
    stroke-width="10" />
  <ellipse 
    cx="-25" 
    cy="-25" 
    rx="10" 
    ry="15" />
  <ellipse 
    cx="25" 
    cy="-25" 
    rx="10" 
    ry="15" />
  <path
    d="M -40,30 Q 0,30 40,30"
    fill="none"
    stroke="black"
    stroke-width="10"
    stroke-linecap="round" />
</svg>

In the example above, the control point is at the same distance from the two endpoints, but this is not necessary. In the example below, the control point is moved to the right. Hover over the image to see the control point.

-100, -100
-60, 50 40, -50 40, 50 -60, 50 40, -50 40, 50
200, 200
<svg 
  width="200"
  height="200"
  viewBox="-100 -100 200 200"
>
  <path 
    d="
      M -60,50 
      Q 40,-50 40,50" 
    fill="none"
    stroke="black"
    stroke-width="10"
  />
</svg>

In today’s example, we have a series of quadratic beziers where the control points get further and further away from the center of the tree as the path goes down.

<svg width="200" height="400" viewBox="-100 -200 200 400">
  <path
    d="
      M 0 -80
      Q 5 -75 0 -70
      Q -10 -65 0 -60
      Q 15 -55 0 -50
      Q -20 -45 0 -40
      Q 25 -35 0 -30
      Q -30 -25 0 -20
      Q 35 -15 0 -10
      Q -40 -5 0 0
      Q 45 5 0 10
      Q -50 15 0 20
      Q 55 25 0 30
      Q -60 35 0 40
      Q 65 45 0 50
      Q -70 55 0 60
      Q 75 65 0 70
      Q -80 75 0 80
      Q 85 85 0 90
      Q -90 95 0 100
      Q 95 105 0 110
      Q -100 115 0 120
      L 0 140
      L 20 140
      L -20 140"
    fill="none"
    stroke="#0C5C4C"
    stroke-width="5"
  />
</svg>

If we break down each quadratic bézier above into two line segments with the same coordinates, that would look like this:

-100, -200
0, -80 5, -75 0, -70 -10, -65 0, -60 15, -55 0, -50 -20, -45 0, -40 25, -35 0, -30 -30, -25 0, -20 35, -15 0, -10 -40, -5 0, 0 45, 5 0, 10 -50, 15 0, 20 55, 25 0, 30 -60, 35 0, 40 65, 45 0, 50 -70, 55 0, 60 75, 65 0, 70 -80, 75 0, 80 85, 85 0, 90 -90, 95 0, 100 95, 105 0, 110 -100, 115 0, 120 0, 140 20, 140 -20, 140 0, -80 5, -75 0, -70 -10, -65 0, -60 15, -55 0, -50 -20, -45 0, -40 25, -35 0, -30 -30, -25 0, -20 35, -15 0, -10 -40, -5 0, 0 45, 5 0, 10 -50, 15 0, 20 55, 25 0, 30 -60, 35 0, 40 65, 45 0, 50 -70, 55 0, 60 75, 65 0, 70 -80, 75 0, 80 85, 85 0, 90 -90, 95 0, 100 95, 105 0, 110 -100, 115 0, 120 0, 140 20, 140 -20, 140
200, 400
<svg 
  width="200"
  height="400"
  viewBox="-100 -200 200 400"
>
  <path 
    d="
      M 0 -80
      L 5 -75 L 0 -70
      L -10 -65 L 0 -60
      L 15 -55 L 0 -50
      L -20 -45 L 0 -40
      L 25 -35 L 0 -30
      L -30 -25 L 0 -20
      L 35 -15 L 0 -10
      L -40 -5 L 0 0
      L 45 5 L 0 10
      L -50 15 L 0 20
      L 55 25 L 0 30
      L -60 35 L 0 40
      L 65 45 L 0 50
      L -70 55 L 0 60
      L 75 65 L 0 70
      L -80 75 L 0 80
      L 85 85 L 0 90
      L -90 95 L 0 100
      L 95 105 L 0 110
      L -100 115 L 0 120
      L 0 140
      L 20 140
      L -20 140"
    fill="none"
    stroke="black"
  />
</svg>