Sketch作为一款近些年流行起来的设计工具,在设计师里已经广为流传,Sketch的开发者甚至还为Sketch提供了开发插件的功能,让sketch有了更强的扩展性,正是基于如此强大的扩展性,让我们可以基于sketch做很多的扩展,今天在这里介绍下Sketch插件的开发方式。
技术方案
根据我自己的sketch插件开发经验,sketch插件开发有两种比较常用的技术选型
方式 | CocoaScript + Objective-C | skpm + 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等,这种方式相对开发资料更丰富,我们内部的插件开发新功能也基本采用这种技术方向开发
nice blog bro thanks, https://about.me/yerel1-bursa-eskort-bayan-sitesi
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.
Bursa’da anahtar teslim tadilat hizmetleri sunan firmamız, evinizin her detayını sizin isteğiniz doğrultusunda yeniden şekillendiriyor.