Bounding Plugin for Knotx
npm install @knotx/plugins-bounding边界框插件,为节点提供缩放和连接点功能。
``bash`
npm install @knotx/plugins-bounding
@knotx/plugins-bounding 是 KnotX 框架的边界框插件,为节点提供缩放(resize)和连接点(connect handle)功能。支持多种缩放手柄位置、自定义样式、最小尺寸限制和惯性效果。
该插件通过 InteractJS 实现交互功能:
1. 缩放手柄:在节点周围提供可拖拽的缩放手柄
2. 连接点:在节点边缘提供连接点,用于节点间连接
3. 边界框:为选中节点显示边界框
4. 交互处理:处理缩放和连接的拖拽交互
该插件依赖以下包:
- @knotx/core - 核心功能@knotx/decorators
- - 装饰器支持@knotx/plugins-canvas
- - 画布插件(peer dependency)@knotx/jsx
- - JSX 支持(peer dependency)@knotx/render
- - 渲染工具interactjs
- - 交互库rxjs
- - 响应式编程
`typescript
import { Bounding } from '@knotx/plugins-bounding'
// 创建边界框插件实例
const bounding = new Bounding()
// 在引擎中注册插件
engine.use(bounding)
`
`typescript`
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']
}
})
`tsx
const { getCustomResizeHandleAttributes } = useKnotX().bounding
// 为自定义节点添加缩放手柄
function ResizableNode({ node }) {
return (
{/ 右下角缩放手柄 /}
$3
`typescript
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: '可缩放节点' }
}
})
`配置接口
$3
`typescript
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[]
}
}
`$3
`typescript
type ResizeHandlePosition =
| 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
| 'left' | 'right' | 'top' | 'bottom'
| 'center'
`$3
`typescript
declare module '@knotx/core' {
interface PluginData {
bounding: {
getCustomResizeHandleAttributes: (nodeId: string, position: ResizeHandlePosition) => Record
}
}
}
`默认配置
`typescript
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: []
}
}
`交互功能
$3
- 多位置手柄:支持 8 个方向的缩放手柄
- 最小尺寸:可配置节点的最小宽度和高度
- 惯性效果:支持启用/禁用惯性效果
- 节点类型过滤:可指定哪些节点类型可以缩放
$3
- 边缘连接点:在节点四个边缘提供连接点
- 自定义样式:支持自定义连接点的样式和阴影效果
- 动态显示:根据交互状态动态显示/隐藏连接点
$3
- 选择指示:为选中节点显示边界框
- 尺寸阈值:当节点尺寸超过阈值时才显示边界框
- 自定义样式:支持自定义边界框的样式
事件处理
$3
`typescript
interface ResizeEvent {
nodeId: string
startWidth: number
startHeight: number
startX: number
startY: number
position: string
}
`$3
`typescript
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