@knotx/plugins-bounding
v0.5.7
Published
Bounding Plugin for Knotx
Readme
@knotx/plugins-bounding
边界框插件,为节点提供缩放和连接点功能。
安装
npm install @knotx/plugins-bounding基本概述
@knotx/plugins-bounding 是 KnotX 框架的边界框插件,为节点提供缩放(resize)和连接点(connect handle)功能。支持多种缩放手柄位置、自定义样式、最小尺寸限制和惯性效果。
实现原理
该插件通过 InteractJS 实现交互功能:
- 缩放手柄:在节点周围提供可拖拽的缩放手柄
- 连接点:在节点边缘提供连接点,用于节点间连接
- 边界框:为选中节点显示边界框
- 交互处理:处理缩放和连接的拖拽交互
依赖插件
该插件依赖以下包:
@knotx/core- 核心功能@knotx/decorators- 装饰器支持@knotx/plugins-canvas- 画布插件(peer dependency)@knotx/jsx- JSX 支持(peer dependency)@knotx/render- 渲染工具interactjs- 交互库rxjs- 响应式编程
API 使用
基本使用
import { Bounding } from '@knotx/plugins-bounding'
// 创建边界框插件实例
const bounding = new Bounding()
// 在引擎中注册插件
engine.use(bounding)配置选项
const bounding = new Bounding().init({
features: {
resize: true,
connect: true,
boundingBox: true
},
sizes: {
resizeHandle: 6,
connectHandle: 8,
boundingBoxThreshold: 200
},
styles: {
resizeHandle: {
fill: '#3b82f6',
stroke: '#ffffff',
strokeWidth: 1
},
connectHandle: {
fill: '#10b981',
stroke: '#ffffff',
strokeWidth: 1,
shadowColor: '#000000',
shadowWidth: 1
},
boundingBox: {
stroke: '#3b82f6',
strokeWidth: 1
}
},
resize: {
minWidth: 50,
minHeight: 30,
inertia: false,
handles: ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'left', 'right', 'top', 'bottom'],
nodesType: ['default', 'custom']
}
})自定义缩放手柄属性
const { getCustomResizeHandleAttributes } = useKnotX().bounding
// 为自定义节点添加缩放手柄
function ResizableNode({ node }) {
return (
<div style={{ position: 'relative' }}>
<div>{node.data.label}</div>
{/* 右下角缩放手柄 */}
<div
{...getCustomResizeHandleAttributes(node.id, 'bottom-right')}
style={{
position: 'absolute',
right: -3,
bottom: -3,
width: 6,
height: 6,
backgroundColor: '#3b82f6',
border: '1px solid #ffffff',
borderRadius: '50%',
cursor: 'nw-resize'
}}
/>
</div>
)
}完整示例
import { Engine } from '@knotx/core'
import { Bounding } from '@knotx/plugins-bounding'
import { Canvas } from '@knotx/plugins-canvas'
const engine = new Engine()
// 注册依赖插件
engine.use(new Canvas())
// 注册边界框插件
engine.use(new Bounding().init({
features: {
resize: true,
connect: true,
boundingBox: true
},
sizes: {
resizeHandle: 8,
connectHandle: 10,
boundingBoxThreshold: 150
},
styles: {
resizeHandle: {
fill: '#ec4899',
stroke: '#ffffff',
strokeWidth: 2
},
connectHandle: {
fill: '#06b6d4',
stroke: '#ffffff',
strokeWidth: 2,
shadowColor: 'rgba(0, 0, 0, 0.2)',
shadowWidth: 2
},
boundingBox: {
stroke: '#ec4899',
strokeWidth: 2
}
},
resize: {
minWidth: 80,
minHeight: 50,
inertia: true,
handles: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
nodesType: ['default']
}
}))
// 创建可缩放节点
engine.dispatchNodeOperation({
type: 'add',
node: {
id: 'resizable-node',
type: 'default',
position: { x: 100, y: 100 },
measured: { width: 120, height: 80 },
data: { label: '可缩放节点' }
}
})配置接口
BoundingConfig
interface BoundingConfig {
// 功能开关
features?: {
resize?: boolean
connect?: boolean
boundingBox?: boolean
}
// 尺寸配置
sizes?: {
resizeHandle?: number
connectHandle?: number
boundingBoxThreshold?: number
}
// 样式配置
styles?: {
resizeHandle?: {
fill?: string
stroke?: string
strokeWidth?: number
}
connectHandle?: {
fill?: string
stroke?: string
strokeWidth?: number
shadowColor?: string
shadowWidth?: number
}
boundingBox?: {
stroke?: string
strokeWidth?: number
}
}
// resize 配置
resize?: {
minWidth?: number
minHeight?: number
inertia?: boolean
handles?: ResizeHandlePosition[]
nodesType?: string[]
}
}ResizeHandlePosition
type ResizeHandlePosition =
| 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
| 'left' | 'right' | 'top' | 'bottom'
| 'center'插件数据接口
declare module '@knotx/core' {
interface PluginData {
bounding: {
getCustomResizeHandleAttributes: (nodeId: string, position: ResizeHandlePosition) => Record<string, string>
}
}
}默认配置
const DEFAULT_RESIZE_HANDLES: ResizeHandlePosition[] = [
'top-left',
'top-right',
'bottom-left',
'bottom-right'
]
const DEFAULT_CONNECT_HANDLE_POSITIONS = [
{ top: true },
{ right: true },
{ bottom: true },
{ left: true }
]
const DEFAULT_CONFIG = {
features: {
resize: true,
connect: true,
boundingBox: true
},
sizes: {
resizeHandle: 6,
connectHandle: 8,
boundingBoxThreshold: 200
},
styles: {
resizeHandle: {
fill: '#3b82f6',
stroke: '#ffffff',
strokeWidth: 1
},
connectHandle: {
fill: '#10b981',
stroke: '#ffffff',
strokeWidth: 1,
shadowColor: '#000000',
shadowWidth: 1
},
boundingBox: {
stroke: '#3b82f6',
strokeWidth: 1
}
},
resize: {
minWidth: 50,
minHeight: 30,
inertia: false,
handles: DEFAULT_RESIZE_HANDLES,
nodesType: []
}
}交互功能
缩放功能
- 多位置手柄:支持 8 个方向的缩放手柄
- 最小尺寸:可配置节点的最小宽度和高度
- 惯性效果:支持启用/禁用惯性效果
- 节点类型过滤:可指定哪些节点类型可以缩放
连接点功能
- 边缘连接点:在节点四个边缘提供连接点
- 自定义样式:支持自定义连接点的样式和阴影效果
- 动态显示:根据交互状态动态显示/隐藏连接点
边界框功能
- 选择指示:为选中节点显示边界框
- 尺寸阈值:当节点尺寸超过阈值时才显示边界框
- 自定义样式:支持自定义边界框的样式
事件处理
缩放事件
interface ResizeEvent {
nodeId: string
startWidth: number
startHeight: number
startX: number
startY: number
position: string
}缩放数据
interface ResizeData {
nodeId: string
width: number
height: number
}文件目录结构
packages/plugins-bounding/
├── src/
│ ├── bounding.tsx # 边界框插件主文件
│ └── index.ts # 导出文件
├── dist/ # 编译输出目录
├── CHANGELOG.md # 变更日志
├── package.json # 包配置
├── build.config.ts # 构建配置
├── eslint.config.mjs # ESLint 配置
└── tsconfig.json # TypeScript 配置许可证
MIT
