4

sketch插件开发指南

 2 years ago
source link: https://www.zoo.team/article/sketch
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

文章目录

  • 前期知识储备

    • 使用 skpm 快速创建 Sketch 插件

      • 1. 安装 skpm

      • 2. 使用脚手架模板创建插件

      • 3. 安装依赖

      • 4. 本地开发热更新

      • 5. 打包构建

    • 工程目录结构

    • manifest.json

      • 1. 基础配置

      • 2. 菜单项支持多级配置

  • 开发辅助工具:DevTools

  • API Reference

    • JavaScript API

      • JS API 使用示例

    • Actions

      • Action API 使用示例

    • Context

  • WebView

    • 新建 WebView

    • WebView和插件之间的通信

    • WebView 调试

sketch插件开发指南

2021-11-22 发布于 方案沉淀 · 阅读量:5

责任小编:心火

​ 先抛个问题,众所周知,Sketch 是 UED 设计工具,大多数 Sketch 插件都是用于提升设计人员工作效率。那么,作为前端研发的我们为什么要学习 Sketch 插件开发呢?

​ 纵观整个前端研发流程,PRD => Design => Code => Release。目前我们的研发提效方式主要集中在 Code => Release 环节,通过 Low Code 低代码开发平台(组件化 + 配置化 + 搭建能力)来提升交付效率。当搭建能力趋于成熟的情况下,前端研发提效的下一个突破口在哪儿?是的,就是 Design to Code,通过解析 Sketch 设计稿来完成 UI 层代码的生成,让前端研发同学更专注于业务逻辑代码。这也是我学习 Sketch 插件开发的初衷。当然今天分享不是 D2C 相关,所以主要篇幅还是集中在 “如何帮助大家快速掌握 Sketch 插件开发”。

前期知识储备

  • 开发语言:JavaScript + CocoaScript(为 JS 访问内部 Sketch API 和 macOS 框架提供了桥梁)

  • 其他技术补充:Sketch 插件支持 WebView,可使用 React、Vue 等框架开发

  • 工程化工具:前端打包工具 webpack、脚手架工具 skpm

如果你是一枚前端研发工程师,那么这一切对你而言就不陌生了。

使用 skpm 快速创建 Sketch 插件

脚手架工具 skpm 提供了插件创建、打包、发布等功能,以及丰富的脚手架模板。分分钟可以出创建一个 Sketch 插件工程。

1. 安装 skpm

npm install -g skpm

2. 使用脚手架模板创建插件

skpm create <project-name> --template=<skpm-template>

3. 安装依赖

npm install
  • 说明:这一步不仅会安装三方依赖包,并且会自动创建 Symbolic Link,将开发目录下构建的插件实时同步到 Sketch 插件安装目录下,便于开发调试。

4. 本地开发热更新

npm run watch
  • 说明:watch 命令会监听插件 src 目录的文件,一旦文件变更,会触发重新编译构建。再通过上面提到的 Symbolic Link,将重新编译构建的插件同步到 Sketch 插件的安装目录下,即可实时查看到插件修改的效果。

5. 打包构建

npm run build

至此,你应该已经得到了一个完整的 Sketch 插件工程,那我们一起来看下它都包含了哪些内容。

工程目录结构

├── assets // 静态资源 │ └── icon.png // 插件显示的Icon图标 ├── sketch-plugin-demo.sketchplugin // skpm构建后生成的插件安装包 │ └── Contents │ ├── Resources │ │ └── _webpack_resources │ │ └── resources_webview.js │ │ └── resources_webview.js.map │ └── Sketch │ ├── manifest.json │ ├── __my-command.js │ └── __my-command.js.map ├── package.json ├── webpack.skpm.config.js // webpack配置文件 ├── resources // Webview相关资源文件 │ ├── style.css │ ├── webview.html │ └── webview.js └── src ├── manifest.json // 插件的清单文件 └── my-command.js // 命令对应的执行脚本js

manifest.json

manifest.json 清单文件是 Sketch 插件最核心的一个文件。主要包括插件名称、描述、作者信息、调用菜单项 menu、定义的命令 commands 、事件监听 Actions 等等。Sketch 插件支持定义一个或多个菜单项 menu,菜单项关联相应的命令 command,命令功能由对应的 JS 脚本来实现。

1. 基础配置

// 基础配置示例 "compatibleVersion": 3, // 兼容版本号 "bundleVersion": 1, "commands": [ // 定义命令 "name": "生成随机色", "identifier": "sketch-plugin-demo.generate-random-color", "shortcut": "ctrl shift r", "script": "./generateColor.js", "handlers": { "run": "onRun", "actions": { "OpenDocument": "onOpenDocument" "menu": { // 定义菜单项 "title": "sketch-plugin-demo", "items": [ "my-plugin-with-webview.my-command-identifier" // 对应上面命令的identifier

详细释义如下:

  • commands
    • name:命令对应菜单项的显示名称
    • identifier:命令的唯一标识,建议命名规则 ${PluginName}.xxx-xxx-xxx
    • shortcut:调用命令的快捷键
    • script:实现命令功能的函数所在的脚本
    • handlers:定义处理程序,包含触发命令时调用的函数方法名(默认为 onRun),以及定义 Action 事件监听
  • menu
    • title:插件在菜单栏显示的名称
    • items:定义菜单的集合,对应命令的 identifier

2. 菜单项支持多级配置

"commands": [ "name": "第三级菜单项", "identifier": "my-plugin-with-webview.my-command-identifier", "script": "./my-command.js", "handlers": { "run": "onRun", "actions": { "Shutdown": "onShutdown" "menu": { "title": "my-plugin-with-webview", "items": [ "title": "第一级菜单项", "items": [ "title": "第二级菜单项", "items": [ "my-plugin-with-webview.my-command-identifier"

开发辅助工具:DevTools

  • 为提升开发效率,可安装 Sketch 插件 DevTools,便于查看 Sketch 文档结构、Network、Action 执行情况等等,并且支持 Console。

API Reference

JavaScript API

虽然 Sketch 应用是使用 Objective-C 开发的,但官方团队为 Sketch 插件提供了一套 JavaScript API,支持访问和修改 Sketch 文档、获取用户自定义设置、提供数据源等等。主要包含以下五个模块:

// 访问和修改Sketch文档 import SketchDom from 'sketch/dom'; // 处理异步操作。在插件开发中,无法使用ES6的async,需sketch提供async import Async from 'sketch/async'; // 提供图像或文本数据,直接与Sketch用户界面集成,使内容在整个设计过程中随时可用 import DataSupplier from 'sketch/data-supplier'; // 常用的UI操作,例如:展示message/alert提示信息、获取用户输入等等 import UI from 'sketch/ui'; // 获取/保存用户的自定义数据 import Settings from 'sketch/settings'; // 包含以上5个模块的所有内容 import Sketch from 'sketch';
  • 注意:sketch package 涵盖了所有内容,体积比较大,不建议直接引用。大家可根据实际场景按需引入以上 5 个独立的模块。

JS API 使用示例

接下去,我们使用 JS API 实现一个小功能 “获取所选图层中的文本内容”。完整代码见Github

import SketchDom from 'sketch/dom'; import UI from 'sketch/ui'; const strArray = []; // 递归获取每个层级图层中的文本内容,并存储到strArray数组中 const getTextValue = (layers) => { if (layers.length) { layers.forEach(layer => { const { type, layers: subLayers = [] } = layer; if (type === 'Text') { strArray.push(layer.text); if (subLayers.length) { getTextValue(subLayers); // 用message提示信息的方式展示获取到的文本内容 const print = () => { UI.message('已选择的文本内容:' + strArray.toString()); export default () => { const doc = SketchDom.getSelectedDocument(); // 获取已选中的文档 const layers = doc.selectedLayers.layers; // 获取已选中的图层 getTextValue(layers); print(strArray);

Actions

在 Sketch 3.8 中,引入了 Action API,实现了插件对用户行为事件的监听。目前已支持 300+ 的 Action,以下列举了日常我们用到最多的几个 Action:

Action 触发条件 应用场景 StartUp 插件安装/启动时 文档预处理、读取用户配置、拉初始化数据等 ShutDown 插件被禁用/卸载时 清理插件的缓存数据,功能不可用提示信息等 SelectionChanged 用户选择的Layers发生改变时 重新获取/处理Layers的相关数据信息 Open/CloseDocument 打开/关闭文档时 提示引导信息

Action API 使用示例

// 1. 在 manifest.json 文件中注册 Action "commands": [ "name": "Actions", "identifier": "sketch-plugin-demo.actions", "script": "./actions.js", "handlers": { "actions": { "StartUp": "onStartUp", "Shutdown": "onShutdown" // 2. 在命令对应的js文件中,定义Action的回调函数 export const onStartUp = context => { UI.message('Sketch-plugin-demo 插件已启动'); export const onShutdown = context => { UI.message('Sketch-plugin-demo 插件已被禁用');

Context

仔细的同学会发现,在上述 Action 使用示例中,回调函数默认接收了一个 Context 的对象,也就是当前操作的上下文,在实际开发中非常有用。我们将 Context 打印到控制台,可以发现它包含以下字段:

  • action:当前执行的 Action 以及所处的阶段,分为2个阶段 begin 和 finish
  • scriptPath:当前执行脚本的绝对路径
  • command:当前执行的命令
  • document:当前操作的 Sketch 文档
  • selection:当前选中的所有图层

WebView

Sketch 插件开发,除了使用 JS API 访问和修改文档外,还有一块很重要的能力,就是支持 WebView 开发。我们可以使用 skpm 快速创建一个包含 WebView 的插件。

skpm create my-plugin-with-webview --template=skpm/with-webview

关于目录结构,前面也有提到过,WebView 相关文件都是存放在 resources 目录下统一管理。但这边有个小坑,通过 Webpack 编译构建后的 JS 文件会自动加上 resources_ 前缀。例如:webview.js 编译后会变成 resources_webview.js。所以,在 HTML 中引用 JS 时,也特别要注意这个点。

接下去,我们详细来看一下刚才创建的插件工程代码。

新建 WebView

const createWebView = () => { // options配置信息 const options = { identifier: 'my-plugin-with-webview.webview', title: 'This is a WebView', width: 600, height: 200, resizable: true // 新建WebView窗口 const browserWindow = new BrowserWindow(options); // 页面载入完成后才显示弹窗,避免窗口白屏 browserWindow.once('ready-to-show', () => { browserWindow.show() const webContents = browserWindow.webContents; // 页面载入完成后提示信息 webContents.on('did-finish-load', () => { UI.message('UI loaded!'); // 装载HTML页面 browserWindow.loadURL(require('../resources/webview.html'));

WebView和插件之间的通信

  • 插件发送消息到 WebView
// On the plugin webContents .executeJavaScript(`setRandomNumber(${Math.random()})`) .catch(console.error) // On the WebView window.setRandomNumber = (randomNumber) => { document.getElementById('answer').innerHTML = 'Random number from the plugin: ' + randomNumber
  • WebView 发送消息给插件
// On the webview window.postMessage('nativeLog', 'Called from the webview'); // On the plugin import UI from 'sketch/ui'; webContents.on('nativeLog', s => { UI.message(s);

WebView 调试

  • 可通过以下配置开启调试功能。开启调试功能后,可右键唤起工作台。
defaults write com.bohemiancoding.sketch3 WebKitDeveloperExtras -bool YES

为了避免眼睛会了,手没会的情况。下面来 2 个示例给大家练练手。示例代码见GitHub

矩形色块和文本内容成组,要求随机生成 RGB 色值并更新矩形颜色和对应文本内容。效果如下:

  • 测试文件可直接使用示例工程中的 ./test-file/test.sketch,其图层元素结构如下:
  • 通过 DevTools 插件快速查看 sketch 文件的元素结构,直接对元素属性进行操作即可。
import SketchDom from 'sketch/dom'; import UI from 'sketch/ui'; import Mock from 'mockjs'; const Random = Mock.Random; export default () => { const doc = SketchDom.getSelectedDocument(); // 获取已选中文档 const layers = doc.selectedLayers.layers; // 获取已选择图层 if (layers.length) { layers.forEach(layer => { const { type, layers: subLayers = [] } = layer; if (type === 'Group') { subLayers.forEach(subLayer => { const randomColor = Random.hex(); // 随机生成RGB色值 if (subLayer.type === 'ShapePath') { subLayer.style.fills[0].color = randomColor; // 更新矩形颜色 if (subLayer.type === 'Text') { subLayer.text = randomColor; // 更新文本内容为RGB色值 } else { UI.message('当前没有元素被选中,请选择');

基于 Umi + Antd 实现一个嵌在 WebView 里的登录页。效果如下:

  • 首先,我们需要在 Sketch 插件工程中集成 Umi + Antd

    • 在插件工程的根目录下,新建 webview 文件夹
  • $ mkdir webview && cd webview
  • 基于 Umi 模板新建工程,这边我选择的脚手架类型是 app,引入框架包括 antd 和 dva
npm create umi
  • 在 .umirc.js 文件中,添加以下配置
outputPath:‘../src/dist‘, // 打包构建输出的目录 exportStatic: { dynamicRoot: true // 静态自由部署
  • 在 webview/src/pages 目录下,新建 document.ejs 文件,Umi 约定默认以这个文件作为模板
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>Your App</title> </head> <body> <div id="root"></div> </body> </html>
  • 为便于开发调试,可本地启动 web 服务,然后 webview 装载此服务的页面,本地 web 代码更新会实时编译同步到 webview 中
const webPage = `http://localhost:8000#${Math.random()}`; browserWindow.loadURL(webPage)

这样一来,我们就可以愉快的使用 Umi 和 Ant Design 了

import styles from './index.css'; import { Input, Button } from 'antd'; import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons'; export default function () { return ( <div className={styles.normal}> <div> <Input className={styles.antdInput} placeholder="请输入用户名" /> <Input.Password className={styles.antdInput} placeholder="请输入密码" iconRender={visible => (visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />)} /> <Button className={styles.antdBtn} type="primary">登录</Button> </div> </div>

以上是关于 Sketch 插件开发的主要内容,它为我们提供了向前端上游探索的能力,大家可以结合自己公司的情况,研发一些 Sketch 插件帮助 UED 和前端提效。例如,UI 设计规范、Sketch Symbol 组件库以及与下游前端组件库关联映射、Sketch to Code 等等。重要的不是会什么技术,而是想做成什么事情。如何让业务交付更快,让业务有更低的试错成本,这是我们需要一直思考的问题。

❉ 作者介绍 ❉
%E6%B2%AB%E6%B2%AB.png
快来做第一个评论的人吧~

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK