npm.io
3.1.6 • Published 2 weeks ago

@sketch-ruler/canvas

Licence
MIT
Version
3.1.6
Deps
1
Size
107 kB
Vulns
0
Weekly
0

@sketch-ruler/canvas

框架无关的 Canvas 2D 渲染器与 DOM 输入管理器。负责标尺绘制、离屏缓存、鼠标/键盘/滚轮事件适配。依赖 @sketch-ruler/core

安装

npm install @sketch-ruler/canvas
# 或
pnpm add @sketch-ruler/canvas

快速上手

InputManager — 统一输入管理

绑定到画布容器,自动处理 Ctrl+滚轮缩放空格+拖拽平移键盘快捷键(Ctrl+0 / Ctrl++/Ctrl+-)。

import { InputManager } from '@sketch-ruler/canvas'
import { TransformEngine } from '@sketch-ruler/core'

const engine = new TransformEngine({ x: 0, y: 0, scale: 1 })

const inputManager = new InputManager(engine, {
  zoomStep: 0.25, // 滚轮缩放步长
  zoomMode: 'pointer', // 'pointer' | 'viewport-center' | 'content-center'
  viewportSize: { width: 1470, height: 700 },
  contentSize: { width: 1920, height: 1080 },
  onCursorChange: (cls) => {
    // cls: 'default' | 'grab' | 'grabbing'
    container.className = cls
  }
})

// 绑定到画布 DOM(事件实际绑定到 parentElement)
inputManager.bind(canvasElement)

// 动态切换缩放模式
inputManager.setZoomMode('viewport-center')

// 获取当前光标类名
const cursorClass = inputManager.getCursorClass()

// 清理
inputManager.destroy()

事件处理细节:

  • 滚轮缩放:按住 Ctrl / Cmd + 滚轮,以 zoomMode 指定的原点进行缩放
  • 空格拖拽:按住 Space + 鼠标左键拖拽平移
  • 键盘快捷键
    • Ctrl+0:缩放到 100%
    • Ctrl++ / Ctrl+=:放大
    • Ctrl+-:缩小
    • Ctrl+1:适配视口(留 5% 边距)
Canvas2DRenderer — Canvas 2D 标尺渲染器
import { Canvas2DRenderer } from '@sketch-ruler/canvas'

const canvas = document.getElementById('ruler') as HTMLCanvasElement
const renderer = new Canvas2DRenderer(canvas)

renderer.render({
  width: 1400,
  height: 20,
  scale: 1,
  offset: 0,
  vertical: false, // false=水平标尺, true=垂直标尺
  thick: 20,
  marks: scaleMarks, // 由 core 的 computeScaleMarks 生成
  config: tickConfig,
  palette: {
    bgColor: '#f6f7f9',
    tickColor: '#BABBBC',
    labelColor: '#7D8694',
    borderColor: '#eeeeef'
  }
})
离屏缓存 — OffscreenRulerCache

用于频繁重绘场景,将标尺静态外观预渲染到离屏 Canvas,仅在配色/厚度/密度变更时重建。

import { OffscreenRulerCache } from '@sketch-ruler/canvas'

const cache = new OffscreenRulerCache()

// 在渲染循环中使用
const usedCache = cache.drawStatic(targetCtx, marks, {
  width: 1400,
  height: 20,
  ratio: window.devicePixelRatio,
  palette,
  thick: 20,
  vertical: false,
  canvasSize: 1000
})

// 清空缓存(如配色变更时)
cache.clear()
标签缓存 — LabelCache

缓存刻度文字标签,避免每帧重复测量文本和 fillText。

import { LabelCache } from '@sketch-ruler/canvas'

const labelCache = new LabelCache(500) // 最大缓存 500 条

// 在 Canvas2DRenderer 渲染循环中使用
const entry = labelCache.get(ctx, { text: '100', font: '12px Arial', color: '#7D8694' })
// entry: { canvas: HTMLCanvasElement, width: number, height: number }
ctx.drawImage(entry.canvas, x, y)

// 清空缓存
labelCache.clear()
滚轮标准化 — WheelNormalizer

将不同浏览器/操作系统的滚轮事件统一为标准格式。

import { normalizeWheel, getZoomDelta } from '@sketch-ruler/canvas'

canvas.addEventListener('wheel', (e) => {
  // 标准化滚轮事件
  const normalized = normalizeWheel(e)
  // normalized: { deltaX, deltaY, deltaZ, deltaMode }

  // 计算缩放增量(默认灵敏度 0.001)
  const delta = getZoomDelta(e, 0.001)
  engine.zoomBy(delta, e.clientX, e.clientY)
})
底层适配器(自行组合事件)

如果你不想用 InputManager,可以直接使用底层适配器:

import { MouseAdapter } from '@sketch-ruler/canvas'
import type { MouseAdapterCallbacks } from '@sketch-ruler/canvas'

const adapter = new MouseAdapter(parentElement, {
  onWheel: (e, normalized) => {
    // 自定义滚轮处理
  },
  onMouseDown: (e) => {
    // 自定义鼠标按下
  },
  onMouseMove: (e) => {
    // 自定义鼠标移动
  },
  onMouseUp: (e) => {
    // 自定义鼠标抬起
  },
  onMouseEnter: () => {},
  onMouseLeave: () => {}
} as MouseAdapterCallbacks)

adapter.bind()
// adapter.unbind()
import { KeyboardAdapter } from '@sketch-ruler/canvas'
import type { KeyCombo } from '@sketch-ruler/canvas'

const kb = new KeyboardAdapter({
  onShortcut: (combo: KeyCombo, e: KeyboardEvent) => {
    // combo: 'ctrl+0' | 'ctrl+plus' | 'ctrl+minus' | 'space' | ...
    console.log('shortcut', combo)
  }
})

kb.bind()
// kb.unbind()

API 概览

导出 类型 说明
InputManager 统一输入管理(滚轮/拖拽/键盘)
MouseAdapter 鼠标事件封装(wheel/mousedown/mousemove/mouseup)
KeyboardAdapter 键盘快捷键封装
normalizeWheel 函数 滚轮事件标准化
getZoomDelta 函数 从原生 WheelEvent 计算缩放增量
Canvas2DRenderer Canvas 2D 标尺渲染器
OffscreenRulerCache 离屏标尺缓存
LabelCache 刻度标签缓存

与 @sketch-ruler/core 的配合

import { TransformEngine, computeScaleMarks, getTickConfig } from '@sketch-ruler/core'
import { InputManager, Canvas2DRenderer } from '@sketch-ruler/canvas'

// 1. 创建引擎
const engine = new TransformEngine({ x: 0, y: 0, scale: 1 })

// 2. 绑定输入
const input = new InputManager(engine, { zoomMode: 'pointer' })
input.bind(canvasElement)

// 3. 监听状态并渲染
engine.onUpdate((state) => {
  // 更新 DOM transform
  content.style.transform = `matrix(${state.scale}, 0, 0, ${state.scale}, ${state.x}, ${state.y})`

  // 渲染标尺
  const marks = computeScaleMarks({
    scale: state.scale,
    offset: state.x,
    viewportSize: 1400,
    thick: 20,
    config: getTickConfig(state.scale)
  })
  renderer.render({ width: 1400, height: 20, scale: state.scale, offset: state.x, marks })
})

License

MIT

Keywords