@plait 系列库 API 完整文档
概述
@plait 是一个强大的画图框架系列,为 Drawnix 提供了完整的绘图、思维导图和文本编辑功能。本文档详细介绍了项目中使用的所有 @plait 相关库的 API、使用方法和示例。
📦 库概览
| 库名称 | 版本 | 主要功能 | 核心特性 |
|---|---|---|---|
@plait/core | ^0.86.1 | 核心框架 | 画板、元素管理、变换操作、插件系统 |
@plait/draw | ^0.86.1 | 绘图功能 | 几何图形、箭头、图像、表格、矢量线 |
@plait/mind | ^0.86.1 | 思维导图 | 节点管理、布局算法、分支样式 |
@plait/common | ^0.86.1 | 通用工具 | 分组、图片、文本、属性管理 |
@plait/layouts | ^0.86.1 | 布局算法 | 思维导图布局、自动排列 |
@plait/text-plugins | ^0.86.1 | 文本插件 | 富文本编辑、链接、格式化 |
@plait-board/react-board | - | React组件 | React集成、组件封装、事件处理 |
🎯 @plait/core - 核心框架
核心接口
PlaitBoard - 画板核心接口
typescript
interface PlaitBoard {
// 基础属性
viewport: Viewport; // 视口信息
children: PlaitElement[]; // 子元素列表
theme: PlaitTheme; // 主题配置
operations: PlaitOperation[]; // 操作历史
selection: Selection | null; // 当前选择
pointer: PlaitPointerType | string; // 当前指针类型
history: PlaitHistory; // 历史记录
options: PlaitBoardOptions; // 板配置选项
// 核心方法
undo(): void; // 撤销操作
redo(): void; // 重做操作
apply(operation: PlaitOperation): void; // 应用操作
onChange(): void; // 变更回调
afterChange(): void; // 变更后回调
// 事件处理
mousedown(event: MouseEvent): void; // 鼠标按下
mousemove(event: MouseEvent): void; // 鼠标移动
mouseup(event: MouseEvent): void; // 鼠标释放
keyDown(event: KeyboardEvent): void; // 键盘按下
// 元素操作
drawElement(context: PlaitPluginElementContext): ComponentType<ElementFlavour>;
isHit(element: PlaitElement, point: Point, isStrict?: boolean): boolean;
getRectangle(element: PlaitElement): RectangleClient | null;
}PlaitElement - 元素基类
typescript
interface PlaitElement {
id: string; // 唯一标识
children?: PlaitElement[]; // 子元素
points?: Point[]; // 坐标点
type?: string; // 元素类型
groupId?: string; // 所属组ID
angle?: number; // 旋转角度
[key: string]: any; // 扩展属性
}PlaitPointerType - 指针类型枚举
typescript
enum PlaitPointerType {
hand = "hand", // 手型工具
selection = "selection" // 选择工具
}PlaitBoardOptions - 画板配置
typescript
interface PlaitBoardOptions {
readonly?: boolean; // 是否只读
hideScrollbar?: boolean; // 隐藏滚动条
disabledScrollOnNonFocus?: boolean; // 非焦点时禁用滚动
themeColors?: ThemeColor[]; // 主题颜色
}核心工具类
PlaitBoard 工具类
typescript
const PlaitBoard = {
// 类型检查
isBoard(value: any): value is PlaitBoard;
isAlive(board: PlaitBoard): boolean;
// 路径和节点
findPath(board: PlaitBoard, node: PlaitNode): Path;
// DOM 获取
getHost(board: PlaitBoard): SVGSVGElement;
getElementHost(board: PlaitBoard): SVGSVGElement;
getRoughSVG(board: PlaitBoard): RoughSVG;
getBoardContainer(board: PlaitBoard): HTMLElement;
// 状态检查
isFocus(board: PlaitBoard): boolean;
getPointer<T = PlaitPointerType>(board: PlaitBoard): T;
isPointer<T = PlaitPointerType>(board: PlaitBoard, pointer: T): boolean;
// 元素操作
getSelectedElements(board: PlaitBoard): PlaitElement[];
isSelectionGrip(board: PlaitBoard): boolean;
};BoardTransforms - 画板变换操作
typescript
const BoardTransforms = {
// 指针类型更新
updatePointerType(board: PlaitBoard, pointer: string): void;
// 视口操作
updateViewport(board: PlaitBoard, viewport: Partial<Viewport>): void;
// 主题操作
updateTheme(board: PlaitBoard, theme: Partial<PlaitTheme>): void;
// 选择操作
updateSelection(board: PlaitBoard, selection: Selection | null): void;
};核心插件
withBoard - 核心画板插件
typescript
const withBoard: (board: PlaitBoard) => PlaitBoard;功能: 提供基础的画板功能,包括元素管理、事件处理、渲染等。
withHistory - 历史记录插件
typescript
const withHistory: (board: PlaitBoard) => PlaitBoard;功能: 提供撤销/重做功能,管理操作历史。
withSelection - 选择插件
typescript
const withSelection: (board: PlaitBoard) => PlaitBoard;功能: 提供元素选择、多选、选择框等功能。
使用示例
typescript
import { PlaitBoard, PlaitElement, PlaitPointerType, withBoard, withHistory, withSelection } from '@plait/core';
// 创建画板
const board = createBoard();
const enhancedBoard = withSelection(withHistory(withBoard(board)));
// 操作画板
BoardTransforms.updatePointerType(enhancedBoard, PlaitPointerType.selection);
// 获取选中元素
const selectedElements = PlaitBoard.getSelectedElements(enhancedBoard);
// 检查指针类型
if (PlaitBoard.isPointer(enhancedBoard, PlaitPointerType.hand)) {
console.log('当前是手型工具');
}🎨 @plait/draw - 绘图功能库
主要类型
PlaitDrawElement - 绘图元素联合类型
typescript
type PlaitDrawElement =
| PlaitGeometry // 几何图形
| PlaitArrowLine // 箭头线
| PlaitVectorLine // 矢量线
| PlaitImage // 图像
| PlaitBaseTable // 表格
| PlaitSwimlane // 泳道图;DrawPointerType - 绘图指针类型
typescript
type DrawPointerType =
| BasicShapes // 基础形状
| ArrowLineShape // 箭头形状
| FlowchartSymbols // 流程图符号
| SwimlaneDrawSymbols // 泳道符号
| TableSymbols // 表格符号
| UMLSymbols // UML符号
| VectorLinePointerType // 矢量线类型;BasicShapes - 基础形状枚举
typescript
enum BasicShapes {
rectangle = "rectangle",
ellipse = "ellipse",
diamond = "diamond",
roundRectangle = "roundRectangle",
parallelogram = "parallelogram",
text = "text",
triangle = "triangle",
leftArrow = "leftArrow",
trapezoid = "trapezoid",
rightArrow = "rightArrow",
cross = "cross",
star = "star",
pentagon = "pentagon",
hexagon = "hexagon",
octagon = "octagon",
// ... 更多形状
}PlaitGeometry - 几何图形接口
typescript
interface PlaitGeometry extends PlaitElement {
type: 'geometry';
shape: GeometryShapes; // 形状类型
text?: Element; // 文本元素
width: number; // 宽度
height: number; // 高度
strokeWidth: number; // 描边宽度
strokeColor: string; // 描边颜色
fill?: string; // 填充颜色
strokeStyle?: StrokeStyle; // 描边样式
angle?: number; // 旋转角度
opacity?: number; // 透明度
}PlaitArrowLine - 箭头线接口
typescript
interface PlaitArrowLine extends PlaitElement {
type: 'arrow';
points: Point[]; // 路径点
strokeWidth: number; // 描边宽度
strokeColor: string; // 描边颜色
startHandle: ArrowLineHandle; // 起始手柄
endHandle: ArrowLineHandle; // 结束手柄
texts?: ArrowLineText[]; // 文本标签
strokeStyle?: StrokeStyle; // 描边样式
angle?: number; // 旋转角度
opacity?: number; // 透明度
}核心工具类
PlaitDrawElement 工具类
typescript
const PlaitDrawElement = {
// 类型检查方法
isGeometry(value: any): value is PlaitGeometry;
isArrowLine(value: any): value is PlaitArrowLine;
isVectorLine(value: any): value is PlaitVectorLine;
isImage(value: any): value is PlaitImage;
isTable(value: any): value is PlaitTable;
isDrawElement(value: any): value is PlaitDrawElement;
// 分类检查
isBasicShape(value: any): boolean;
isFlowchart(value: any): boolean;
isUML(value: any): boolean;
};DrawTransforms - 绘图变换操作
typescript
const DrawTransforms = {
// 几何图形操作
insertGeometry(
board: PlaitBoard,
points: Point[],
shape: GeometryShapes
): PlaitGeometry;
resizeGeometry(
board: PlaitBoard,
points: Point[],
textHeight: number,
path: Path
): void;
setText(
board: PlaitBoard,
element: PlaitGeometry,
text: Element,
width: number,
textHeight: number
): void;
insertText(
board: PlaitBoard,
point: Point,
text: string
): void;
// 箭头线操作
resizeArrowLine(
board: PlaitBoard,
options: ArrowLineResizeOptions,
path: Path
): void;
setArrowLineTexts(
board: PlaitBoard,
element: PlaitArrowLine,
texts: ArrowLineText[]
): void;
connectArrowLineToDraw(
board: PlaitBoard,
lineElement: PlaitArrowLine,
handle: ArrowLineHandle,
geometryElement: PlaitGeometry
): void;
// 形状切换
switchGeometryShape(board: PlaitBoard, shape: GeometryShapes): void;
// 图像操作
insertImage(
board: PlaitBoard,
imageItem: CommonImageItem,
startPoint?: Point
): void;
};插件配置
WithDrawOptions - 绘图插件选项
typescript
interface WithDrawOptions extends WithPluginOptions {
customGeometryTypes: string[]; // 自定义几何形状类型
}withDraw - 绘图插件
typescript
const withDraw: (options?: WithDrawOptions) => PlaitPlugin;功能: 提供完整的绘图功能,包括几何图形、箭头、图像等。
使用示例
typescript
import {
withDraw,
DrawTransforms,
PlaitDrawElement,
BasicShapes,
FlowchartSymbols
} from '@plait/draw';
import { PlaitBoard } from '@plait/core';
// 启用绘图功能
const drawPlugin = withDraw({
customGeometryTypes: ['customHeart', 'customStar']
});
// 插入矩形
const rectangle = DrawTransforms.insertGeometry(
board,
[{x: 100, y: 100}, {x: 200, y: 200}],
BasicShapes.rectangle
);
// 插入流程图符号
const processSymbol = DrawTransforms.insertGeometry(
board,
[{x: 300, y: 100}, {x: 400, y: 200}],
FlowchartSymbols.process
);
// 检查元素类型
if (PlaitDrawElement.isGeometry(rectangle)) {
console.log('这是一个几何图形');
}
// 调整图形大小
DrawTransforms.resizeGeometry(
board,
[{x: 100, y: 100}, {x: 250, y: 250}],
20,
PlaitBoard.findPath(board, rectangle)
);🧠 @plait/mind - 思维导图库
主要类型
PlaitMind - 思维导图元素
typescript
interface PlaitMind<T = BaseData> extends MindElement<T> {
type: 'mind' | 'mindmap';
points: Point[]; // 位置点
}MindElement - 思维导图节点
typescript
interface MindElement<T = BaseData> extends BaseMindElement {
type: 'mind_child' | 'mind' | 'mindmap';
children: MindElement[]; // 子节点
data: T; // 节点数据
}BaseData - 基础数据结构
typescript
interface BaseData {
topic: string; // 节点文本
created?: number; // 创建时间
updated?: number; // 更新时间
expanded?: boolean; // 是否展开
color?: string; // 节点颜色
fontColor?: string; // 字体颜色
fontSize?: number; // 字体大小
fontWeight?: string; // 字体粗细
fontStyle?: string; // 字体样式
textDecoration?: string; // 文本装饰
}MindElementShape - 节点形状枚举
typescript
enum MindElementShape {
roundRectangle = "round-rectangle", // 圆角矩形
underline = "underline" // 下划线形状
}BranchShape - 分支形状枚举
typescript
enum BranchShape {
bight = "bight", // 曲线
polyline = "polyline" // 折线
}MindLayoutType - 布局类型枚举
typescript
enum MindLayoutType {
right = "right", // 右侧布局
left = "left", // 左侧布局
standard = "standard", // 标准布局
upward = "upward", // 向上布局
downward = "downward", // 向下布局
rightBottomIndented = "right-bottom-indented", // 右下缩进
rightTopIndented = "right-top-indented", // 右上缩进
leftTopIndented = "left-top-indented", // 左上缩进
leftBottomIndented = "left-bottom-indented" // 左下缩进
}核心工具类
PlaitMind 工具类
typescript
const PlaitMind = {
isMind(value: any): value is PlaitMind;
};MindElement 工具类
typescript
const MindElement = {
// 布局检查
hasLayout(value: MindElement, layout: MindLayoutType): boolean;
isIndentedLayout(value: MindElement): boolean;
isMindElement(board: PlaitBoard | null, element: PlaitElement): element is MindElement;
// 节点关系
getParent(node: MindElement): MindElement<BaseData>;
getRoot(board: PlaitBoard, element: MindElement): PlaitMind;
getAncestors(board: PlaitBoard, element: MindElement): PlaitElement[];
getDepth(element: MindElement): number;
// 特性检查
hasEmojis(element: MindElement): element is MindElement<EmojiData>;
hasImage(element: MindElement): element is MindElement<ImageData>;
// 节点操作
isFirstChild(node: MindElement): boolean;
isLastChild(node: MindElement): boolean;
getSiblings(board: PlaitBoard, node: MindElement): MindElement[];
};MindTransforms - 思维导图变换操作
typescript
const MindTransforms = {
// 布局设置
setLayout(board: PlaitBoard, type: MindLayoutType): void;
setShape(board: PlaitBoard, shape: MindElementShape): void;
setBranchShape(board: PlaitBoard, branchShape: BranchShape): void;
setBranchWidth(board: PlaitBoard, branchWidth: number): void;
setBranchColor(board: PlaitBoard, branchColor: string): void;
// 节点内容
setTopic(board: PlaitBoard, element: MindElement, topic?: string): void;
// 表情符号
addEmoji(board: PlaitBoard, element: MindElement, emojiItem: EmojiItem): void;
removeEmoji(board: PlaitBoard, element: MindElement, emojiItem: EmojiItem): void;
// 节点结构
insertChildNode(board: PlaitBoard, element: MindElement): void;
insertSiblingNode(board: PlaitBoard, element: MindElement): void;
insertMind(board: PlaitBoard, mind: PlaitMind): void;
removeNode(board: PlaitBoard, element: MindElement): void;
// 节点样式
setColor(board: PlaitBoard, element: MindElement, color: string): void;
setFontColor(board: PlaitBoard, element: MindElement, color: string): void;
setFontSize(board: PlaitBoard, element: MindElement, size: number): void;
};插件
withMind - 思维导图插件
typescript
const withMind: (baseBoard: PlaitBoard) => PlaitBoard & PlaitMindEmojiBoard;功能: 提供完整的思维导图功能,包括节点管理、布局算法、样式设置等。
使用示例
typescript
import {
withMind,
MindTransforms,
MindElement,
MindLayoutType,
MindElementShape,
PlaitMind
} from '@plait/mind';
import { PlaitBoard } from '@plait/core';
// 启用思维导图功能
const mindBoard = withMind(board);
// 创建思维导图
const mindData: PlaitMind = {
type: 'mind',
id: 'mind-1',
points: [{x: 400, y: 300}],
data: { topic: '中心主题' },
children: [
{
type: 'mind_child',
id: 'child-1',
data: { topic: '子主题1' },
children: []
}
]
};
MindTransforms.insertMind(mindBoard, mindData);
// 设置布局
MindTransforms.setLayout(mindBoard, MindLayoutType.standard);
// 设置节点形状
MindTransforms.setShape(mindBoard, MindElementShape.roundRectangle);
// 添加子节点
const rootNode = MindElement.getRoot(mindBoard, mindData);
MindTransforms.insertChildNode(mindBoard, rootNode);
// 检查节点类型
if (MindElement.isMindElement(mindBoard, selectedElement)) {
const depth = MindElement.getDepth(selectedElement);
console.log(`节点深度: ${depth}`);
}🛠️ @plait/common - 通用工具库
主要功能
PropertyTransforms - 属性变换操作
typescript
const PropertyTransforms = {
// 设置元素属性
setProperty(board: PlaitBoard, element: PlaitElement, key: string, value: any): void;
setProperties(board: PlaitBoard, element: PlaitElement, properties: Record<string, any>): void;
// 删除属性
unsetProperty(board: PlaitBoard, element: PlaitElement, key: string): void;
// 获取属性
getProperty(board: PlaitBoard, element: PlaitElement, key: string): any;
};BoardCreationMode - 创建模式枚举
typescript
enum BoardCreationMode {
dnd = "dnd", // 拖拽创建
drawing = "drawing" // 绘制创建
}setCreationMode - 设置创建模式
typescript
const setCreationMode = (board: PlaitBoard, mode: BoardCreationMode): void;核心插件
withGroup - 分组插件
typescript
const withGroup: (board: PlaitBoard) => PlaitBoard;功能: 提供元素分组功能,支持多元素组合、取消组合、嵌套分组等。
withImage - 图片插件
typescript
const withImage: (board: PlaitBoard) => PlaitBoard;功能: 提供图片插入、编辑、变换等功能。
withText - 文本插件
typescript
const withText: (board: PlaitBoard) => PlaitBoard;功能: 提供文本编辑、格式化等功能。
核心接口
LinkElement - 链接元素
typescript
interface LinkElement extends CustomElement {
url: string; // 链接地址
title?: string; // 链接标题
target?: string; // 打开方式
}CommonImageItem - 通用图片项
typescript
interface CommonImageItem {
url: string; // 图片地址
file?: File; // 文件对象
width?: number; // 图片宽度
height?: number; // 图片高度
name?: string; // 图片名称
}StrokeStyle - 描边样式
typescript
enum StrokeStyle {
solid = "solid", // 实线
dashed = "dashed", // 虚线
dotted = "dotted" // 点线
}常量
typescript
const DEFAULT_COLOR = '#37352f'; // 默认颜色使用示例
typescript
import {
withGroup,
withImage,
PropertyTransforms,
BoardCreationMode,
setCreationMode,
StrokeStyle
} from '@plait/common';
import { PlaitBoard } from '@plait/core';
// 启用通用功能
const enhancedBoard = withGroup(withImage(withText(board)));
// 设置创建模式
setCreationMode(enhancedBoard, BoardCreationMode.dnd);
// 设置元素属性
PropertyTransforms.setProperty(enhancedBoard, element, 'strokeColor', '#ff0000');
PropertyTransforms.setProperty(enhancedBoard, element, 'strokeStyle', StrokeStyle.dashed);
PropertyTransforms.setProperties(enhancedBoard, element, {
fill: '#ffff00',
opacity: 0.8
});
// 获取属性
const strokeColor = PropertyTransforms.getProperty(enhancedBoard, element, 'strokeColor');📐 @plait/layouts - 布局算法库
主要类型
MindLayoutType - 布局类型(已在 mind 库中介绍)
LayoutType - 布局大类
typescript
enum LayoutType {
logic = "logic", // 逻辑布局
indented = "indented", // 缩进布局
fishBone = "fish-bone" // 鱼骨图布局
}LayoutOptions - 布局选项
typescript
interface LayoutOptions {
getHeight: (node: OriginNode) => number; // 获取节点高度
getWidth: (node: OriginNode) => number; // 获取节点宽度
getHorizontalGap: (node: OriginNode, parent?: LayoutNode) => number; // 水平间距
getVerticalGap: (node: OriginNode, parent?: LayoutNode) => number; // 垂直间距
getVerticalConnectingPosition: (node: OriginNode, parent?: LayoutNode) => ConnectingPosition; // 连接位置
getExtendWidth?: (node: OriginNode) => number; // 扩展宽度
getExtendHeight: (node: OriginNode) => number; // 扩展高度
getIndentedCrossLevelGap: () => number; // 缩进跨级间距
}LayoutNode - 布局节点
typescript
interface LayoutNode extends OriginNode {
x: number; // X坐标
y: number; // Y坐标
width: number; // 宽度
height: number; // 高度
children: LayoutNode[]; // 子节点
parent?: LayoutNode; // 父节点
layout: LayoutData; // 布局数据
}核心功能
布局算法
typescript
// 逻辑布局算法
const logicLayout: (root: OriginNode, options: LayoutOptions) => LayoutNode;
// 缩进布局算法
const indentedLayout: (root: OriginNode, options: LayoutOptions) => LayoutNode;
// 鱼骨图布局算法
const fishBoneLayout: (root: OriginNode, options: LayoutOptions) => LayoutNode;使用示例
typescript
import { MindLayoutType, LayoutType } from '@plait/layouts';
// 在思维导图中使用布局
MindTransforms.setLayout(mindBoard, MindLayoutType.standard);
// 检查布局类型
const currentLayout = MindElement.getLayout(rootNode);
if (currentLayout === MindLayoutType.right) {
console.log('当前是右侧布局');
}✍️ @plait/text-plugins - 文本插件库
主要功能
LinkEditor - 链接编辑器
typescript
const LinkEditor = {
// 包装链接
wrapLink(editor: Editor, text: string, url: string): void;
// 取消链接
unwrapLink(editor: Editor, at?: Location): void;
// 检查链接状态
isLinkActive(editor: Editor): boolean;
// 获取链接元素
getLinkElement(editor: Editor): NodeEntry<CustomElement>;
// 插入链接
insertLink(editor: Editor, url: string, text?: string): void;
};TextTransforms - 文本变换操作
typescript
const TextTransforms = {
// 文本格式化
setBold(editor: Editor): void;
setItalic(editor: Editor): void;
setUnderline(editor: Editor): void;
setStrikethrough(editor: Editor): void;
// 字体设置
setFontSize(editor: Editor, size: number): void;
setFontColor(editor: Editor, color: string): void;
// 对齐方式
setAlignment(editor: Editor, alignment: 'left' | 'center' | 'right'): void;
};工具函数
typescript
// URL检测
const isUrl = (text: string): boolean;
// 获取元素文本标记
const getTextMarksByElement = (element: Element): TextMark[];
// 检查是否为链接
const isLinkElement = (element: any): element is LinkElement;使用示例
typescript
import { LinkEditor, TextTransforms, isUrl } from '@plait/text-plugins';
import { Editor } from 'slate';
// 检查文本是否为URL
const text = 'https://example.com';
if (isUrl(text)) {
// 插入链接
LinkEditor.insertLink(editor, text, text);
}
// 设置文本格式
TextTransforms.setBold(editor);
TextTransforms.setFontSize(editor, 16);
TextTransforms.setFontColor(editor, '#ff0000');
// 检查链接状态
if (LinkEditor.isLinkActive(editor)) {
const linkElement = LinkEditor.getLinkElement(editor);
console.log('当前链接:', linkElement[0].url);
}⚛️ @plait-board/react-board - React组件库
主要组件
Board - 画板组件
typescript
interface PlaitBoardProps {
style?: React.CSSProperties; // 样式
className?: string; // CSS类名
children?: React.ReactNode; // 子组件
afterInit?: (board: PlaitBoard) => void; // 初始化回调
}
const Board: React.FC<PlaitBoardProps>;Wrapper - 包装器组件
typescript
interface WrapperProps {
value: PlaitElement[]; // 元素数据
viewport?: Viewport; // 视口配置
theme?: PlaitTheme; // 主题配置
options: PlaitBoardOptions; // 画板选项
plugins: PlaitPlugin[]; // 插件列表
onChange?: (data: BoardChangeData) => void; // 变更回调
onSelectionChange?: (selection: Selection | null) => void; // 选择变更回调
onViewportChange?: (value: Viewport) => void; // 视口变更回调
onThemeChange?: (value: ThemeColorMode) => void; // 主题变更回调
onValueChange?: (value: PlaitElement[]) => void; // 值变更回调
children?: React.ReactNode; // 子组件
}
const Wrapper: React.FC<WrapperProps>;BoardChangeData - 画板变更数据
typescript
interface BoardChangeData {
value: PlaitElement[]; // 新的元素数据
viewport?: Viewport; // 新的视口
theme?: PlaitTheme; // 新的主题
}React Hooks
useBoard - 获取画板实例
typescript
const useBoard: () => PlaitBoard;usePluginEvent - 插件事件处理
typescript
const usePluginEvent: (
board: PlaitBoard,
viewportContainerRef: RefObject<HTMLElement>,
hostRef: RefObject<SVGSVGElement>
) => void;插件
withReact - React集成插件
typescript
const withReact: (board: PlaitBoard) => PlaitBoard;功能: 提供React组件渲染支持。
withPinchZoom - 缩放插件
typescript
const withPinchZoom: (board: PlaitBoard) => PlaitBoard;功能: 提供触控缩放支持。
使用示例
typescript
import React from 'react';
import { Board, Wrapper, useBoard, withReact } from '@plait-board/react-board';
import { PlaitElement, PlaitTheme } from '@plait/core';
import { withDraw } from '@plait/draw';
const MyBoardComponent: React.FC = () => {
const [value, setValue] = useState<PlaitElement[]>([]);
const [viewport, setViewport] = useState<Viewport>();
const [theme, setTheme] = useState<PlaitTheme>();
// 插件配置
const plugins = [
withReact,
withDraw(),
// ... 其他插件
];
// 画板选项
const options: PlaitBoardOptions = {
readonly: false,
hideScrollbar: false,
};
const handleChange = (data: BoardChangeData) => {
setValue(data.value);
if (data.viewport) setViewport(data.viewport);
if (data.theme) setTheme(data.theme);
};
return (
<Wrapper
value={value}
viewport={viewport}
theme={theme}
options={options}
plugins={plugins}
onChange={handleChange}
>
<Board afterInit={(board) => {
console.log('画板初始化完成:', board);
}} />
</Wrapper>
);
};
// 使用Hook获取画板实例
const BoardTools: React.FC = () => {
const board = useBoard();
const handleUndo = () => {
board.undo();
};
const handleRedo = () => {
board.redo();
};
return (
<div>
<button onClick={handleUndo}>撤销</button>
<button onClick={handleRedo}>重做</button>
</div>
);
};🚀 完整集成示例
Drawnix风格的完整实现
typescript
import React, { useState } from 'react';
import {
PlaitBoard,
PlaitElement,
PlaitPointerType,
Viewport,
PlaitTheme
} from '@plait/core';
import { withDraw } from '@plait/draw';
import { withMind } from '@plait/mind';
import { withGroup } from '@plait/common';
import { Board, Wrapper, useBoard } from '@plait-board/react-board';
const DrawnixBoard: React.FC = () => {
const [value, setValue] = useState<PlaitElement[]>([]);
const [viewport, setViewport] = useState<Viewport>();
const [theme, setTheme] = useState<PlaitTheme>();
// 插件系统配置
const plugins = [
withDraw({
customGeometryTypes: ['customHeart', 'customStar']
}),
withGroup,
withMind,
// 自定义插件
withCustomShapes(),
withHotkeyPlugin(),
];
// 画板配置
const options: PlaitBoardOptions = {
readonly: false,
hideScrollbar: false,
disabledScrollOnNonFocus: false,
themeColors: MindThemeColors,
};
// 处理画板变更
const handleChange = (data: BoardChangeData) => {
setValue(data.value);
setViewport(data.viewport);
setTheme(data.theme);
// 自动保存到本地存储
localStorage.setItem('drawnix-data', JSON.stringify(data.value));
};
// 处理选择变更
const handleSelectionChange = (selection: Selection | null) => {
console.log('选择变更:', selection);
};
return (
<div className="drawnix-container">
<Wrapper
value={value}
viewport={viewport}
theme={theme}
options={options}
plugins={plugins}
onChange={handleChange}
onSelectionChange={handleSelectionChange}
>
<Board
afterInit={(board) => {
console.log('Drawnix画板初始化完成');
// 可以在这里进行初始化配置
}}
/>
</Wrapper>
{/* 工具栏组件 */}
<Toolbar board={useBoard()} />
</div>
);
};
// 自定义插件示例
const withCustomShapes = () => {
return (board: PlaitBoard) => {
// 注册自定义形状渲染器
board.registerCustomShapeRenderer('customHeart', CustomHeartRenderer);
board.registerCustomShapeRenderer('customStar', CustomStarRenderer);
return board;
};
};
// 自定义热键插件
const withHotkeyPlugin = () => {
return (board: PlaitBoard) => {
board.addKeydownHandler((event) => {
if (event.ctrlKey && event.key === 'z') {
event.preventDefault();
board.undo();
}
if (event.ctrlKey && event.key === 'y') {
event.preventDefault();
board.redo();
}
});
return board;
};
};📚 API参考总结
核心概念
- 插件系统: @plait采用插件化架构,所有功能都通过插件实现
- 变换操作: 使用Transforms进行状态变更,确保数据一致性
- 类型安全: 完整的TypeScript类型定义,提供良好的开发体验
- React集成: 通过@plait-board/react-board提供React组件支持
最佳实践
- 插件组合: 合理组合插件,避免功能冲突
- 性能优化: 使用React.memo和useCallback优化渲染性能
- 错误处理: 妥善处理插件加载和运行时错误
- 类型检查: 充分利用TypeScript类型系统确保代码质量
扩展开发
- 自定义插件: 实现PlaitPlugin接口添加新功能
- 自定义形状: 使用PlaitCustomGeometry接口添加新图形
- 自定义渲染: 通过board.registerCustomShapeRenderer注册渲染器
- 事件处理: 使用board.addEventListener添加自定义事件监听
文档版本: v1.0最后更新: 2025年11月17日基于 @plait v0.86.1
