更新记录

1.0.0(2026-06-17) 下载此版本

v1.0.0 (2024-06-17)

新功能

  • 首次发布 jz-writepad 多端手写签名画板组件
  • 支持三端通用:H5、微信小程序、支付宝小程序、App 等多平台
  • 实现手指触摸绘制(主动绘制)功能
  • 实现外部数据驱动绘制(被动绘制)功能
  • 实现实时数据同步功能(draw-frame 事件)
  • 实现透明背景 PNG 图片导出
  • 支持临时文件链接和 base64 两种导出格式
  • H5 平台支持 uni.createWritepad() API 方式
  • 使用贝塞尔曲线算法实现平滑绘制
  • 支持撤销、清空画布功能
  • 支持自定义笔触颜色、宽度、样式

技术架构

  • 使用纯 JS Class 实现
  • 基础类 + 实体类继承架构
  • 平台差异通过渲染器子类实现
  • 事件系统基于 BaseEventEmitter

已知问题

  • App-Nvue 平台兼容性待测试
  • 压感功能仅部分设备支持

平台兼容性

uni-app(4.73)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - -

jz-writepad 多端手写签名画板

支持三端通用(H5、小程序、App)的手写签名/涂鸦画板组件,使用纯 JS Class 实现。

核心特性

  • 全屏画布 - 支持自定义尺寸或全屏模式
  • 双模式绘制 - 支持手指触摸绘制(主动绘制)和外部数据驱动绘制(被动绘制)
  • 实时数据同步 - 触摸绘制时实时抛出绘制数据,支持远程同步场景
  • 透明背景导出 - 导出 PNG 透明背景图片,支持临时链接或 base64 格式
  • H5 特殊挂载 - H5 平台支持通过 API 直接挂载到 DOM,无需引入组件
  • 多端兼容 - H5、微信小程序、支付宝小程序、App 等多平台支持
  • 纯 JS Class 实现 - 基础类 + 实体类继承架构,代码结构清晰

安装使用

方式一:组件引入(小程序/App)

<template>
  <view class="page">
    <jz-writepad
      ref="writepad"
      :fullscreen="false"
      width="750rpx"
      height="500rpx"
      strokeColor="#333333"
      :strokeWidth="2"
      @draw-frame="handleDrawFrame"
      @draw-end="handleDrawEnd"
      @ready="handleReady"
    />

    <view class="actions">
      <button @tap="handleUndo">撤销</button>
      <button @tap="handleClear">清空</button>
      <button @tap="handleExport">导出签名</button>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue';

const writepad = ref(null);

// 接收实时绘制数据(用于远程同步)
function handleDrawFrame(frame) {
  // 将 frame 发送到远程服务器或 WebSocket
  console.log('Draw frame:', frame);
  // ws.send(JSON.stringify(frame));
}

// 画布就绪
function handleReady(canvasId) {
  console.log('Canvas ready:', canvasId);
}

// 导出签名
async function handleExport() {
  const result = await writepad.value.exportImage({
    format: 'base64'
  });
  console.log('Export result:', result);
}

// 撤销
function handleUndo() {
  writepad.value.undo();
}

// 清空
function handleClear() {
  writepad.value.clear();
}
</script>

方式二:H5 API 方式(无需组件引入)

// H5 平台直接通过 API 创建全屏画板
const writepad = uni.createWritepad({
  strokeColor: '#000000',
  strokeWidth: 3,
  zIndex: 9999,
  sessionId: 'user_123'
});

// 监听绘制事件(核心同步功能)
writepad.on('draw-frame', (frame) => {
  // 发送到远程同步
  socket.send(JSON.stringify(frame));
});

// 监听其他事件
writepad.on('draw-start', (point) => console.log('开始绘制', point));
writepad.on('draw-move', (point) => console.log('绘制移动', point));
writepad.on('draw-end', (path) => console.log('结束绘制', path));

// 导出签名
writepad.exportImage({ format: 'base64' }).then(result => {
  console.log('签名图片:', result.data);
});

// 销毁画板
writepad.destroy();

组件属性 Props

属性 类型 默认值 说明
width String/Number '100%' 画布宽度
height String/Number '100%' 画布高度
fullscreen Boolean true 是否全屏模式
strokeColor String '#000000' 笔触颜色
strokeWidth Number 3 笔触宽度(像素)
strokeStyle String 'solid' 笔触样式:'solid' | 'dashed'
disabled Boolean false 是否禁用触摸绘制
enablePressure Boolean false 是否启用压感
backgroundColor String 'transparent' 背景颜色
backgroundImage String '' 背景图片 URL
sessionId String 'default' 会话 ID(用于区分绘制来源)
drawData Array [] 外部绘制数据队列(被动绘制)
exportFormat String 'tempFile' 导出格式:'tempFile' | 'base64'
exportQuality Number 1 导出图片质量 0-1
showToolbar Boolean false 是否显示内置工具栏

组件事件 Events

事件 参数 说明
draw-frame frame: DrawFrame 核心事件,每个绘制动作实时抛出,用于远程同步
draw-start point: DrawPoint 开始绘制
draw-move point: DrawPoint 绘制移动
draw-end path: DrawPath 结束绘制(返回完整路径)
clear - 清空画布
undo pathId: String 撤销路径
export-success result: ExportResult 导出成功
export-error error: Error 导出失败
ready canvasId: String 画布初始化完成

组件方法 Methods

通过 ref 调用组件方法:

const writepad = ref(null);

// 导出图片
await writepad.value.exportImage({ format: 'base64' });

// 导出签名(自动裁剪空白区域)
await writepad.value.exportSignature({ padding: 10 });

// 清空画布
writepad.value.clear();

// 撤销最后一笔
writepad.value.undo();

// 撤销指定路径
writepad.value.undoPath(pathId);

// 获取所有路径
const paths = writepad.value.getPaths();

// 获取路径数据(可序列化)
const data = writepad.value.getPathsData();

// 设置笔触配置
writepad.value.setStroke({ color: '#ff0000', width: 5 });

// 执行外部绘制数据
writepad.value.executeDrawData(frames);

绘制数据结构

DrawPoint 绘制点

{
  id: 'point_xxx',       // 点 ID
  x: 100,                // X 坐标
  y: 200,                // Y 坐标
  timestamp: 1700000000, // 时间戳(毫秒)
  action: 'start',       // 动作类型:'start' | 'move' | 'end'
  pressure: 0.5          // 压感值(可选,0-1)
}

DrawPath 绘制路径

{
  id: 'path_xxx',        // 路径 ID
  points: [...],         // 路径点集合
  strokeColor: '#000000',// 笔触颜色
  strokeWidth: 3,        // 笔触宽度
  strokeStyle: 'solid',  // 笔触样式
  startTime: 1700000000, // 开始时间
  endTime: 1700000010,   // 结束时间
  completed: true        // 是否完成
}

DrawFrame 绘制帧(同步数据)

{
  type: 'path_point',    // 帧类型:'path_start' | 'path_point' | 'path_end' | 'clear' | 'undo'
  data: {...},           // 帧数据(点或路径)
  sessionId: 'user_123', // 会话 ID
  sequence: 1            // 序列号(用于排序)
}

远程同步绘制示例

<template>
  <jz-writepad
    ref="writepad"
    :drawData="remoteDrawData"
    :sessionId="sessionId"
    @draw-frame="sendToRemote"
  />
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const writepad = ref(null);
const remoteDrawData = ref([]);
const sessionId = ref('user_123');

let ws = null;

onMounted(() => {
  // 建立 WebSocket 连接
  ws = new WebSocket('ws://your-server/sync');

  ws.onmessage = (event) => {
    const frame = JSON.parse(event.data);
    if (frame.sessionId !== sessionId.value) {
      // 来自其他用户,添加到绘制队列
      remoteDrawData.value.push(frame);
    }
  };
});

onUnmounted(() => {
  if (ws) ws.close();
});

// 发送本地绘制数据到远程
function sendToRemote(frame) {
  if (ws && ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify(frame));
  }
}
</script>

类架构说明

本插件使用纯 JS Class 实现,采用基础类 + 实体类继承架构:

基础类层

  • BaseEntity - 最基础实体类,提供 ID 生成、属性管理
  • BaseEventEmitter - 事件发射器基类,提供 on/off/emit 方法

数据实体类层(继承 BaseEntity)

  • DrawPoint - 绘制点类
  • DrawPath - 绘制路径类(聚合 DrawPoint)
  • DrawFrame - 绘制帧类(用于同步)

渲染器类层(继承 BaseCanvasRenderer)

  • BaseCanvasRenderer - Canvas 渲染器基类(定义抽象接口)
  • H5CanvasRenderer - H5 渲染器(实现 H5 平台 Canvas 2D API)
  • UniCanvasRenderer - 小程序/App 渲染器(实现 uni Canvas API)

管理器类层(继承 BaseEventEmitter)

  • DrawEngine - 绘制引擎(聚合渲染器,处理绘制逻辑)
  • DataParser - 数据解析器(解析外部绘制数据)
  • ExportManager - 导出管理器(处理图片导出)
  • WritepadManager - H5 全屏管理器(H5 API 方式使用)
  • WritepadInstance - H5 实例类(单个画板实例)

支持平台

平台 支持状态 说明
H5 ✅ 完全支持 支持 API 方式和组件方式
微信小程序 ✅ 完全支持 使用组件方式
支付宝小程序 ✅ 完全支持 使用组件方式
百度小程序 ✅ 完全支持 使用组件方式
字节跳动小程序 ✅ 完全支持 使用组件方式
App-Vue ✅ 完全支持 使用组件方式
App-Nvue ⚠️ 不确定 Nvue 使用 gcanvas,需要特殊处理

更新日志

v1.0.0

  • 首次发布
  • 支持三端通用(H5、小程序、App)
  • 实现实时数据同步功能
  • 支持透明背景导出
  • H5 平台支持 API 方式挂载

License

MIT

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。