/sketch-context2d

Javascript CanvasRenderingContext2d in Sketch

Primary LanguageObjective-C

DRAFT – MORE TO COME

COMPATIBLE WITH SKETCH 41.2

Introduction

This isn't a plugin. It´s a node.js module and command-line tool to run js modules via browserify in Sketch.

Essentially it creates a javascript context with an injected canvas object which is a representation of the current selected artboard or group and exposes Sketchs drawing capabilities through the canvas 2d context. The API mirrors CanvasRenderingContext2D.

Long story short, you can use javascript to draw things in Sketch just like you can in browser environments using canvas.

Paths are shape-layers, text gets translated to text-layers, all still editable and styleable. Transformation, style and text-layout states are saved on a stack.

###Great, but why?

I work on visualising data on a daily basis. With a few exceptions this goes beyond developing simple visually reduced pie- or bar-charts. While there are already solutions for drawing those in Sketch, none of them are flexible enough. They are either too opinionated visually or expect a certain data format.

You shouldnt create visual-systems for data-representation in Sketch, verify them afterwards by implementing a defined style with actual data and hope it won't break. Creating those systems is also about edge-cases: What happens if the actual data isn't as interesting as expected? How can extreme values be handled? In which cases does it make sense to break the rule-set and establish a new one? Those questions should be part of the design process.

We find solutions by constantly switching between design and implementation. I think this process can be unified and happen in a shared environment, right within Sketch and using our own preferred code toolset.

Some visual examples

Out of context, some explorations using the same external data-set and a shared style. You can find the Sketch file and the js files for plotting the data here, the original data is located here.

How does it work?

sketch-context2d takes your js files, browserifies them (handling your filesystem requests as well) and creates a new javascript-context right within Sketch with wrapped bindings to its layer drawing procedures.

A simple example.js file:

//you can require node modules 😎
//var favModule = require('fav-module');

function main(canvas){ //canvas, your selected artboard / group
    var ctx = canvas.getContext('2d'); //exposed drawing capabilities

    var width  = canvas.width;  //artboard / group width
    var height = canvas.height; //artboard / group height

    ctx.beginPath();     //begin new shape-layer
    ctx.moveTo(0,0);     //construct shape-layer
    ctx.lineTo(100,100);
    ctx.stroke();        //stroke shape-group and add to artboard / group
}

module.exports = main; //expose drawing function to sketch-context2d

This will create a new group within your currently selected artboard or group named example_{timestamp}. The visual result of your drawing function will be placed within that group. In this case a diagonal black line will appear. Every time you change the example.js file and rerun sketch-context2d (or use the --watch option) the aforementioned group will get updated, including its timestamp.

A recorded example using the --watch option drawing the Sketch logo in code.

Installation

Install node.js if necessary

brew install node

Using npm, do: (Not published yet)

npm install -g sketch-context2d

Run

Select a target artboard or group within Sketch.

####CLI ( To be added )

$ sketch-context2d file.js
Option Description
--help Show all options
--verbose Log details of the process
--log-verbose Log js script line number and columns
--recreate Don´t update groups in place, create new ones
--flatten Flattens resulting group to image
--watch Watch the js script passed

Module API example

//do something here

//sketch-context2d options, see above
const options = {
    verbose    : false,
    verboseLog : false,
    recreate   : false,
    flatten    : false,
    watch      : false
};

//run / watch js file in Sketch
require('sketch-context2d')(['dir/file.js'],options);

API-Reference

CanvasRenderingContext2d References

https://www.w3.org/TR/2dcontext/ (best overview) https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D
(more accessible, reference for single cmd tests here)

API-Implementation Status

Around 70% is already done, mostly pixel based manipulations is missing. Everything not configurable by Sketch´s Interface is ignored (eg. miterLimit, lineDashOffset).
Overview here

CanvasRenderingContext2d API Additions

Some additions necessary to the original API:

Global

//check if you are in Sketch
if(sketch){
    //do Sketch specific stuff here
}

Context

//Default, text-layers created via fillText/strokeText get transformed 
//to shape-groups to apply all transformations. You can't skew, apply non-uniform
//scales to text-layers
ctx.useTextLayerShapes = true;

//Prevents text-layers from being transformed to shapes. 
//They remain fully editable, scale- and rotation-transforms are ignored though
ctx.useTextLayerShapes = false;

Images

var image = new Image();
if(!sketch){
    //you can skip the callback in sketch-context2d, 
    //as images are loaded synchronously
    image.onload = function(){draw(canvas);};
    image.src = pathToImg;
} else {
    image.src = pathToImg;
    draw(canvas);
}