Skip to content

About

Renderer-agnostic rubberband selection and multi-drag engine: rAF coalescing, drag snapshot, preview/commit split. From X6 issue 4823.

Resources

Stars

101 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Selection Drag Engine

渲染器无关的框选 / 多选拖拽引擎。来自 X6 issue 4823 的大画布拖拽性能经验,核心不绑定 X6、DOM 或任何具体渲染器。

三条性能保证(也是全部设计动机):

  1. rAF 合帧:高频 pointermove 只累计位移,每帧最多 flush 一次。
  2. 拖拽快照:pointerdown 一次性冻结"要动谁",拖动中零重复计算。
  3. preview / commit 分离:拖动中只动预览层,真实模型只在 pointerup 提交一次。

运行

npm test        # 4 项核心行为测试
npm run dev     # 启动 demo

Demo:http://127.0.0.1:5173/demos/svg-selection-demo.html(1000 个 SVG 对象,面板实时显示 pointermove / rAF flush / commit 次数与帧耗时)。

接入:实现一个 adapter

引擎本身零依赖;宿主只需注入一个 adapter 对象(可参考 src/svg-selection-adapter.js,136 行):

import { SelectionDragEngine } from 'selection-drag-engine'

const engine = new SelectionDragEngine({ adapter: myAdapter })

adapter 契约

方法 调用时机 职责
hitTest(rect, { mode }) 仅 pointerup 返回框选命中的 id 列表;mode: 'intersects' | 'contains'
setSelection(ids) 选择集变化时 应用新选择集
getSelection() 可选 返回当前选择集;不实现则用引擎内部状态
createDragSnapshot(ids) pointerdown 冻结选中对象的可变副本(引擎不解释其结构,只透传)
beginDragPreview(snapshot) pointerdown 后 建立预览层(clone / 遮罩 / 半透明,宿主自定)
previewDrag(snapshot, delta) 每帧最多 1 次 只更新预览层 transform;必须廉价,禁止写真实模型
commitDrag(snapshot, delta) 仅 pointerup 把 delta 应用到真实数据与渲染;全拖拽唯一一次
endDragPreview(snapshot) pointerup / cancel 销毁预览层、恢复源对象状态
renderRubberband(rect | null) 框选期间每帧最多 1 次 画/隐藏橡皮筋矩形;null 表示隐藏

实现守则:

  • previewDrag 里只改 transform(或等价的廉价属性),不遍历业务数据、不发事件。
  • 所有真实写入收敛到 commitDrag;hitTest 只在抬起时跑——O(n) 只付一次。
  • 忽略引擎在非 pointerup 时刻的任意中间态。

边界(非目标)

  • 已实现:框选、多选、拖拽预览、拖拽提交、指标回调。
  • 未实现(按需自加):resize / rotate、edge routing、undo/redo、spatial index(当前 hitTest 为 O(n),百~千级对象够用)、DOM/Canvas adapter。
  • 框选命中允许 O(n),但只发生在框选结束时;snapshot / commit 允许 O(k),k 为选中数量。

目录

  • src/selection-drag-engine.js — 状态机 + rAF 合帧核心(引擎唯一必读文件)
  • src/svg-selection-adapter.js — SVG adapter 参考实现
  • src/geometry.js / src/raf-scheduler.js — 矩形工具、rAF 适配
  • tests/selection-drag-engine.test.js — 合帧、命中时机、几何行为
  • docs/design.md — 设计动机与性能约束
  • demos/svg-selection-demo.html — 1000 对象实例

背景

X6 issue 4823:大数据量框选拖拽时,旧实现把"查图 + 移动 + 更新高亮框"全挂在高频 mousemove 上,成本 = 事件数 × 选中数。本库把同一套修复(合帧 / 缓存 / 冻结)固化为独立内核。背景分析见 issue 讨论。

License

MIT

About

Renderer-agnostic rubberband selection and multi-drag engine: rAF coalescing, drag snapshot, preview/commit split. From X6 issue 4823.

Resources

Stars

101 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages