npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jieyin/editor-sdk

v1.1.125

Published

基于 Vue 3 + Fabric.js 的可视化设计编辑器 SDK,支持产品选型、刀版/变形模板、图层编辑、预览渲染与设计保存/还原。

Readme

@jieyin/editor-sdk 使用文档

基于 Vue 3 + Fabric.js 的可视化设计编辑器 SDK,支持产品选型、刀版/变形模板、图层编辑、预览渲染与设计保存/还原。


目录


安装与依赖

npm install @jieyin/editor-sdk
# 或
pnpm add @jieyin/editor-sdk
# 或
yarn add @jieyin/editor-sdk

对等依赖(需在业务项目中安装)

| 依赖 | 版本 | | --- | ------ | | vue | ^3.5.0 |

引入样式

import '@jieyin/editor-sdk/style.css'

快速开始

方式一:全局注册

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { install } from '@jieyin/editor-sdk'
import '@jieyin/editor-sdk/style.css'

const app = createApp(App)
app.use(install)
app.mount('#app')
<template>
  <Editor
    :product="product"
    :basic-info="basicInfo"
    :diecut-data="diecutData"
    :deformation-data="deformationData"
    :license-config="licenseConfig"
    :file-token="fileToken"
    @save-design="onSaveDesign"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import type { ProductItem, BasicInfo, DiecutResponse, DeformationResponse, LicenseConfig } from '@jieyin/editor-sdk'

const product = ref<ProductItem | null>(null)
const basicInfo = ref<BasicInfo | null>(null)
const diecutData = ref<DiecutResponse | null>(null)
const deformationData = ref<DeformationResponse | null>(null)
const fileToken = ref<string | null>(null)
const licenseConfig: LicenseConfig = {
  licenseKey: 'YOUR_LICENSE_KEY',
  apiBaseUrl: 'https://your-license-api.com'
}

function onSaveDesign() {
  // 调用业务保存接口
}
</script>

方式二:按需引入组件

<template>
  <Editor
    :product="product"
    :basic-info="basicInfo"
    :diecut-data="diecutData"
    :deformation-data="deformationData"
    :options="{ showTopbar: true, showSidebar: true, showPreview: true }"
    :license-config="licenseConfig"
    :file-token="fileToken"
    :on-save-design="onSaveDesign"
    :on-object-modified="onObjectModified"
  />
</template>

<script setup lang="ts">
import { Editor, type LicenseConfig, type ProductItem, type BasicInfo, type DiecutResponse, type DeformationResponse } from '@jieyin/editor-sdk'
import '@jieyin/editor-sdk/style.css'

// ... 同上
</script>

Editor 组件

Props

| 属性 | 类型 | 默认值 | 说明 | | ------------------------ | ------------------------------------------------------------ | ------ | ------------------------------------------- | | product | ProductItem \| null | null | 当前选中的产品(单产品模式直接传入) | | basicInfo | BasicInfo \| null | null | 产品基础信息(名称、尺码、颜色等) | | diecutData | DiecutResponse \| null | null | 刀版数据(含 jsonURL、resources 等) | | deformationData | DeformationResponse \| null | null | 变形/模板数据 | | options | EditorOptions | 见下 | 界面与行为配置 | | productListApi | ProductListApi | - | 产品列表接口(列表模式必传) | | productDetailApi | ProductDetailApi | - | 产品详情接口(列表模式必传) | | productListPageSize | number | - | 产品列表每页条数 | | productListInitialPage | number | - | 产品列表初始页码 | | initialProductId | string \| number | - | 进入时默认选中的产品 ID;不在第一页时也会按 ID 加载详情并展示 | | fileBaseUrl | string | - | 文件资源基础 URL(用于代理/拼接) | | licenseConfig | LicenseConfig | - | License 配置(不传则不做 License 校验) | | fileToken | string \| null | null | 文件访问 Token(用于带鉴权的图片/资源) | | onObjectModified | (getDiecutStateMap: () => Record<string, unknown>) => void | - | 画布内容变更回调,可在此调用 getDiecutStateMap() 拿各刀版状态 | | onRenderAllTemplates | (renderMethod) => Promise<...> | - | 自定义「渲染所有模板」逻辑(如上传到服务器) | | onSaveDesign | () => void \| Promise<void> | - | 保存设计(传入则在 Topbar 显示保存按钮) | | onGoHome | () => void | - | 返回首页(传入则在 Topbar 显示返回按钮) | | onTemplateReady | () => void | - | 首次模板加载完成后调用(可用于从 completeJsonUrl 还原设计) |

EditorOptions

interface EditorOptions {
  showTopbar?: boolean    // 是否显示顶栏,默认 true
  showSidebar?: boolean   // 是否显示左侧栏,默认 true
  showPreview?: boolean   // 是否显示预览面板,默认 true
  enableGrid?: boolean   // 是否启用网格,默认 true
  usePreviewEffect?: boolean  // 是否使用预览效果组件,默认 true
}

暴露方法(ref 调用)

通过 ref 获取组件实例后,可调用以下方法:

| 方法 | 说明 | | -------------------------------- | ------------------------------------------------------------------------------- | | renderAllTemplates() | 渲染当前产品下所有模板,返回 Promise<Array<{ index: number; bitmap: ImageBitmap \| null }>> | | triggerRenderAllTemplates() | 触发一次「渲染所有模板」(会走 onRenderAllTemplates 若已传) | | getDiecutStateMap() | 获取当前各刀版画布状态 Map(用于保存设计) | | getCurrentProductName() | 获取当前产品名称 | | loadCanvasJson(diecutId, json) | 按刀版 ID 加载一份画布 JSON | | loadDesignStateMap(stateMap) | 从「按 diecutId 分组」的状态 Map 还原整单设计 |

示例:

<template>
  <Editor ref="editorRef" ... />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Editor } from '@jieyin/editor-sdk'

const editorRef = ref<InstanceType<typeof Editor> | null>(null)

async function save() {
  const stateMap = editorRef.value?.getDiecutStateMap?.()
  const name = editorRef.value?.getCurrentProductName?.()
  // 上传 stateMap、name 到后端...
}

async function restore(stateMap: Record<string, unknown>) {
  editorRef.value?.loadDesignStateMap?.(stateMap)
}
</script>

类型定义

@jieyin/editor-sdk 可导出以下常用类型(详见 src/types.ts):

  • 产品与配置ProductItemBasicInfoEditorOptionsEditorPropsLicenseConfig
  • 刀版与变形DiecutResourceDiecutItemDiecutResponseDeformationInfoDeformationGroupDeformationResponseDeformationSizeGroupDeformationColorGroup
  • 接口约定ProductListApiProductDetailApiProductListResultProductDetailResult
import type {
  ProductItem,
  BasicInfo,
  DiecutResponse,
  DeformationResponse,
  EditorOptions,
  LicenseConfig,
  ProductListApi,
  ProductDetailApi
} from '@jieyin/editor-sdk'

工具与服务

文件 Token(fileToken)

用于带鉴权的文件 URL(如图片、刀版资源)。支持「外部注入」或「内部拉取 + 自动附加」。

import {
  setExternalFileToken,
  getFileToken,
  clearFileToken,
  ensureFileToken,
  appendFileTokenToUrl,
  appendFileTokenIfPresent,
  withFileToken,
  fetchWithFileToken,
  setFileTokenFetchers,
  isFileTokenExpired
} from '@jieyin/editor-sdk'
  • 外部注入:业务侧维护 Token,通过 setExternalFileToken(token) 注入;Editor 内部请求文件时会自动用该 Token 拼到 URL。
  • 内部拉取setFileTokenFetchers({ fetchFileToken, fetchFileTokenRefresh }) 后,ensureFileToken() / fetchWithFileToken(url) 会负责获取/刷新并附加 Token。

License

import {
  LicenseAPI,
  LicenseManager,
  setLicenseInfo,
  getLicenseInfo,
  clearLicenseInfo,
  TokenRefresher,
  withRetry
} from '@jieyin/editor-sdk'
  • 在 Editor 上通过 licenseConfig 传入即可完成校验与刷新;也可在非 Editor 场景下单独使用 LicenseManager / LicenseAPI

渲染服务(renderService)

用于按 JSON 渲染位图、蒙版、混合等(多用于预览与导出):

import type { IRenderByJson } from '@jieyin/editor-sdk'
// 以及 renderService 下具体方法按需使用

进阶:Composables

Editor 内部由多个 composable 组成(产品数据、模板、刀版、画布、图层、工具状态等)。若你需要在自定义页面中复用某一块能力,可直接从 SDK 引入对应 composable(注:部分依赖 Editor 内部上下文,建议以「使用 Editor 组件」为主,按需再抽 composable)。

导出列表见 sdk/src/components/Editor/composables/index.ts,例如:

  • useLicenseuseProductDatauseToolStateuseTemplateManager
  • useCanvasManageruseLayerManageruseDiecutManager
  • useImageHandleruseTextHandleruseLayerOperationsuseObjectAdder
  • usePreviewManagerusePreviewRendererusePreviewUpdateQueue
  • useTemplateLoaderuseCanvasStateByDiecutuseCanvasViewport
  • useEditorWatchersuseCopyToDiecutsuseClearCanvasuseEditorResetuseDownloadPng
  • 以及相关类型:TemplateItemLayerDiecutOptionUseTemplateLoaderOptions

更细的 composable 说明见:sdk/src/components/Editor/README.md


常见场景示例

单产品模式(直接传产品与详情数据)

<Editor
  :product="product"
  :basic-info="basicInfo"
  :diecut-data="diecutData"
  :deformation-data="deformationData"
  :file-token="fileToken"
  :license-config="licenseConfig"
  :on-save-design="onSaveDesign"
/>

数据由业务侧请求产品详情接口得到后,赋给 basicInfodiecutDatadeformationData 即可。

产品列表模式(分页 + 选产品拉详情)

<Editor
  :product-list-api="productListApi"
  :product-detail-api="productDetailApi"
  :product-list-page-size="12"
  :product-list-initial-page="1"
  :initial-product-id="initialProductId"
  :file-token="fileToken"
  :license-config="licenseConfig"
  :on-save-design="onSaveDesign"
/>
  • productListApi(page, pageSize) 返回 { rows: ProductItem[], total?: number }
  • productDetailApi(productId) 返回 { basicInfo, diecutData, deformationData }
  • initialProductId 若落在第一页列表中,进入后会默认选中该产品。

保存设计(拿状态 Map + 调用业务接口)

const editorRef = ref<InstanceType<typeof Editor> | null>(null)

async function onSaveDesign() {
  const stateMap = editorRef.value?.getDiecutStateMap?.()
  const productName = editorRef.value?.getCurrentProductName?.()
  if (!stateMap) return
  await saveDesignTask({ productName, stateMap })
}

从已保存设计还原(如编辑我的设计)

  1. 拉取设计详情,拿到 completeJsonUrl 或按刀版分组的 stateMap

  2. 若用 stateMap:先让 Editor 完成模板加载(产品、刀版、变形数据就绪),在 onTemplateReady 中调用:

    editorRef.value?.loadDesignStateMap?.(stateMap)
  3. 若用 completeJsonUrl:在 onTemplateReady 中 fetch 该 JSON,按你与后端的约定解析成 stateMap 再调用 loadDesignStateMap(stateMap)

License 配置

const licenseConfig: LicenseConfig = {
  licenseKey: 'YOUR_LICENSE_KEY',
  apiBaseUrl: 'https://your-license-api.com',
  timeout: 10000,
  enableAutoRefresh: true,
  refreshThreshold: 0.3,
  onError: (err) => console.error('License Error:', err),
  onSuccess: () => console.log('License OK'),
  onTokenRefresh: (token) => { /* 可选:同步到业务 */ }
}

不传 licenseConfig 时,Editor 不进行 License 校验,直接进入编辑界面。

文件 Token(外部注入,如登录后从业务接口拿)

const fileToken = ref<string | null>(null)

onMounted(async () => {
  const res = await yourAuthApi.getFileToken()
  fileToken.value = res.file_token
  // 可选:同步给 SDK 内部使用
  setExternalFileToken(res.file_token)
})
<Editor :file-token="fileToken" ... />

业务侧负责 Token 刷新时,保持 fileTokensetExternalFileToken 更新即可。


版本与构建

  • 当前包名:@jieyin/editor-sdk,版本见 package.json
  • 构建:npm run build(会先执行 wasm 构建再打 SDK 包)。
  • 产物:dist/editor-sdk.es.jsdist/style.cssdist/index.d.ts

如有问题或需要定制,请联系维护团队。