--- title: Completing our pattern order: 260 --- When we say we're going to *complete* our pattern, we mean we're going to add things like a title and a scalebox and so on. These things or not always wanted on a pattern. For example, if you're cutting out patterns with a laser cutter, or tracing them with a projects, you typically only want to have the pattern outline. ## The complete setting Users can indicate their desire to have either a bare-bones pattern, or rather when that's completed with all bells and whistles with [the `complete` setting](/reference/settings/complete). To make sure we respect the user's choice, we must wrap all of these embellishments in a code block that only executes when the `complete` setting is *truthy*. To access the setting, we can destructure it: ```mjs function draftBib({ Path, Point, paths, points, measurements, options, macro, // highlight-start complete, // highlight-end part, }) { // Our earlier work is not shown for brevety // highlight-start if (complete) { // Complete pattern here } // highlight-end return part } ``` ## Adding snippets Snippets are little re-useable things to embellish your pattern with. Things like buttons or buttonholes, a logo, or snaps. To use them, much like points and paths, we need to destructure both the `Snippet` constructure as well as the `snippets` object to hold our snippets: ```mjs function draftBib({ Path, Point, paths, points, measurements, options, macro, complete, // highlight-start Snippet, snippets, // highlight-end part, }) { // Our earlier work is not shown for brevety if (complete) { // Complete pattern here } return part } ``` We'll be using them below to add a `snap-stud`, `snap-socket`, and a `logo` snippet. You can find all possible snippets in [our documentation](/reference/api/snippet/). ## The completed design Let's put this and few other things together to complete our design: ```js function draftBib({ Path, Point, paths, points, measurements, options, macro, // highlight-start complete, snippets, Snippet, // highlight-end part, }) { // Construct the quarter neck opening let tweak = 1 let target = (measurements.head * options.neckRatio) /4 let delta do { points.right = new Point(tweak * measurements.head / 10, 0) points.bottom = new Point(0, tweak * measurements.head / 12) points.rightCp1 = points.right.shift(90, points.bottom.dy(points.right)/2) points.bottomCp2 = points.bottom.shift(0, points.bottom.dx(points.right)/2) paths.quarterNeck = new Path() .move(points.right) .curve(points.rightCp1, points.bottomCp2, points.bottom) .hide() // Add this line delta = paths.quarterNeck.length() - target if (delta > 0) tweak = tweak * 0.99 else tweak = tweak * 1.02 } while (Math.abs(delta) > 1) // Construct the complete neck opening points.rightCp2 = points.rightCp1.flipY() points.bottomCp1 = points.bottomCp2.flipX() points.left = points.right.flipX() points.leftCp1 = points.rightCp2.flipX() points.leftCp2 = points.rightCp1.flipX() points.top = points.bottom.flipY() points.topCp1 = points.bottomCp2.flipY() points.topCp2 = points.bottomCp1.flipY() // Drawing the bib outline const width = measurements.head * options.widthRatio const length = measurements.head * options.lengthRatio points.topLeft = new Point( width / -2, points.top.y - (width / 2 - points.right.x) ) points.topRight = points.topLeft.shift(0, width) points.bottomLeft = points.topLeft.shift(-90, length) points.bottomRight = points.topRight.shift(-90, length) // Shape the straps points.edgeLeft = new Point(points.topLeft.x, points.left.y) points.edgeRight = new Point(points.topRight.x, points.right.y) points.edgeTop = new Point(0, points.topLeft.y) points.edgeLeftCp = points.edgeLeft.shiftFractionTowards(points.topLeft, 0.5) points.edgeRightCp = points.edgeLeftCp.flipX() points.edgeTopLeftCp = points.edgeTop.shiftFractionTowards( points.topLeft, 0.5 ) points.edgeTopRightCp = points.edgeTopLeftCp.flipX() // Round the straps const strap = points.edgeTop.dy(points.top) points.tipRight = points.edgeTop.translate(strap / 2, strap / 2) points.tipRightTop = new Point(points.tipRight.x, points.edgeTop.y) points.tipRightBottom = new Point(points.tipRight.x, points.top.y) macro("round", { from: points.edgeTop, to: points.tipRight, via: points.tipRightTop, prefix: "tipRightTop", }) macro("round", { from: points.tipRight, to: points.top, via: points.tipRightBottom, prefix: "tipRightBottom", }) const rotateThese = [ "edgeTopLeftCp", "edgeTop", "tipRight", "tipRightTop", "tipRightTopStart", "tipRightTopCp1", "tipRightTopCp2", "tipRightTopEnd", "tipRightBottomStart", "tipRightBottomCp1", "tipRightBottomCp2", "tipRightBottomEnd", "tipRightBottom", "top", "topCp2" ] while (points.tipRightBottomStart.x > -1) { for (const p of rotateThese) points[p] = points[p].rotate(1, points.edgeLeft) } // Snap anchor points.snapLeft = points.top.shiftFractionTowards(points.edgeTop, 0.5) // Add points for second strap points.edgeTopRightCp = points.edgeTopLeftCp.flipX() points.topCp1 = points.topCp2.flipX() points.tipLeftTopStart = points.tipRightTopStart.flipX() points.tipLeftTopCp1 = points.tipRightTopCp1.flipX() points.tipLeftTopCp2 = points.tipRightTopCp2.flipX() points.tipLeftTopEnd = points.tipRightTopEnd.flipX() points.tipLeftBottomStart = points.tipRightBottomStart.flipX() points.tipLeftBottomCp1 = points.tipRightBottomCp1.flipX() points.tipLeftBottomCp2 = points.tipRightBottomCp2.flipX() points.tipLeftBottomEnd = points.tipRightBottomEnd.flipX() points.snapRight = points.snapLeft.flipX() // Round the bottom corners macro("round", { from: points.topLeft, to: points.bottomRight, via: points.bottomLeft, radius: points.bottomRight.x / 4, prefix: "bottomLeft" }) macro("round", { from: points.bottomLeft, to: points.topRight, via: points.bottomRight, radius: points.bottomRight.x / 4, prefix: "bottomRight" }) // Create one path for the bib outline paths.seam = new Path() .move(points.edgeLeft) .line(points.bottomLeftStart) .curve(points.bottomLeftCp1, points.bottomLeftCp2, points.bottomLeftEnd) .line(points.bottomRightStart) .curve(points.bottomRightCp1, points.bottomRightCp2, points.bottomRightEnd) .line(points.edgeRight) .curve( points.edgeRightCp, points.edgeTopRightCp, points.tipLeftTopStart ) .curve( points.tipLeftTopCp1, points.tipLeftTopCp2, points.tipLeftTopEnd ) .curve( points.tipLeftBottomCp1, points.tipLeftBottomCp2, points.tipLeftBottomEnd ) .curve( points.topCp1, points.rightCp2, points.right ) .curve( points.rightCp1, points.bottomCp2, points.bottom ) .curve( points.bottomCp1, points.leftCp2, points.left ) .curve( points.leftCp1, points.topCp2, points.tipRightBottomEnd ) .curve( points.tipRightBottomCp2, points.tipRightBottomCp1, points.tipRightBottomStart ) .curve( points.tipRightTopCp2, points.tipRightTopCp1, points.tipRightTopStart ) .curve( points.edgeTopLeftCp, points.edgeLeftCp, points.edgeLeft ) .close() .addClass("fabric") // highlight-start if (complete) { /* * Let's add the points where * the closure's snaps should go. */ // Add snaps points.snapLeft = points.top .shiftFractionTowards(points.edgeTop, 0.5) points.snapRight = points.snapLeft .flipX() /* * Now, let's use our newfound snippet powers * to add the snaps to these points. * First the left snap (the stud part) */ snippets.snapStud = new Snippet( 'snap-stud', points.snapLeft ) /* * The right snap (the socket part) * should go on the back of the fabric. * To try to make that more obvious to the user * let's set its `opacity` attribute to 0.5 * this way it will be semi-transparent. */ snippets.snapSocket = new Snippet( 'snap-socket', points.snapRight ).attr('opacity', 0.5) /* * Another snippet we should add is our logo. * A logo is not required, but we love skully. */ // Add a logo points.logo = new Point(0, 0) snippets.logo = new Snippet( "logo", points.logo ) /* * We already know how to use macros * This one adds a title to our part */ // Add a title points.title = points.bottom .shift(-90, 45) macro("title", { at: points.title, nr: 1, title: "bib", scale: 0.7 }) /* * This macro adds a scalebox to our part */ // Add a scalbox points.scalebox = points.title .shift(-90, 55) macro( "scalebox", { at: points.scalebox } ) /* * Our bib should be finished with bias tape. * To add it, we're using Path.offset() * You will learn to LOVE this methid * when designing pattern with seam allowance * as it draws a path parallel to another one */ paths.bias = paths.seam .offset(-5) .addClass("various dashed") .addText( "finishWithBiasTape", "center fill-various" ) } // highlight-end return part } ```