--- title: Paths order: 40 --- Paths are the lines and curves that make up your pattern. They are made up of individual drawing operations that together make up the path. FreeSewing supports the following types of drawing operations: - The **move** operation moves our virtual pen but does not draw anything. - The **line** operation draws a straight line - The **curve** operation draws a [Bézier curve](/guides/prerequisites/bezier-curves) - The **close** operation closes the path To crucial thing to keep in mind is that, with the exception of the **move** operation, all drawing operations start from wherever you are currently on your virtual sheet of paper. For example, you might expect the **line** operation to take a start- and endpoint. But in fact, it only takes an endpoint, and will draw a straight line from where our virtual pen currently is to said endpoint. Because all but the **move** drawing operations are relative to their operation preceding it, **all Paths must start with a move operation**. Understanding that each drawing operation builds upon the next one is an important insight. ```mjs ({ Point, points, Path, paths, options, part }) => { // Draws a w*h box, returns a Path object const box = (name, origin, width, height, classes='fabric') => { let base = height if (width < height) base = width let t = base points[name + 'TopLeft'] = new Point(origin.x, origin.y) points[name + 'BottomLeft'] = new Point(origin.x, origin.y + height) points[name + 'BottomRight'] = new Point( origin.x + width, origin.y + height ) points[name + 'TopRight'] = new Point(origin.x + width, origin.y) points[name + 'Mid'] = points[name + 'TopLeft'].shiftFractionTowards( points[name + 'BottomRight'], 0.5 ) points[name + 'Mid'].y += 3 return new Path() .move(points[name + 'TopLeft']) .line(points[name + 'BottomLeft']) .line(points[name + 'BottomRight']) .line(points[name + 'TopRight']) .line(points[name + 'TopLeft']) .close() .addClass(classes) } // Draws a box and handled text placement const drawBox = (name, x, y, width, height, text=true, classes, textClasses='') => { points[name + 'Origin'] = new Point(x, y) paths[name] = box(name, points[name + 'Origin'], width, height, classes) if (text === 'b') { paths[name+'_label'] = new Path() .move(points[name+'BottomLeft']) .line(points[name+'BottomRight']) .addClass('hidden') .addText(name, 'center ' + textClasses) .attr('data-text-dy', -1) } else if (text) points[name + 'Mid'].addText(name, 'center') } // Parts set 0 drawBox('Part A (set 0)', -27, -27, 44, 70, 'b', 'note', 'bold') drawBox('points', -24, -24, 38, 12, true, 'note') drawBox('paths', -24, -9, 38, 12, true, 'note fill-note') paths['paths'].attr('fill-opacity', 0.2) drawBox('snippets', -24, 6, 38, 12, true, 'note') drawBox('Part B (set 0)', 26, -27, 44, 70, 'b', 'note', 'bold') drawBox(' points ', 29, -24, 38, 12, true, 'note') drawBox(' paths ', 29, -9, 38, 12, true, 'note fill-note') paths[' paths '].attr('fill-opacity', 0.2) drawBox(' snippets ', 29, 6, 38, 12, true, 'note') drawBox('Part C (set 0)', 79, -27, 44, 70, 'b', 'note', 'bold') drawBox(' points ', 82, -24, 38, 12, true, 'note') drawBox(' paths ', 82, -9, 38, 12, true, 'note fill-note') paths[' paths '].attr('fill-opacity', 0.2) drawBox(' snippets ', 82, 6, 38, 12, true, 'note') drawBox('setStore 0', -24, 21, 144, 12, true, 'lining dashed') paths['setStore 0'].attr('fill-opacity', 0.2) // Pattern drawBox('Pattern Store', -30, -45, 155, 15, true, 'lining') paths['Pattern Store'].attr('fill-opacity', 0.2) drawBox('Pattern', -34, -49, 163, 106, 'b', 'fabric stroke-lg', 'text-lg bold') return part } ``` Our example image (which, if you hadn't realized was created with FreeSewing) has a lot of paths in it. Each box, the arrows, the lines in the React logo, and so on. Click the **X-Ray** tab to reveal them.