react可视化标尺@scena/react-ruler使用

@scena/react-ruler 是一款轻量、可定制的 React 标尺组件,支持水平 / 垂直方向、缩放、滚动偏移适配,非常适合可视化编辑器、画布标注等场景。

安装

官网地址: https://daybrush.com/ruler/

javascript 复制代码
npm install @scena/react-ruler --save

核心api

属性 类型 说明 默认值
type horizontal/vertical 标尺方向(水平 / 垂直) horizontal
width number 标尺宽度(水平标尺生效) 100%
height number 标尺高度(垂直标尺生效) 100%
zoom number 标尺缩放比例(与画布缩放联动) 1
scrollPos number 标尺滚动偏移(与画布滚动联动) 0
unit number 标尺刻度单位 (如 50 = 每 50px 一个大刻度) 50
segment number 大刻度下的小分段数(如 2=50px 分 2 段) 2
lineColor string 刻度线颜色 #ddd
textColor string 刻度文字颜色 #888
backgroundColor string 标尺背景色 #fff
negativeRuler boolean 是否显示负数刻度(支持画布左 / 上偏移) false
textOffset [number, number] 刻度文字的偏移量,格式为 [x, y],单位:px;方向适配水平 / 垂直标尺 [0, 0]

实现案例

javascript 复制代码
import { useEffect, useRef, useMemo, useCallback } from "react";
import { useEditScreen } from '@/store/useEditScreen'
import Ruler from "@scena/react-ruler";
import './index.scss'
const RulerComponent = (props) => {
  const { children } = props
  const verticalRulerRef = useRef<null | Ruler>(null)
  const horizontalRulerRef = useRef<null | Ruler>(null

  return (
    <div className="ruler-container">
      <div className="left">
        <div className="px-box">px</div>
        {/* 垂直ruler */}
        <Ruler
          ref={verticalRulerRef}
          type="vertical"
          lineColor={"#aaa"}
          textColor={"#000"}
          backgroundColor={"#fff"}
          negativeRuler={true}
          segment={2}
          textOffset={[10, 0]}
        />
      </div>
      <div className="right">
        <div style={{ height: "20px" }}>
          {/* 水平ruler */}
          <Ruler
            type="horizontal"
            ref={horizontalRulerRef}
            lineColor={"#aaa"}
            textColor={"#000"}
            backgroundColor={"#fff"}
            negativeRuler={true}
            segment={2}
            textOffset={[0, 10]}
          />
        </div>
        { children }
      </div>
    </div>
  );
}

export default RulerComponent

样式

javascript 复制代码
.ruler-container {
  width: 100%;
  height: calc(100% - 40px);
  display: flex;
  overflow: hidden;
  .left {
    width: 20px;
    height: 100%;
  }
  .px-box {
    font-size: 12px;
    text-align: center;
    height: 20px;
    background: #fff;
  }
  .right {
    flex: 1;
  }
}

核心联动逻辑

1. 缩放联动

  • 标尺的zoom必须与画布的transForm: scale(scale)同步
  • 刻度单位 unit 需根据缩放比例动态调整(缩放越大,单位越小,保证刻度不重叠)
  • 画布缩放原点必须设为 transform-origin: left top,与标尺原点对齐

2. 画布缩放原点必须设为 transform-origin: left top,与标尺原点对齐

  • 容器滚动时,scrollPosX = scrollLeft / scale、scrollPosY = scrollTop / scale(滚动偏移需转换为逻辑像素);
  • 开启 negativeRuler={true} 支持负数刻度,适配画布左 / 上偏移场景
  • 标尺 scrollPos 是「逻辑像素偏移」,需除以缩放比例才能与画布滚动偏移匹配

3. 坐标对齐

  • 画布内元素的绝对定位(left/top)是「逻辑像素」,与标尺刻度一一对应
  • 若需将标尺刻度转换为屏幕物理像素,需乘以缩放比例(逻辑像素 × scale = 物理像素)

其它配置

自定义刻度文字格式

通过 formatText 属性自定义刻度显示(如添加单位、格式化数字):

javascript 复制代码
<Ruler
  type="horizontal"
  zoom={scale}
  scrollPos={scrollPosX}
  formatText={(value) => `${value}px`} // 刻度显示为 "50px" "100px"
/>

隐藏小刻度 / 文字

通过 showMinorLine/showText 控制显示

javascript 复制代码
<Ruler
  type="vertical"
  showMinorLine={scale > 0.5} // 缩放小于0.5时隐藏小刻度
  showText={scale > 0.3} // 缩放小于0.3时隐藏文字
/>

标尺偏移校准

若标尺刻度与画布坐标错位,可通过 offset 属性微调:

javascript 复制代码
<Ruler
  type="horizontal"
  offset={2} // 水平偏移2px
/>

五、常见问题与解决方案

1. 标尺刻度与画布坐标错位

  • 检查画布 transform-origin 是否为 left top;
  • 确保 scrollPos 计算时除以了缩放比例(scrollLeft / scale);
  • 校准标尺 offset 属性,微调像素偏差。

2. 缩放后刻度重叠

  • 动态调整 unit 属性(缩放越大,unit 越小);
  • 缩放过小时隐藏小刻度 / 文字(showMinorLine/showText)。

3. 滚轮缩放卡顿

  • 给 handleWheel 添加 e.preventDefault() 阻止默认滚动;
  • 限制缩放范围(如 0.2~2),避免极端缩放;
  • 使用 requestAnimationFrame 优化缩放计算(高频操作)。

4. 负数刻度不显示

  • 确保开启 negativeRuler={true};
  • 检查 scrollPos 是否为负数(画布左 / 上滚动时才会显示负数刻度)。

在计算屏幕缩放的比例的时候 使用了antDesign Layout布局 导致获取元素clientHiehgt一直有问题 后面把Layout布局改成了div

相关推荐
●VON1 小时前
Flutter for OpenHarmony前置知识《Flutter 状态管理入门实战:使用 Provider 构建计数器应用》
前端·学习·flutter·华为·openharmony
艾小码1 小时前
Vue开发三年,我才发现依赖注入的TypeScript正确打开方式
前端·javascript·vue.js
土豆12508 小时前
React-Draggable 快速上手指南
react.js
veneno9 小时前
大量异步并发请求控制并发解决方案
前端
i***t9199 小时前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
oden10 小时前
2025博客框架选择指南:Hugo、Astro、Hexo该选哪个?
前端·html
小光学长10 小时前
基于ssm的宠物交易系统的设计与实现850mb48h(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·前端·数据库
小小前端要继续努力10 小时前
渐进增强、优雅降级及现代Web开发技术详解
前端