Skip to content

开发指南

快速开始

  1. 使用@pixso/create-plugin 创建插件项目

运行 npm 命令快速开始你的插件:

bash
npm init @pixso/plugin my-plugin

插件模板内置了 @pixso/plugin-typings 和 @pixso/plugin-cli ,降低项目搭建成本

  1. 启动本地插件项目的 dev-server
bash
cd my-plugin
npm install
npm run dev

@pixso/plugin-cli 会为你的插件应用开启热更新

注意:plugin-cli 的 dev 启动的 UI 会加载在 Non-null origin iframe 里;如果您构建打包后的 UI 是加载在 Null origin iframe 里,请注意 Web API 使用的区别。

  1. 启动 Pixso 网页中的热更新监听

Pixso 网页端将会监听本地 dev-server 的固定端口

构建用户界面

本质上,构建用户界面与开发传统 Web 应用没有任何区别。你甚至可以使用现代 Web 框架,如 VueReact 等等。以下示例使用原生技术构建用户界面。

html
<!DOCTYPE html>
<body>
  <div class="content">
    <div style="margin-bottom: 20px; color: #fff;">
      输入椭圆的数量:<input type="text" />
    </div>
    <button id="btn">创建</button>
  </div>
</body>

然后在 main.js 中编写 JavaScript 代码

js
// main.js
pixso.showUI(__html__); // 用于展示插件用户界面

Null origin iframe

Pixso 2.0 加载的 UI iframe 使用的是 data: 协议的 URL,不同于 Pixso 1.0 的 blob: 协议,主要是为了规避安全风险,保护 Pixso 数据的安全。

data: 协议加载的 iframe 的 origin 为 "null",这会限制部分 Web API 的使用,如:document.cookiewindow.localStoragewindow.sessionStorageIndexedDB

Non-null origin iframe

如果您不想您的 UI 加载在一个 null origin 的 iframe 里,还可以通过执行以下操作将 iframe 导航到自定义 URL:

pixso.showUI(`<script>window.location.href = "https://..."</script>`)

与主线程之间的消息通信

以下为用户界面与主线程之间的消息通信方式

用户界面发送消息

html
<script>
  ...
  parent.postMessage({ pluginMessage: '这是一条消息' }, '*')
  ...
</script>

主线程脚本接收消息

js
pixso.ui.onmessage = (message) => {
  console.log("收到来自前端的消息", message);
};

主线程脚本发送消息

js
pixso.ui.postMessage(42);

用户界面接收消息

html
<script>
  ...
  onmessage = (event) => {
    console.log("收到来自主线程脚本的消息", event.data.pluginMessage)
  }
  ...
</script>

通过用户界面触发 drop 事件

插件支持使用消息通知来告知 Pixso 触发 drop 事件,在调用通知的时候,支持定义 drop 事件触发的位置及其他自定义参数值。

以下是在用户界面中触发 drop 事件的示例代码:

html
parent.postMessage({ pluginDrop: PluginDrop }, '*')

PluginDrop 的类型如下:

typescript
interface PluginDrop {
  // clientX 和 clientY 取至浏览器的鼠标事件,pixso 会根据这个坐标换算出对应画布坐标系中的坐标,并在 drop 事件参数中返回。
  clientX: number;
  clientY: number;
  items?: DropItem[];
  files?: File[];
  // 自定义附加数据
  dropMetadata?: any;
  // relativeToPluginCoordinates,默认为 false,clientX 和 clientY 被当做相对于 Pixso 页面来处理;值为 true 时,clientX 和 clientY 被当做相对于插件 iframe 来处理;
  relativeToPluginCoordinates?: boolean; // 可设置为 dragEvent.view === window
}

interface DropItem {
  type: string;
  data: string;
}

发送网络请求

在 Pixso 插件中发送网络请求的方法与在 Web 浏览器中运行的普通 JavaScript 基本一致,发送网络请求的 API 由浏览器提供,而非 Pixso 提供。

以下示例通过创建一个不可见的 <iframe> 来发送网络请求。

js
pixso.showUI(__html__)
pixso.ui.postMessage({ type: 'request' })

pixso.ui.onmessage = (msg) => {
  const text = pixso.createText()
  // 将文字图层展示于可视区域中
  text.x = pixso.viewport.center.x
  text.y = pixso.viewport.center.y

  pixso.loadFontAsync(text.textStyles[0].textStyle.fontName as FontName)
    .then(() => {
      text.characters = msg
      pixso.closePlugin()
    })
}

该不可见的 <iframe> 与其他用户界面一样,需要在 manifest.json 中引用 HTML 文件。在这里,我们只是简单地制定一个标准 XMLHttpRequest 并将结果返回给主线程。

html
<script>
  window.onmessage = async (event) => {
    if (event.data.type === "request") {
      const request = new XMLHttpRequest();
      request.open("GET", "https://jsonplaceholder.typicode.com/posts");
      request.responseType = "json";
      request.onload = () => {
        window.parent.postMessage(request.response[0].title, "*");
      };
      request.send();
    }
  };
</script>