Sketch插件开发入门

Sketch作为一款近些年流行起来的设计工具,在设计师里已经广为流传,Sketch的开发者甚至还为Sketch提供了开发插件的功能,让sketch有了更强的扩展性,正是基于如此强大的扩展性,让我们可以基于sketch做很多的扩展,今天在这里介绍下Sketch插件的开发方式。

技术方案

根据我自己的sketch插件开发经验,sketch插件开发有两种比较常用的技术选型

方式CocoaScript + Objective-Cskpm + JavaScript
上手难度
文档丰富度较丰富
编译方式不用编译直接运行,“所写即所得”通过编译 bundle 运行
代码管理明文保存,缺少混淆skpm工作集开发,发布,能够混淆
开发生态缺少开发生态,需要手动编写工具类可纳入前端生态,使用成熟的npm包等
开发工具无限制,任何文本编辑器均可使用js类如WebStorm等编辑器可提高开发效率

插件结构

从上面两个技术选型来看,各有千秋,目前我们的UI自动化插件两方面的技术选型都有使用到,这里先介绍第一种基于CocoaScript的方式,插件工程其实就是一个以.sketchplugin结尾的文件夹,里面的目录结构如下

可以直接双击example.sketchplugin进行安装,或者把该插件放在

⁨⁩/Users/xxxx/Library/⁨Application Support/com.bohemiancoding.sketch3/plugins/
前一种方式的本质其实也是第二种方式

manifest.json

必不可少的文件,里面声明了插件的每个命令和对应⁩入口函数

{
  "author": "zujie.czj",
  "identifier":"com.jc.testplugin",
  "description":"Test",
  "commands":[
    {
      "name":"HelloWorld",
      "identifier":"com.jc.hello",
      "handler":"onRunHello",
      "script":"HelloWorld.cocoascript"
    }
  ]
}

上面json里的identifier 用来表示该插件的ID唯一值,commands用来表示开发插件里的命令,比如上面我定义了一个名称为HelloWorld的command,它的入口方法在HelloWorld.cocoascript的onRunHello方法里

我们定义改命令的操作很简单,简单地打印一个HelloWorld
操作方式如下

可以在控制台看到Hello World输出

开发调试

代码知道怎么写了,那debug该如何操作呢?这方面插件支持还比较简陋,无法断点支持,只能通过打log,然后在mac的控制台程序里看输出来调试,就像前面打印的Hello World一样

context

从上面的介绍我们看到,插件的入口函数传入了一个context,这个context的包含这么些内容

  • command: MSPluginCommand对象,代表当前执行的命令
  • document: MSDocument 对象 ,当前的文档
  • plugin: MSPluginBundle 对象,当前的插件bundle,里面包含当前运行的脚本
  • scriptPath: NSString 当前执行脚本的绝对路径
  • scriptURL: 当前执行脚本的绝对路径,跟 scriptPath不同的是它是个 NSURL 对象
  • selection: 一个 NSArray 对象,包含了当前选择的所有图层。数组中的每一个元素都是 MSLayer 对象

通过这个context我们可以扩展出很多能力,比如我们这边实现一个选中图层弹出图层名称的简单功能

var onRunHello = function (context) {
    //log("Hello World");
    //log(JSON.stringify(context));
    var selections = context.selection;
    if(selections){
        if(selections.length > 1){
            context.document.showMessage("请选择一个图层");
        }
        else if(selections.length === 0){
            context.document.showMessage("没有选中图层");
        }
        else{
            var layer = selections[0];
            context.document.showMessage(layer.name());
        }
    }
};

代码很简单,基本一看就懂,完成的效果就像

开发助手

使用CocoaScript我们需要知道sketch提供的api有哪些,官网文档并不丰富,但是有大神直接dump出sketch 的头文件, 通过这个头文件,我们基本所有的api都能查询到,开发资料一下子丰富起来

同时插件论坛 里面的问答资料也很丰富,回答也算及时,这些都能帮助快速开发出sketch插件。

skpm

我们一开始介绍过sketch插件开发还有另外一种skpm + JavaScript的方式,该种方式和前面所说的开发方式其实也是大同小异,但开发效率和工具却丰富得多。它基于丰富的工具库来做插件开发,前面介绍的方式如果是小米加步枪,这个方式至少算是扛着大炮做插件了。

安装skpm

npm install -g skpm

创建工程模板

直接在sketch的插件目录下

skpm create my-plugin

创建成功后

工程目录

目录作用
src代码目录
*.sketchplugin编译产生资源,不可编辑,每次代码修改都需要编译生成
assets任何资源文件比如png都可以放在这个目录

开发

我们用这种新的技术手段把上面写的demo展示图层名字的demo改改
mainfiest.json:

{
  "$schema": "https://raw.githubusercontent.com/BohemianCoding/SketchAPI/develop/docs/sketch-plugin-manifest-schema.json",
  "icon": "icon.png",
  "commands": [
    {
      "name": "my-command",
      "identifier": "my-plugin.my-command-identifier",
      "script": "./my-command.js",
      "handlers" : {
        "run" : "onRunName"
      }
    }
  ],
  "menu": {
    "title": "my-plugin",
    "items": [
      "my-plugin.my-command-identifier"
    ]
  }
}

my-command.js:

let sketch = require('sketch');
let UI = require('sketch/ui');
// documentation: https://developer.sketchapp.com/reference/api/


export function onRunName() {
  let doc = sketch.getSelectedDocument();
  let selectedLayers = doc.selectedLayers;
  let selectedCount = selectedLayers.length;

  if (selectedCount > 1) {
    UI.message('请选择一个图层')
  }
  else if (selectedCount === 0) {
    UI.message('没有选中图层')
  } else if (selectedCount === 1){
    UI.message(selectedLayers.layers[0].name);
  }
}

写完代码需要

npm run build

让代码生效。

上面的插件代码可以看出跟前一种方式比代码差异不大,但我们对应sketch提供的api是以import方式导入,同样的我们也可以import一些优秀的库比如treemap-js, xml-js等,这种方式相对开发资料更丰富,我们内部的插件开发新功能也基本采用这种技术方向开发

关于chenzujie

非著名码农一枚,认真工作,快乐生活
此条目发表在Sketch分类目录,贴了标签。将固定链接加入收藏夹。

Sketch插件开发入门》有2条回应

  1. Bralet说:

    Bralette, sutyen gibi destek sağlamayan, daha çok rahatlık odaklı bir iç giyim parçasıdır. Genellikle ince askılara veya dantel detaylara sahiptir.

发表评论

邮箱地址不会被公开。 必填项已用*标注