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

相关推荐
数据掘金6 分钟前
百度统计后台页面数据异常?从手动调用时机开始排查
前端
hunteritself8 分钟前
10 层 4K 实时剪辑,国产工作站进入广电制作核心
大数据·前端·人工智能·深度学习·transformer
踩着两条虫8 分钟前
我在浏览器里“盖”了一个村:Vue + Three.js 大屏开发踩坑记
前端·vue.js·three.js
mbshqqb13 分钟前
TypeScript基础教程之同步生成器
前端·javascript·typescript
嘟嘟同学和妮妮同学32 分钟前
【升级】一个中国历史可视化站:皇帝时间线梳理、古代思想流派、诗词鉴赏 (2)
前端·html
暗夜行者之光1 小时前
LangGraph + MCP 实战:构建"自然语言查数据"的 ChatBI Agent
前端·后端
一tiao咸鱼1 小时前
还在手动海投?我做了个 AI 求职助手,自动筛选 BOSS 职位再精准投递
前端·后端·面试
尤水就下1 小时前
🔥预热:在线文档的 block 架构是如何实现的(未完待续...)
前端·javascript·架构
song5011 小时前
React Native for OpenHarmony 实战:三方库 react-native-parallax-scroll-view 的鸿蒙化适配指南
分布式·react native·react.js·transformer·harmonyos
总要学点什么1 小时前
第51篇:数据分析-热力图——笔刷画的是圆,落到地上却成了椭圆
3d·数据挖掘·数据分析·前端框架·gis·webgl·cesium