Path Builder – Create SVG Paths in C#

Create SVG Path with Aspose.SVG

SVG paths are one of the most powerful SVG features for creating custom vector graphics, curves, outlines, and complex shapes. Using Aspose.SVG Builder API, developers can create SVG path elements programmatically in C# with readable fluent syntax instead of manually writing SVG path data strings.

This article explains how to create SVG paths in C#, build complex vector graphics programmatically, and use SVG text paths with Aspose.SVG for .NET.

Path Builder

The PathBuilder class simplifies SVG path creation by providing methods for common SVG path commands such as M (move to), L (line to), C (cubic Bézier curve), Q (quadratic Bézier curve), A (arc), and Z (close path).

The Aspose.SVG Builder API provides the SVGPathElementBuilder class for constructing SVG <path> elements programmatically. Using PathBuilder, developers can define SVG path commands with fluent chained methods that improve code readability and simplify SVG generation.

SVG paths are commonly used for:

Builders within Builders

The SVG Builder API introduces syntax sugar to further refine the process of SVG creation and manipulation. This includes nested builders for various SVG elements, providing a more intuitive and efficient way to define complex SVG structures.

A “builder within a builder” pattern involves the use of multiple builder classes, where one builder is nested within another to facilitate the construction of complex objects or structures. In this pattern, the outer builder constructs a higher-level object or container, while the inner builder is responsible for constructing a component or sub-object within that container.

In the following code snippet, PathBuilder is an example of a builder within a builder, illustrating a nested builder pattern. Here, the SVGSVGElementBuilder serves as the outer builder responsible for creating the <svg> element. In SVGSVGElementBuilder, an instance of PathBuilder is used to construct a <path> element, which is the element inside the <svg> root element.

1using Aspose.Svg.Builder;
2using System.Drawing;
3using System.IO;
 1// Create an SVG path element with line commands programmatically in C# using SVG Path Builder
 2
 3// Initialize an SVG document
 4using (SVGDocument document = new SVGDocument())
 5{
 6    // Create an <svg> element with specified width, height and viewBox, and add a <path> element to it
 7    SVGSVGElement svg = new SVGSVGElementBuilder()
 8        .Width(200).Height(200)
 9        .ViewBox(0, 0, 150, 150)
10
11        .AddPath(p => p
12        // 'D' method defines the 'd' attribute, which contains the path data
13        .D(d => d
14        // 'M' sets the starting point of the path (Move to x=50, y=50)
15        .M(50, 50)
16        // 'L' draws a line from the current point to the new point (Line to x=100, y=50)
17        .L(100, 50)
18        // Another 'L' to draw a line to a new point (Line to x=100, y=100)
19        .L(100, 100)
20        // 'Z' closes the path by drawing a line to the starting point
21        .Z())
22        // Sets the fill color of the path to teal 
23        .Fill(Color.Teal))
24        .Build(document.FirstChild as SVGSVGElement);
25
26    // Save the SVG document
27    document.Save(Path.Combine(OutputDir, "path.svg"));
28}

How the Path Works

In this example, the AddPath() method of the SVG builder is used to define a <path> element. The D() method defines SVG path data using SVG path commands. In this example:

The fluent syntax simplifies SVG path generation and makes path definitions easier to read and maintain.

SVG Path Commands Supported by PathBuilder

PathBuilder supports SVG absolute and relative path commands for creating lines, curves, arcs, and complex vector graphics programmatically. These commands can be combined to create complex SVG shapes, smooth curves, vector illustrations, and reusable graphical components in C#.

CommandRelative CommandDescription
MmMove the current point to a new position
LlDraw a straight line to a point
HhDraw a horizontal line
VvDraw a vertical line
CcDraw a cubic Bézier curve
SsDraw a smooth cubic Bézier curve
QqDraw a quadratic Bézier curve
TtDraw a smooth quadratic Bézier curve
AaDraw an elliptical arc
ZzClose the current path

Add Custom SVG Path Data

Path data can also be added directly as a string using the AddPathSegment() method.

1.D(d => d.AddPathSegment(
2    "M199 89 C206 66 235 25 270 30 286 38 298 59 310 73"
3))

This approach is useful when importing existing SVG path data or working with externally generated SVG graphics.

Create SVG Curves and Bézier Paths

SVG paths support quadratic and cubic Bézier curves for creating smooth vector graphics and complex outlines.

 1using Aspose.Svg.Builder;
 2using System.Drawing;
 3using System.IO;
 4
 5using (SVGDocument document = new SVGDocument())
 6{
 7    // Create an <svg> element with specified width, height and viewBox, and add a <path> element to it
 8    SVGSVGElement svg = new SVGSVGElementBuilder()
 9        .Width(500).Height(500)
10        .ViewBox(0, 0, 400, 400)
11
12        .AddPath(p => p
13            .D(d => d
14            .M(80, 210)
15            .Q(95, 110, 200, 200)
16            .T(350, 200)
17        )
18        // Sets the fill color of the path to red
19        .Fill(Color.Red))
20        .Build(document.FirstChild as SVGSVGElement);
21
22    // Save the SVG document
23    document.Save(Path.Combine(OutputDir, "curve-path.svg"));
24}

In this example:

Curve commands are commonly used for illustrations, charts, signatures, and decorative SVG graphics.

SVG TextPath

SVG can place text along a path defined by a <path> element. This is made by a <textPath> element with attribute href. The text displaying along the curve mostly takes attribute href with reference to the <path> element. Below is an example of how SVG textPath can be implemented using SVG Builder API:

1using Aspose.Svg.Builder;
2using System.Drawing;
3using System.IO;
 1// Create SVG text path in C# using SVG Builder
 2
 3// Initialize an SVG document
 4using (SVGDocument document = new SVGDocument())
 5{
 6    // Create an <svg> element with specified width, height, and viewBox, and add into it <path> elements
 7    SVGSVGElement svg = new SVGSVGElementBuilder()
 8        .Width(1200).Height(300)
 9        .ViewBox(0, 0, 1200, 300)
10
11        .AddPath(p => p.Id("Path1")
12            .Fill(f => f.None()).Stroke(Color.IndianRed).Transform(t => t.Translate(-100, 40))
13            .D(d => d.AddPathSegment("M 199 89 C 206 66 235 25 270 30 286 38 298 59 310 73 321 87 338 99 356 103 387 111 396 90 410 85"))
14         )
15
16        .AddPath(p => p.Id("Path2")
17            .Fill(f => f.None()).Stroke(Paint.None).Transform(t => t.Translate(400, -100))
18            .D(d => d.M(80, 210).Q(95, 110, 200, 200).T(400, 200)))
19
20
21         .AddText(t => t.FontSize(30).Fill(Color.Teal)
22             .AddTextPath(tp => tp
23                 .Href("#Path1")
24                 .AddContent("SVG textPath element")
25              )
26             .AddTextPath(tp => tp
27                  .Href("#Path2")
28                  .AddContent("SVG can place text along a path")
29              )
30         )
31
32        .Build(document.FirstChild as SVGSVGElement);
33
34    // Save the SVG document
35    document.Save(Path.Combine(OutputDir, "text-path.svg"));
36}

In the example, we create two paths with different id attributes. The paths are created using different approaches – the first path uses the AddPathSegment() method, and the second path uses the M(), Q(), and T() methods. Also, the first path is colored, but the second is transparent. The SVG <textPath> element refers to the id attribute of the <path> element in the SVG document, which allows text to be displayed along this predefined path:

Visualization of the text-path.svg file with text following SVG curves.

In this example, we also use the builders within builders. The outer builder SVGSVGElementBuilder is responsible for constructing the <svg> element, while nested builders are used to add <path> elements and <text> elements with <textPath> elements inside them. The builders within builders pattern simplifies the construction of complex SVG documents by breaking down the process into hierarchical layers of builders. This pattern promotes encapsulation, readability, and flexibility, making it easier for developers to create and manipulate SVG documents efficiently.

Common Mistakes and Fixes

ProblemPossible CauseRecommended Fix
The SVG path is not visibleMissing fill or stroke stylesApply Fill() or Stroke() to the path element
The path shape appears incompleteThe path is not closedUse the Z() command to close the path
Text does not follow the curveIncorrect path referenceEnsure Href() matches the path Id() value
Curves appear distortedIncorrect control point coordinatesAdjust Bézier curve control points
Imported SVG path data does not render correctlyInvalid SVG path syntaxValidate the SVG path string before importing

Quick Recipes

1. Create a simple triangle

 1using (SVGDocument document = new SVGDocument())
 2{
 3    SVGSVGElement svg = new SVGSVGElementBuilder()
 4        .Width(200).Height(200)
 5        .ViewBox(0, 0, 150, 150)
 6        .AddPath(p => p
 7            .D(d => d
 8            .M(50, 150)
 9            .L(150, 150)
10            .L(100, 50)
11            .Z())
12        .Fill(Color.Teal))
13        .Build(document.FirstChild as SVGSVGElement);
14    document.Save("triangle.svg");
15}

2. Add a path segment

1    .AddPath(p => p
2        .Fill(Color.IndianRed)
3        .D(d => d.AddPathSegment("M10 75 Q150 0 290 75"))
4        )

3. Combine multiple segments

 1    .AddPath(p => p
 2    .Fill(Color.CadetBlue)
 3    .Stroke(Color.Red)
 4    .StrokeWidth(2)
 5    .D(d => d
 6        .AddPathSegment("M40 120")
 7        .AddPathSegment("C70 20 140 20 170 120")
 8        .AddPathSegment("S270 220 300 120")
 9        .AddPathSegment("Q250 180 170 170")
10        .AddPathSegment("Q90 160 40 120")
11        )
12    )

Note: The first recipe is a complete example. The other recipes are fragments that should be incorporated into a full SVG document creation workflow.

FAQ

1. Is PathBuilder better than writing SVG path strings manually?
For complex SVG graphics, PathBuilder is usually easier to maintain and debug than manually concatenating SVG path strings. Fluent path commands improve readability and reduce the risk of malformed SVG path syntax.

2. Why are SVG paths commonly used instead of basic shapes?
SVG paths provide much greater flexibility than simple elements such as <rect> or <circle>. A single path can represent highly complex vector graphics, curves, and compound shapes.

3. Can I convert existing SVG path data into PathBuilder commands?
Yes. Existing SVG d attribute values can be translated into fluent PathBuilder commands or inserted directly using path segment methods.

4. Are SVG paths resolution-independent?
Yes. SVG paths are vector-based and scale without losing quality, making them suitable for responsive graphics, high-resolution displays, and print workflows.

5. Can SVG paths contain multiple disconnected shapes?
Yes. A single SVG path can contain multiple subpaths by using multiple M (move to) commands within the same path definition.

6. What is the difference between relative and absolute SVG path commands?
Absolute commands use fixed SVG coordinates, while relative commands calculate positions relative to the current drawing point. Relative commands are often used to create more compact SVG markup.

Related Resources

Close
Loading

Analyzing your prompt, please hold on...

An error occurred while retrieving the results. Please refresh the page and try again.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.