跳到主要内容

标尺与参考线

Ydesign 内置了 标尺(Ruler)+ 参考线(Guidelines) 的能力,覆盖了画布对位 / 元素对齐 / 视觉草图常见的辅助场景。整个能力由:

  • @ydesign/core 里的 RulerHandler(注册在 editor.rulerHandler
  • @ydesign/react-editor 里的 <RulerButton />(画布右下角的开关按钮)

两部分组成,可以分别独立使用。


快速接入

<RulerButton /> 放在 <WorkspaceWrap> 里,和 <ZoomButtons /> 并列即可:

import { DesignEditorContainer, SidePanelWrap, WorkspaceWrap } from '@ydesign/react-editor';
import Workspace from '@ydesign/react-editor/canvas/workspace';
import { ZoomButtons } from '@ydesign/react-editor/toolbar/zoom-buttons';
import { RulerButton } from '@ydesign/react-editor/toolbar/ruler-button';

<DesignEditorContainer>
<SidePanelWrap>{/* ... */}</SidePanelWrap>
<WorkspaceWrap>
<Workspace store={store} />
<ZoomButtons store={store} />
<RulerButton store={store} />
</WorkspaceWrap>
</DesignEditorContainer>;

<RulerButton /> 自带:

  • 开关:点按钮 → 下拉菜单 → "显示标尺和参考线"切换;状态记忆在 localStorage,刷新后保持
  • 清除参考线:菜单第二项;只有当画布上至少存在一条参考线时可点
  • 多语言:会读取 translate('toolbar.ruler') / toolbar.rulerShow / toolbar.rulerClear

用户交互

启用标尺后:

操作效果
鼠标悬停在标尺区域光标变 ns-resize / ew-resize
在标尺区域按下鼠标拖入画布拖出一条参考线
选中参考线(点击它)参考线变 蓝色,同时标尺顶部 / 左侧蓝色高亮显示当前坐标
拖动参考线跟随鼠标移动;同步更新标尺数字
拖动参考线进入标尺区域鼠标光标变为 🚫 禁止图标,提示"松手即删除"
拖动参考线回到标尺区域松开自动删除该参考线(鼠标光标自动恢复)
缩放画布标尺刻度密度自适应(缩放越大刻度越密)
选中任意对象标尺顶部 / 左侧出现 蓝色高亮区段,两端显示对象的 left / right、top / bottom

📍 标尺坐标系的原点 (0, 0) 对应 workarea 的左上角,与"位置"工具栏里的 X / Y 显示完全一致。


核心能力 API(editor.rulerHandler

开关 / 状态

editor.rulerHandler.enable();           // 显示标尺
editor.rulerHandler.disable(); // 隐藏标尺(参考线一并隐藏)
editor.rulerHandler.toggle(); // 切换
editor.rulerHandler.isEnabled; // boolean,当前是否启用

参考线管理

editor.rulerHandler.clearGuidelines();  // 移除所有参考线
editor.rulerHandler.showGuidelines(); // 显示所有参考线(不影响 isEnabled)
editor.rulerHandler.hideGuidelines(); // 隐藏所有参考线
editor.rulerHandler.hasGuidelines(); // boolean,画布上是否存在参考线

命中检测(高级)

editor.rulerHandler.isPointOnRuler(point); // 'horizontal' | 'vertical' | false

判断给定的 viewport 坐标(屏幕像素,相对 canvas 左上角)是否落在标尺区域。常用于自定义事件。


自定义外观

RulerHandler 支持在初始化时传入配置项:

import RulerHandler, { type RulerHandlerOptions } from '@ydesign/core/dist/handlers/RulerHandler';

const options: RulerHandlerOptions = {
ruleSize: 20, // 标尺宽高,默认 20
fontSize: 10, // 刻度字号,默认 10
backgroundColor: '#fff', // 标尺背景色
borderColor: '#ddd', // 标尺边框色
textColor: '#888', // 刻度数字颜色
highlightColor: '#007fff', // 选中对象 / 选中参考线时的高亮色
guidelineColor: '#4bec13', // 参考线默认颜色
};

如果需要替换默认配置,可以在自己的应用里创建 Editor 时手动注入。当前 <RulerButton /> 用默认配置即可,绝大多数场景无需调整。


与持久化 / 历史的关系

参考线对持久化系统是透明的

  • 不进 store.objects(不会触发自动保存)
  • 不进 historyHandler(撤销 / 重做时不会"撤销出"参考线,也不会消失)
  • 不进 excludeFromExport: true(导出 PNG / JSON 时被跳过)

也就是说,参考线只是当前编辑会话内的视觉辅助,关闭浏览器就消失。需要"保存参考线布局"的场景,建议你自己读取 editor.rulerHandler 里的对象状态做单独存储。


实现细节(可跳过)

  • 标尺本身不是 fabric 对象,而是订阅 after:render 之后在画布主 context 上手动绘制 —— 因此不会出现在 canvas.toJSON()
  • 参考线是普通的 fabric.Line(带 isGuideline: true 标记),但 stroke 设为透明,由我们在 after:render 阶段自定义渲染(这样不受 canvas.clipPath 裁剪,可以延伸到 workarea 之外)
  • 命中检测覆写了 containsPoint 方法,用"鼠标到参考线的垂直距离 ≤ 6 屏幕像素"判定 —— 比 fabric 默认的长跨度命中更可靠
  • 每次 object:added 后自动把参考线置顶,保证图片 / 文字下方的参考线仍然可被选中

FAQ

Q:为什么参考线穿过图片时也能选中? 启用标尺时会订阅 object:added,新对象一旦加入就把所有参考线置顶。所以即使图片在视觉上"覆盖"了参考线,hit-test 也会先命中参考线。

Q:参考线会被保存到模板 JSON 里吗? 不会。excludeFromExport: true 已经设置,store.objects 中也会过滤掉,因此你可以放心使用而不必担心污染数据。

Q:可以隐藏标尺但保留参考线吗? 可以。直接调 disable() 关闭标尺,参考线对象会自动设为 visible: false,再次 enable() 时恢复显示。如果需要长期"无标尺有参考线"的状态,建议自己先 enable() 再用 CSS / 业务代码盖住标尺区域。