Drawing Paths
Paths are the foundation of complex shapes in FxCanvas, allowing you to create custom geometry from lines, curves, and arcs. Unlike simple shapes like rectangles or ellipses, paths give you complete control over the outline of your drawings.
Understanding Paths
A path is a sequence of connected points and curves that define a shape's boundary. You build paths step by step, then fill them with color or stroke their outlines. Paths are essential for creating irregular shapes, logos, icons, and organic forms.
Paths are frequently stroked for outlines; see Working with Strokes.
Creating and Building Paths
All path operations start with beginPath(), which clears any existing path and starts a new one.
import { CanvasEncoder } from 'fxcanvas';
const canvas = new CanvasEncoder(400, 200);
// Start a new path
canvas.beginPath();Moving the Pen
The moveTo(x, y) method moves the drawing cursor to a new position without drawing.
canvas.beginPath();
canvas.moveTo(50, 50); // Move to starting pointDrawing Straight Lines
The lineTo(x, y) method draws a straight line from the current position to the specified point.
canvas.beginPath();
canvas.moveTo(50, 50);
canvas.lineTo(150, 50); // Draw horizontal line
canvas.lineTo(150, 100); // Draw vertical line
canvas.stroke();Path Building Methods
FxCanvas provides convenient methods to add common shapes directly to paths, combining the simplicity of shape methods with the flexibility of custom paths.
Adding Rectangles
The rect(x, y, width, height) method adds a rectangular subpath to the current path:
canvas.beginPath();
canvas.rect(50, 50, 100, 100); // Add rectangle to path
canvas.stroke();This creates a rectangular outline that can be combined with other path elements. For basic rectangle drawing without paths, see Drawing Rectangles.
Adding Rounded Rectangles
The roundRect(x, y, width, height, radii?) method adds a rounded rectangular subpath:
canvas.beginPath();
canvas.roundRect(50, 50, 200, 100, 20); // Uniform corner radius
canvas.fill();
// Different radii per corner
canvas.beginPath();
canvas.roundRect(50, 50, 200, 100, [10, 20, 30, 40]); // [TL, TR, BR, BL]
canvas.stroke();Rounded rectangles in paths allow for complex shapes with smooth corners. For direct rounded rectangle drawing, see Drawing Rectangles.
Adding Ellipses
The ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle) method adds an elliptical arc to the path:
canvas.beginPath();
// Full ellipse centered at (100, 100) with radii 50x30
canvas.ellipse(100, 100, 50, 30, 0, 0, Math.PI * 2);
canvas.stroke();
// Partial ellipse (semicircle)
canvas.beginPath();
canvas.ellipse(100, 100, 50, 30, 0, 0, Math.PI); // Top half
canvas.stroke();The ellipse method provides full control over elliptical shapes in paths. For basic ellipse drawing, see Drawing Ellipses.
Paths can be used for clipping; see Clipping and Masking.
Drawing Quadratic Curves
Quadratic curves create smooth, single-control-point curves, perfect for gentle bends.
The quadraticCurveTo(cpx, cpy, x, y) method draws a curve to the endpoint using one control point.
canvas.beginPath();
canvas.moveTo(50, 100);
canvas.quadraticCurveTo(100, 50, 150, 100); // Control point at (100, 50)
canvas.stroke();The control point pulls the curve toward it, creating a smooth bend.
Drawing Bézier Curves
Bézier curves offer more complex curves with two control points, allowing for S-shaped curves and precise control.
The bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) method draws a curve using two control points.
canvas.beginPath();
canvas.moveTo(50, 100);
canvas.bezierCurveTo(75, 50, 125, 150, 150, 100); // Two control points
canvas.stroke();The first control point affects the start of the curve, the second affects the end.
Closing Paths
The closePath() method draws a line back to the path's starting point, creating a closed shape.
canvas.beginPath();
canvas.moveTo(50, 50);
canvas.lineTo(150, 50);
canvas.lineTo(150, 100);
canvas.closePath(); // Draws line back to (50, 50)
canvas.stroke();Filling and Stroking Paths
Once you've built a path, you can fill it or stroke its outline.
Filling Paths
The fill() method fills the path with the current fill style.
canvas.beginPath();
canvas.moveTo(50, 50);
canvas.lineTo(150, 50);
canvas.lineTo(100, 100);
canvas.closePath();
canvas.setFillStyle(new Color(173, 216, 230))); // lightblue
canvas.fill();Paths support advanced compositing modes; see Composite Operations.
Stroking Paths
The stroke() method draws the path outline with the current stroke settings.
canvas.beginPath();
canvas.moveTo(50, 50);
canvas.lineTo(150, 50);
canvas.lineTo(100, 100);
canvas.closePath();
canvas.setStrokeStyle(new Color(0, 0, 139))); // darkblue
canvas.setLineWidth(3);
canvas.stroke();Combining Fill and Stroke
canvas.setFillStyle(new Color(255, 255, 0))); // yellow
canvas.setStrokeStyle(new Color(255, 165, 0))); // orange
canvas.setLineWidth(2);
canvas.beginPath();
// ... build path ...
canvas.closePath();
canvas.fill();
canvas.stroke();Advanced Path Techniques
Drawing Arcs
The arc(x, y, radius, startAngle, endAngle, anticlockwise?) method adds a circular arc to the path.
canvas.beginPath();
canvas.arc(100, 100, 50, 0, Math.PI * 1.5); // 270-degree arc
canvas.stroke();Complex Shapes
// Draw a star
canvas.beginPath();
const centerX = 100, centerY = 100;
const outerRadius = 50, innerRadius = 25;
const spikes = 5;
for (let i = 0; i < spikes * 2; i++) {
const radius = i % 2 === 0 ? outerRadius : innerRadius;
const angle = (i * Math.PI) / spikes;
const x = centerX + Math.cos(angle) * radius;
const y = centerY + Math.sin(angle) * radius;
if (i === 0) canvas.moveTo(x, y);
else canvas.lineTo(x, y);
}
canvas.closePath();
canvas.setFillStyle(new Color(255, 215, 0))); // gold
canvas.fill();Path Clipping
Paths can be used to create clipping regions that limit drawing to within the path.
// Create clipping path
canvas.beginPath();
canvas.arc(100, 100, 50, 0, Math.PI * 2);
canvas.clip();
// Subsequent drawing is clipped to the circle
canvas.setFillStyle(new Color(255, 0, 0))); // red
canvas.fillRect(50, 50, 100, 100); // Only the circular portion appearsPath Reusability
Complex paths can be built in functions for reuse:
function drawHeart(encoder, x, y, size) {
canvas.beginPath();
canvas.moveTo(x, y + size / 4);
canvas.quadraticCurveTo(x, y, x + size / 4, y);
canvas.quadraticCurveTo(x + size / 2, y, x + size / 2, y + size / 4);
canvas.quadraticCurveTo(x + size / 2, y, x + size * 3/4, y);
canvas.quadraticCurveTo(x + size, y, x + size, y + size / 4);
canvas.quadraticCurveTo(x + size, y + size / 2, x + size / 2, y + size);
canvas.quadraticCurveTo(x, y + size / 2, x, y + size / 4);
canvas.closePath();
}
drawHeart(encoder, 50, 50, 50);
canvas.setFillStyle(new Color(255, 0, 0))); // red
canvas.fill();Mastering paths unlocks the full creative potential of FxCanvas, allowing you to create any shape imaginable.