npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-sketch-ruler

v3.1.4

Published

> 是一个基于 React + TypeScript 的标尺组件库,由 [vue3-sketch-ruler](https://github.com/kakajun/vue3-sketch-ruler) 翻译而来,共用 `@sketch-ruler/core` 与 `@sketch-ruler/canvas` 底层插件。适用于低代码平台、大屏可视化、做图工具等场景,提供类似 Photoshop 的缩放与标尺辅助线体验。

Readme

react-sketch-ruler

是一个基于 React + TypeScript 的标尺组件库,由 vue3-sketch-ruler 翻译而来,共用 @sketch-ruler/core@sketch-ruler/canvas 底层插件。适用于低代码平台、大屏可视化、做图工具等场景,提供类似 Photoshop 的缩放与标尺辅助线体验。

build status

🚀 Features

  • ⚛️ React 18+ / 19+ 友好,完全基于 TypeScript
  • 🎯 内置 TransformEngine 变换引擎,零外部 panzoom 依赖
  • 🖱️ 多种缩放模式:鼠标中心、视口中心、内容中心
  • 📐 可配置参考线(拖拽创建、吸附、锁定)
  • 🗺️ 内置 Minimap 缩略图导航(支持拖拽视口、点击跳转)
  • 🔌 插件系统(生命周期钩子 + 自定义渲染器)
  • 🎨 动画支持:ease-out / damped / exponential / direct
  • 📦 平台与业务代码分离,通过 childrenslot="toolbar" 插槽专注业务即可

🦄 Demo

案例浏览: https://kakajun.github.io/react-sketch-ruler

CodePen 示例

安装

npm install --save react-sketch-ruler

# 或
yarn add react-sketch-ruler

# 或
pnpm add react-sketch-ruler

引入方式

ESM

import { SketchRule, Minimap } from 'react-sketch-ruler'
import type { SketchRulerProps, SketchRulerMethods } from 'react-sketch-ruler'
import 'react-sketch-ruler/index.css'

CDN

<script src="https://unpkg.com/react-sketch-ruler/lib/index.umd.js"></script>
<link rel="stylesheet" href="https://unpkg.com/react-sketch-ruler/lib/index.css" />

<script>
  const { SketchRule, Minimap } = window.ReactSketchRuler
</script>

使用

基础用法

import React, { useRef } from 'react'
import { SketchRule } from 'react-sketch-ruler'
import 'react-sketch-ruler/index.css'

const BasicDemo: React.FC = () => {
  const sketchRef = useRef<SketchRulerMethods>(null)

  const width = 1470
  const height = 700
  const canvasWidth = 1000
  const canvasHeight = 500

  const [scale, setScale] = React.useState(1)
  const [lines, setLines] = React.useState({ h: [0, 250], v: [0, 500] })

  return (
    <div style={{ width, height }}>
      <SketchRule
        ref={sketchRef}
        scale={scale}
        width={width}
        height={height}
        canvasWidth={canvasWidth}
        canvasHeight={canvasHeight}
        thick={20}
        lines={lines}
        isShowReferLine={true}
        enableAnimation={true}
        animationMode="ease-out"
        onZoomChange={(detail) => {
          console.log('zoomchange', detail)
          setScale(detail.scale)
        }}
        onUpdateLines={setLines}
      >
        <div data-type="page" style={{ width: canvasWidth, height: canvasHeight }}>
          {/* 业务画布内容 */}
          <img src="bg.png" style={{ width: '100%', height: '100%' }} alt="" />
        </div>

        <div slot="toolbar" className="btns">
          <button onClick={() => sketchRef.current?.reset()}>还原</button>
          <button onClick={() => sketchRef.current?.zoomIn()}>放大</button>
          <button onClick={() => sketchRef.current?.zoomOut()}>缩小</button>
          <button onClick={() => sketchRef.current?.zoomToPreset(1)}>100%</button>
          <span>{(scale * 100).toFixed(0)}%</span>
        </div>
      </SketchRule>
    </div>
  )
}

配合 Minimap

import React, { useRef, useState } from 'react'
import { SketchRule, Minimap } from 'react-sketch-ruler'
import type { SketchRulerMethods } from 'react-sketch-ruler'

const Demo: React.FC = () => {
  const sketchRef = useRef<SketchRulerMethods>(null)
  const [scale, setScale] = useState(1)
  const [offset, setOffset] = useState({ x: 0, y: 0 })

  const handleZoomChange = (detail: { scale: number; x: number; y: number }) => {
    setScale(detail.scale)
    setOffset({ x: detail.x, y: detail.y })
  }

  const handleNavigate = (x: number, y: number) => {
    sketchRef.current?.setTransform({ x, y })
  }

  return (
    <>
      <SketchRule ref={sketchRef} scale={scale} onZoomChange={handleZoomChange} ...>
        <div data-type="page">...</div>
      </SketchRule>

      <Minimap
        contentWidth={1000}
        contentHeight={700}
        viewportX={offset.x}
        viewportY={offset.y}
        viewportWidth={1470}
        viewportHeight={700}
        scale={scale}
        width={200}
        height={150}
        onNavigate={handleNavigate}
      />
    </>
  )
}

插件系统

import { definePlugin } from 'react-sketch-ruler'
import type { SketchRulerPlugin } from 'react-sketch-ruler'

const myPlugin = definePlugin(() => ({
  name: 'demo-logger',
  beforeZoom(ctx) {
    if (ctx.to > 3) ctx.cancel()
  },
  afterZoom(ctx) {
    console.log('zoom', ctx.from, '→', ctx.to)
  },
  onLineCreate: (ctx) => console.log('line created', ctx.line.id),
  onLineDelete: (ctx) => console.log('line deleted', ctx.line.id)
}))

// 使用(建议用 useMemo 缓存,避免反复注册)
function App() {
  const plugins = React.useMemo(() => [myPlugin()], [])
  return <SketchRule plugins={plugins} ... />
}

插件支持以下生命周期钩子:beforeZoom / afterZoom / beforePan / afterPan / onSnap / onLineCreate / onLineDelete / onLineMove,以及自定义渲染器 registerRenderer。详见源码 packages/sketch-ruler/AGENTS.md

Hooks

如果你需要更底层的控制能力,可以直接使用提供的 Hooks:

import {
  useSketchRuler,
  useCanvasTransform,
  useGuideLines,
  useInputManager,
  useSnapDetection
} from 'react-sketch-ruler'

API

Props

| 属性 | 描述 | 类型 | 默认值 | | --- | --- | --- | --- | | width | 容器宽度 | number | 1400 | | height | 容器高度 | number | 800 | | canvasWidth | 画布宽度 | number | 700 | | canvasHeight | 画布高度 | number | 700 | | thick | 标尺厚度 | number | 16 | | scale | 缩放值(受控属性) | number | 1 | | showRuler | 是否显示标尺 | boolean | true | | isShowReferLine | 是否显示参考线 | boolean | true | | lines | 初始化参考线 | { h: number[]; v: number[] } | { h: [], v: [] } | | palette | 标尺样式配置 | PaletteType | {} | | shadow | 阴影高亮区域 | { x, y, width, height } | { x:0, y:0, width:0, height:0 } | | zoomMode | 缩放原点模式 | 'pointer' \| 'viewport-center' \| 'content-center' | 'pointer' | | zoomStep | 缩放步长 | number | 0.25 | | minZoom | 最小缩放 | number | 0.1 | | maxZoom | 最大缩放 | number | 10 | | enableAnimation | 是否启用动画 | boolean | false | | animationMode | 动画模式 | 'direct' \| 'ease-out' \| 'damped' \| 'exponential' | 'ease-out' | | autoCenter | 初始化自动居中 | boolean | true | | paddingRatio | 自动居中边距比(0~0.5) | number | 0.2 | | initialOffset | 初始偏移(autoCenter=false 时生效) | { x: number; y: number } | { x:0, y:0 } | | snapThreshold | 吸附阈值 | number | 5 | | lockLine | 是否锁定参考线 | boolean | false | | selfHandle | 自行处理输入事件 | boolean | false | | plugins | 插件列表 | SketchRulerPlugin[] | [] | | showMinorTicks | 是否显示次刻度 | boolean | false | | eyeIcon | 左上角睁眼图标 Base64 | string | — | | closeEyeIcon | 左上角闭眼图标 Base64 | string | — | | deleteLabel | 删除参考线提示文字 | string | '放开删除' | | children | 画布内容与工具栏插槽 | React.ReactNode | — |

Callbacks

| 回调 | 描述 | 参数 | | ------------------- | ------------------ | ---------------------------------------- | | onUpdateScale | 缩放值变化 | (scale: number) => void | | onZoomChange | 缩放/平移变化 | ({ scale, x, y }) => void | | onUpdateLines | 参考线变化 | ({ h: number[], v: number[] }) => void | | onUpdateLockLine | 参考线锁定状态变化 | (lock: boolean) => void | | onHandleCornerClick | 左上角按钮点击 | (showReferLine: boolean) => void |

Ref

通过 ref 可以调用以下方法:

| 方法 | 描述 | | ---------------------------------- | -------------------- | | engine | TransformEngine 实例 | | setTransform({ x?, y?, scale? }) | 设置变换状态 | | zoomIn() | 放大 | | zoomOut() | 缩小 | | reset() | 重置到初始状态 | | zoomToPreset(scale) | 缩放到预设比例 | | setZoomMode(mode) | 设置缩放模式 |

Palette

| 属性 | 描述 | 默认值 | | -------------------- | -------------- | ---------- | | bgColor | 画布背景 | #f6f7f9 | | tickColor | 刻度颜色 | #BABBBC | | labelColor | 刻度标签颜色 | #7D8694 | | guideLineColor | 参考线颜色 | #51d6a9 | | guideLineLockedColor | 锁定参考线颜色 | #d4d7dc | | hoverBg | 标签背景色 | transparent | | hoverColor | 标签文字色 | #000 | | borderColor | 尺子边框颜色 | #eeeeef | | shadowColor | 阴影背景色 | #e9f7fe | | fontShadowColor | 阴影字体颜色 | #106ebe | | guideLineStyle | 参考线样式 | 'dashed' | | guideLineWidth | 参考线宽度 | 1 | | labelEnabled | 是否显示标签 | true |

Minimap API

| 属性 | 描述 | 类型 | 默认值 | | -------------- | ----------- | -------- | ------ | | contentWidth | 内容宽度 | number | — | | contentHeight | 内容高度 | number | — | | viewportX | 视口 X 偏移 | number | — | | viewportY | 视口 Y 偏移 | number | — | | viewportWidth | 视口宽度 | number | — | | viewportHeight | 视口高度 | number | — | | scale | 缩放比例 | number | — | | width | 缩略图宽度 | number | 200 | | height | 缩略图高度 | number | 150 |

| 回调 | 描述 | 参数 | | ----------- | -------------- | -------------------------------- | | onNavigate | 导航到指定位置 | (x: number, y: number) => void | | onDragStart | 开始拖拽 | () => void | | onDragEnd | 结束拖拽 | () => void |

2.x → 3.x 迁移指南

v3.x 是架构重构版本,与 vue3-sketch-ruler v3.x 对齐,内置 TransformEngine 替代了外部 simple-panzoom 依赖,并引入了 Minimap、插件系统、动画系统等全新能力。

主要 Breaking Changes

| 变更项 | 2.x 写法 | 3.x 写法 | 说明 | | --- | --- | --- | --- | | 组件名 | <SketchRule> | <SketchRule>(保持不变) | — | | 导出方式 | import SketchRule from 'react-sketch-ruler' | import { SketchRule } from 'react-sketch-ruler' | 改为命名导出,仍保留默认导出兼容 | | 工具栏插槽 | 通过 ref 调用 | slot="toolbar" 子元素 | 在 children 中传入 <div slot="toolbar">...</div> | | 缩放事件 | onZoomChange / updateScale | onUpdateScale / onZoomChange | onUpdateScale 仅通知 scale;onZoomChange 返回 { scale, x, y } | | 参考线事件 | handleLine | onUpdateLines | 统一回调命名风格 | | 偏移控制 | panzoomOption | autoCenterpaddingRatioinitialOffset | 移除 panzoomOption,改为内置引擎直接配置 | | 缩放控制 | panzoomOption | zoomModezoomStepminZoommaxZoom | 内置引擎直接配置 | | 动画系统 | 无 | enableAnimationanimationMode | 新增,支持 ease-outdampedexponentialdirect | | 阴影文字 | showShadowText | 移除 | 3.x 已移除该属性 | | palette 属性 | lineTypelineColorlongfgColorfontColor | guideLineStyleguideLineColortickColorlabelColor | 命名规范化 | | Ref 暴露 | panzoomInstance | engine(TransformEngine) | 直接暴露内置引擎实例 | | Ref 方法 | zoomIn()zoomOut()reset() | 同上,并新增 setTransform()zoomToPreset()setZoomMode() | 方法更丰富 | | 外部依赖 | simple-panzoom | 零外部 panzoom 依赖 | 需从项目中移除 simple-panzoom |

快速迁移示例

2.x 代码:

import SketchRule from 'react-sketch-ruler'
;<SketchRule
  ref={sketchruleRef}
  scale={state.scale}
  panzoomOption={panzoomOption}
  palette={{ lineType: 'dashed', lineColor: '#51d6a9' }}
  handleLine={handleLinesChange}
>
  <div>...</div>
</SketchRule>

3.x 代码:

import { SketchRule } from 'react-sketch-ruler'
;<SketchRule
  ref={sketchRef}
  scale={state.scale}
  zoomMode="pointer"
  enableAnimation={true}
  animationMode="ease-out"
  palette={{ guideLineStyle: 'dashed', guideLineColor: '#51d6a9' }}
  onUpdateLines={handleLinesChange}
  onZoomChange={handleZoomChange}
>
  <div>...</div>
  <div slot="toolbar">
    <button onClick={() => sketchRef.current?.reset()}>还原</button>
    <button onClick={() => sketchRef.current?.zoomIn()}>放大</button>
    <button onClick={() => sketchRef.current?.zoomOut()}>缩小</button>
    <button onClick={() => sketchRef.current?.zoomToPreset(1)}>100%</button>
  </div>
</SketchRule>

新增能力速览

  • Minimap 缩略图:独立组件,支持拖拽视口与点击跳转
  • 插件系统:通过 plugins 属性注入生命周期钩子
  • 吸附引擎snapThreshold 配置参考线吸附阈值
  • 动画引擎enableAnimation + animationMode 实现平滑缩放/平移
  • 多实例支持:每个 SketchRule 实例独立管理自己的 TransformEngine
  • 纯原生零依赖:核心引擎 @sketch-ruler/core 纯原生实现,无需 panzoom 等第三方库

开发

# 安装依赖
pnpm install

# 开发模式(先构建组件库,再启动文档站点)
pnpm dev

# 构建组件库
pnpm build

# 构建文档站点
pnpm build:demo

# 运行测试
pnpm test

# 格式化与检查
pnpm fmt
pnpm lint:check

🌈 应用案例

如果你正在使用 react-sketch-ruler,欢迎提交 PR 添加你的项目!

QQ 技术交流群

贡献者

最后

这是个开源业余做的功能,欢迎加强该插件的小伙伴加入。如果 react-sketch-ruler 对您有帮助,请给个 star,您的鼓励是我最大的动力。

引用