How to build your first Sketch plugin

Ah, we are just getting started…Drawing ShapesDrawing shapes is one of my favorite things to do in Sketch.

Some days though, even drawing rectangles is too hard.

On those days I really wish Sketch could do that for me.

Let’s see if we can build a plugin that helps me when I’m lacking some inspiration.

This is what we will make:Oo purty shapes ????In this next part we will learn how to create an artboard, make some shape layers, group them together, and reorder them.

Follow along and let’s go!1.

Import Sketch & Get Common ObjectsOnce you have your script panel open and ready to go, the first thing that we need to do is to import the JS API.

Remember, this is partthat helps us interact with Sketch.

var sketch = require('sketch')Then, we will need to get the current document and page.

To get the current page we use a method on sketch and get the selected page as a property on document.

let document = sketch.

getSelectedDocument()let page = document.

selectedPage2.

Create an ArtboardThe other neat thing that you can do with the JS API is to pull out various useful Sketch objects from it.

I like to think of the JS API like a utility belt which has lots of neat tools.

In practice, you use it to pull out various classes from it.

A class is a special type of function that organizes related functions and properties (you can learn more here).

Here is how we pick out the Artboard class.

let Artboard = sketch.

ArtboardNow, we can use the Artboard class — the tool we just pulled out — to create an actual instance of an Artboard:let myArtboard = new Artboard()and if you log myArtboard you will see that you successfully created an Artboard object!✔️ CheckpointLet’s take a brief moment to see what we have written.

Your code should look like this so far:let sketch = require('sketch')let document = sketch.

getSelectedDocument()let page = document.

selectedPagelet Artboard = sketch.

Artboardlet myArtboard = new Artboard()It’s good practice to move dependencies, or the imported tools, to the top of the file.

Let’s move the Artboard class to the top.

let sketch = require('sketch')let Artboard = sketch.

Artboardlet document = sketch.

getSelectedDocument()let page = document.

selectedPagelet myArtboard = new Artboard()One other thing we can check is to see what myArtboard looks like.

If we add console.

log(myArtboard) to the end of the script and hit “Run” the logged output should look like this:{ type: 'Artboard', id: '82732522-D929-4896-B98B-950E9E1EB7A8', frame: { x: 0, y: 0, width: 100, height: 100 }, name: 'Artboard', selected: false, exportFormats: [ ], sharedStyleId: null, layers: [ ],flowStartPoint: false, background: { enabled: false, includedInExport: true, color: '#ffffffff' } }So now that we created the artboard you might be thinking,“Well…where is it exactly?” If you look underneath your script panel you should see that nothing got added to the canvas (you can also close the panel and look around to be sure — as long as you clicked “Run” your written code will still be there for you when you open the script panel again).

See how the id parameter keeps changing?It turns out that we will need to explicitly attach the artboard to the correct page.

Otherwise, the artboard object that we made will be thrown away once the script is done running.

This is why if you keep hitting the Run button over and over the unique id value of the artboard will change.

Sketch is creating a brand new artboard object each time your script is executed.

To attach the artboard to the page we will need to specify a parent:let myArtboard = new Artboard()myArtboard.

parent = pageOr if we want to be a bit more succinct about it we can pass the parent property when we initialize the artboard.

let myArtboard = new Artboard({ parent: page })Look!.There it is!.A marvelous artboardSweet!.We got our artboard on our canvas.

But, our artboard is a little small.

In fact, the default size is 100 by 100.

Perhaps you have an idea how to make the artboard larger already.

If we look back to when we logged myArtboardthen you might have noticed this property:frame: { x: 0, y: 0, width: 100, height: 100 }So to resize our artboard to 400px by 400px we can modify myArtboard like so:let myArtboard = new Artboard({ parent: page })myArtboard.

frame = { x: 0, y: 0, width: 400, height: 400 }Which we can also move into the initializer:let myArtboard = new Artboard({ parent: page, frame: { x: 0, y: 0, width: 400, height: 400 }})Nice work!.By now you have clicked the Run button a few times and it’s likely that you have created a few artboards on top of one another.

Or maybe you have been deleting them every time you wanted to run the code again.

That is a bit tedious and something we can do programmatically!.To clear everything within a page you can do this:page.

layers = []If we add that before we create our artboard then each time you run the script the previously made artboards will be removed.

So if we put everything together so far we should have something like this:let sketch = require('sketch')let Artboard = sketch.

Artboardlet document = sketch.

getSelectedDocument()let page = document.

selectedPagepage.

layers = []let myArtboard = new Artboard({ parent: page, frame: { x: 0, y: 0, width: 400, height: 400 }})Great job!.Now let’s add some shapes!3.

Creating a SquareCreating a square is very similar to creating an artboard.

We willspecify a frame, a parent, and now a fill!.Here is how we do it:let ShapePath = sketch.

ShapePathlet mySquare = new ShapePath({ parent: myArtboard, frame: { x: 53, y: 213, width: 122, height: 122 }, style: { fills: ['#35E6C9']}})We are already familiar with parent and frame.

style is the newest of the bunch.

If we take a look at the inspector panel inside Sketch we can get an idea of what our code is doing.

When you select a layer, there are a bunch of properties like Resizing, Prototyping, Appearance, Style, Shadows, Inner Shadows, Blurs, etc.

We want to add a fill which is under the Style section.

Fills can be disabled or enabled, have a blend mode, a hex value, and opacity.

You can also have multiple fills as well!Since you can have multiple fills the fill property holds a list of them (in code, a list is often called an array).

That looks like this:style: { fills: [fill1, fill2, fill3, etc.

]}But since we really only want one fill we just need to pass in one hex value.

style: { fills: ['#35E6C9’]}Before we move on to creating other shapes I want to point out one subtle detail with frames:let mySquare = new ShapePath({ parent: myArtboard, frame: { x: 53, y: 213, width: 122, height: 122 }})Since we specified the parent artboard, the frame that we provide will be relative to the artboard that we made (it also inserts it inside the artboard as well).

If we made the parent the page like we did when creating the artboard then its coordinates would be relative to the page.

✔️ CheckpointSo, to review what our code should look like at this step, it should look like this:let sketch = require('sketch')let Artboard = sketch.

Artboardlet document = sketch.

getSelectedDocument()let page = document.

selectedPagepage.

layers = []let myArtboard = new Artboard({ parent: page, frame: { x: 0, y: 0, width: 400, height: 400 } })let ShapePath = sketch.

ShapePathlet mySquare = new ShapePath({ parent: myArtboard, frame: { x: 53, y: 213, width: 122, height: 122 }, style: { fills: ['#35E6C9']}})Let’s move the ShapePath class up to the top to keep our dependencies together.

let sketch = require('sketch')let Artboard = sketch.

Artboardlet ShapePath = sketch.

ShapePathlet document = sketch.

getSelectedDocument()let page = document.

selectedPagepage.

layers = []let myArtboard = new Artboard({ parent: page, frame: { x: 0, y: 0, width: 400, height: 400 } })let mySquare = new ShapePath({ parent: myArtboard, frame: { x: 53, y: 213, width: 122, height: 122 }, style: { fills: ['#35E6C9']}})That is looking really great!.If you click“Run”this is what should appear on the canvas:That’s a nice square there.

*Note: If your square has a border around it then its likely that your Default Layer Style is causing this.

To ensure that a border won’t be drawn you will need to pass in an empty array for borders like so.

This will likely be fixed in later versions of the Sketch API.

style: { fills: ['#35E6C9’], borders: []}4.

Creating Other ShapesTrianglesCreating other shapes like triangles, pentagons, and circles are really similar to drawing rectangles.

We need to specify a parent, a frame, and a fill (well a style that contains a fill).

The only difference now is that we need to specify a ShapeType:let myTriangle= new ShapePath({ shapeType: ShapePath.

ShapeType.

Triangle, parent: myArtboard, frame: { x: 84, y: 62, width: 98, height: 80 }, style: { fills: ['#00d5ffb3']}})ShapePath contains an object called ShapeType.

If you log ShapePath.

ShapeType you’ll find a list of all the different types of shapes you can create.

Here we want to use the Triangle option.

Also, you might have noticed that there is a funny looking Hex code here.

Normally Hex codes are 6-digits and correspond to RGB values (two digits for each color channel).

8-Digit hex codes have some extra bit of information and use the last two digits to encode opacity.

Specifically, the b3 part of the string corresponds to 70% opacity.

*If you are looking to learn more about hex codes then check out these resources:The Code Side of Color by Ben GremillionHexes and Other Magical Numbers by Vaidehi Joshi8-Digit Hex Codes?.by Chris CoyierPentagonsNow that you know how to change the shapeType how might you be able to create a pentagon?.The trick is to use the Polygon option.

let myHex = new ShapePath({ shapeType: ShapePath.

ShapeType.

Polygon, parent: myArtboard, frame: { x: 218, y: 142, width: 120, height: 120 }, style: { fills: ['#FF00B366']}})The default number of sides of a polygon is 5.

Unfortunately, you can’t change the number of sides with the JS API just yet so we are stuck with hexagons for now.

CirclesCircles, of course, are created with the OvalShapeType.

Hah!.You thought it was going to be Circle, eh?. More details

Leave a Reply