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

transform-info-panel

v0.2.0

Published

<p align="center"> <img src="https://img.shields.io/badge/ver-0.0.1-blueviolet?style=for-the-badge" alt="version" /> <img src="https://img.shields.io/badge/three.js-≥0.170-blue?style=for-the-badge&logo=threedotjs" alt="three.js" /> <img src="https:/

Readme

  ╔══════════════════════════════════════════════════════════╗
  ║ ✦ TransformInfoPanel · 变换信息浮动面板 ✦                ║
  ║ ✦ TransformInfoPanel · Floating Transform Info Panel ✦   ║
  ║     实时查看每一次变换的精确数值。                         ║
  ║     See the exact value of every transform, in real time. ║
  ╚══════════════════════════════════════════════════════════╝

📜 概述

📜 Introduction

TransformInfoPanel 是一个通用变换信息浮动面板,同时兼容 TTControlsThree.js 原生 TransformControlsTransformInfoPanel is a universal floating transform info panel, compatible with both TTControls and native Three.js TransformControls.

当你拖拽物体的平移/旋转/缩放手柄时,面板会自动出现在光标附近,实时显示当前的变换模式操作轴坐标空间以及 X / Y / Z 三个轴向的精确数值。 When you drag any translate/rotate/scale handle, this panel automatically appears near your cursor, displaying the current transform mode, active axis, coordinate space, and precise X / Y / Z values in real time.

通过 ITransformControls 接口抽象,面板不直接依赖任何特定控件类型,使用时只需传入符合接口的实例。 Via the ITransformControls interface abstraction, the panel has no direct dependency on any specific controls — just pass in any instance that satisfies the interface.

  • TTControls 用户:直接传入即可(TTControls 天然满足接口)
  • TTControls users: pass it in directly (TTControls naturally satisfies the interface)
  • 原生 TransformControls 用户:使用内置的 NativeTransformControlsAdapter 包裹
  • Native TransformControls users: wrap with the built-in NativeTransformControlsAdapter

支持中英双语暗色/亮色主题切换,以及通过 CSS 变量完全自定义外观。 Supports Chinese/English bilingual display, dark/light theme switching, and full visual customization via CSS variables.

TypeScript 编写,零框架依赖,纯 DOM 渲染,轻量高效。 Written in pure TypeScript, zero framework dependencies, pure DOM rendering — lightweight and efficient.


✨ 特性

✨ Features


📦 安装

📦 Installation

# npm
npm install transform-info-panel

# pnpm(推荐 / recommended)
pnpm add transform-info-panel

# yarn
yarn add transform-info-panel

同伴依赖

Peer Dependencies

| 依赖 / Dependency | 版本 / Version | 说明 / Note | |-------------------|----------------|-------------| | three | ≥ 0.170.0 | 必须 / required | | ttcontrols | ≥ 0.0.1 | 可选 —— 仅使用 TTControls 时需要 | | | | Optional — only needed if using TTControls directly |

⚠️ 请确保项目中已安装 three。使用原生 TransformControls 时无需安装 ttcontrols。 ⚠️ Make sure three is installed. No need to install ttcontrols when using native TransformControls.


🚀 快速开始

🚀 Quick Start

方式 A:TTControls(直接使用)

Method A: TTControls (direct usage)

import * as THREE from 'three'
import { TTControls } from 'ttcontrols'
import { TransformInfoPanel } from 'transform-info-panel'

// 1. 搭建场景与 TTControls
// 1. Set up scene & TTControls
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
document.body.appendChild(renderer.domElement)

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0xff6b9d })
)
scene.add(cube)

const controls = new TTControls(camera, renderer.domElement)
controls.attach(cube)
scene.add(controls.getHelper())

// 2. 创建信息面板 —— 一行代码!
// 2. Create the info panel — one line!
const panel = new TransformInfoPanel(controls, {
  locale: 'zh',          // 语言 / locale: 'zh' | 'en'
  theme: 'dark',         // 主题 / theme: 'dark' | 'light'
  offset: [50, -100],    // 面板偏移 / panel offset
})

// 3. 渲染循环
// 3. Render loop
function animate() {
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
}
animate()

方式 B:原生 TransformControls(通过适配器)

Method B: Native TransformControls (via adapter)

import * as THREE from 'three'
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'
import { TransformInfoPanel, NativeTransformControlsAdapter } from 'transform-info-panel'

// 1. 搭建场景与原生 TransformControls
// 1. Set up scene & native TransformControls
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
document.body.appendChild(renderer.domElement)

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0xe94560 })
)
scene.add(cube)

const controls = new TransformControls(camera, renderer.domElement)
controls.attach(cube)
controls.setMode('translate')
scene.add(controls.getHelper())

// 2. 创建适配器 + 面板
// 2. Create adapter + panel
const adapter = new NativeTransformControlsAdapter(controls, camera)
const panel = new TransformInfoPanel(adapter, {
  locale: 'en',
  theme: 'dark',
  offset: [60, -80],
})

// 3. 渲染循环
// 3. Render loop
function animate() {
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
}
animate()

🎉 完成!拖拽手柄时,变换数值面板会自动出现并跟随光标! 🎉 Done! The transform info panel appears and follows your cursor when you drag a handle!


📖 API 参考

📖 API Reference

构造函数

Constructor

new TransformInfoPanel(controls: ITransformControls, options?: TransformInfoPanelOptions)

| 参数 / Parameter | 类型 / Type | 说明 / Description | |------|------|------| | controls | ITransformControls | 满足接口的控件实例(TTControls 或 NativeTransformControlsAdapter) | | | | Controls instance satisfying the interface (TTControls or NativeTransformControlsAdapter) | | options | TransformInfoPanelOptions | 可选配置项 / optional configuration |


ITransformControls 接口

ITransformControls Interface

面板通过此接口与控件解耦,任何实现该接口的对象都可以作为数据源。 The panel is decoupled from controls via this interface — any object implementing it can serve as a data source.

export interface ITransformControls {
  object: Object3D | undefined
  mode: string
  space: string
  axis: string | null
  camera: Camera
  domElement?: HTMLElement | SVGElement | null
  worldPosition: Vector3
  rotationAngle: number
  rotationAxis: Vector3
  getAllSubMode?(): string | null
  addEventListener(type: string, listener: Function): void
  removeEventListener(type: string, listener: Function): void
}

NativeTransformControlsAdapter

NativeTransformControlsAdapter

内置适配器类,将原生 Three.js TransformControls 包装为 ITransformControls 接口。 Built-in adapter class that wraps native Three.js TransformControls into the ITransformControls interface.

// 构造适配器(需传入 controls 和 camera)
// Construct the adapter (controls + camera required)
import { NativeTransformControlsAdapter } from 'transform-info-panel'

const adapter = new NativeTransformControlsAdapter(nativeControls, camera)

// 适配器桥接的关键差异 / Key differences bridged by the adapter:
//  - camera          → 手动传入并存储 / manually stored
//  - worldPosition   → 从 object.getWorldPosition() 每帧计算 / per-frame via getWorldPosition()
//  - rotationAngle   → mouseDown 记录初始四元数,change 时计算 delta / delta quaternion on change
//  - rotationAxis    → 同上,从 delta quaternion 分解轴 / decomposed from delta quaternion
//  - mode-changed 等 → 在 change 中对比前后值自行派发 / self-dispatched by comparing prev/next
//  - getAllSubMode() → 原生不支持,接口标记为可选 / native unsupported, marked optional

// 销毁适配器(解绑所有原生事件监听)
// Dispose the adapter (unbind all native event listeners)
adapter.dispose()

| 方法 / Method | 说明 / Description | |------|------| | new NativeTransformControlsAdapter(controls, camera) | 构造适配器 / construct adapter | | .dispose() | 销毁适配器,解绑所有原生事件 / dispose, unbind all native events | | 所有 getter/setter | 代理到原生控件对应属性 / proxy to native control properties |


配置选项

Options

interface TransformInfoPanelOptions {
  offset?: [number, number]                   // 默认 / default: [50, -100]
  locale?: 'zh' | 'en'                       // 默认 / default: 'zh'
  theme?: 'dark' | 'light' | Partial<PanelTheme>  // 默认 / default: 'dark'
}

| 属性 / Property | 说明 / Description | |------|------| | offset | 面板相对于物体屏幕投影位置的像素偏移 [x, y] | | | Pixel offset [x, y] from the object's screen-projected position | | locale | 面板显示语言:'zh' 中文 / 'en' English | | | Panel display language | | theme | 预设主题名或自定义主题对象(部分覆盖 dark 预设) | | | Theme preset name or a partial custom theme object (merges with dark preset) |


实例方法

Instance Methods

// 切换语言 —— 即时更新面板所有文字
// Switch locale — instantly updates all panel text
panel.setLocale('en')
panel.setLocale('zh')

// 切换主题 —— 即时更新面板所有 CSS 变量
// Switch theme — instantly updates all CSS variables
panel.setTheme('light')
panel.setTheme('dark')
panel.setTheme({ '--tt-panel-bg': 'rgba(10, 10, 30, 0.95)' })

// 销毁面板 —— 解绑所有事件、移除 DOM 节点
// Dispose — unbind all events, remove DOM node
panel.dispose()

静态方法

Static Methods

// 获取预设主题的 CSS 变量对象(用于外部自定义修改)
// Get a theme preset's CSS variable object (for external customization)
const darkTheme = TransformInfoPanel.themePreset('dark')
const lightTheme = TransformInfoPanel.themePreset('light')

// 基于预设创建自定义主题
// Create a custom theme based on a preset
const myTheme = {
  ...TransformInfoPanel.themePreset('dark'),
  '--tt-panel-bg': 'rgba(0, 20, 40, 0.90)',
  '--tt-panel-mode': '#ff6b9d',
}

🔌 适配器工作原理

🔌 How the Adapter Works

  ┌──────────────────────┐
  │   TransformInfoPanel │  ← 只依赖 ITransformControls 接口
  │                      │  ← Only depends on ITransformControls
  └──────────┬───────────┘
             │
    ┌────────┴────────┐
    │ ITransformControls │  ← 抽象接口 / abstract interface
    └────────┬────────┘
             │
     ┌───────┴───────┐
     │               │
  ┌──┴────────┐  ┌───┴──────────────────────┐
  │ TTControls │  │ NativeTransformControls- │
  │ (直接传入) │  │ Adapter (包装原生控件)   │
  │ (direct)   │  │ (wraps native controls)  │
  └───────────┘  └───┬──────────────────────┘
                      │
               ┌──────┴──────────────┐
               │ TransformControls   │
               │ (three/examples/jsm)│
               └─────────────────────┘

适配器在原生 change 事件中自动完成以下桥接: The adapter automatically bridges the following in the native change event:

| 原生缺失 / Native Missing | 适配器方案 / Adapter Solution | |------|------| | camera | 构造时手动传入 / passed manually at construction | | worldPosition | object.getWorldPosition() 每次 change 时计算 | | rotationAngle / rotationAxis | mouseDown 记录初始四元数,change 时分解 delta quaternion | | mode-changed / axis-changed / space-changed | change 中比对 prev/next 值,变化时自行派发事件 |


🎨 主题系统

🎨 Theme System

预设主题

Preset Themes

| 主题 / Theme | 背景 / Background | 文字 / Text | 模式色 / Mode Color | |------|------|------|------| | dark | rgba(30, 30, 30, 0.92) | #e0e0e0 | #42a5f5(蓝 / blue) | | light | rgba(255, 255, 255, 0.94) | #333 | #1976d2(深蓝 / deep blue) |

CSS 变量参考

CSS Variable Reference

面板通过以下 CSS 变量控制外观,可在 setTheme() 中覆盖任意一项。 The panel's appearance is controlled by these CSS variables — override any of them via setTheme().

interface PanelTheme {
  '--tt-panel-bg': string       // 面板背景色 / panel background
  '--tt-panel-text': string     // 主文字颜色 / main text color
  '--tt-panel-mode': string     // 模式标签颜色 / mode label color
  '--tt-panel-divider': string  // 分隔线颜色 / divider color
  '--tt-panel-muted': string    // 次要文字颜色 / muted text color
  '--tt-panel-value': string    // 数值文字颜色 / value text color
  '--tt-panel-shadow': string   // 外阴影 / box shadow
}

自定义主题示例

Custom Theme Example

// 赛博朋克风 / Cyberpunk style
panel.setTheme({
  '--tt-panel-bg': 'rgba(5, 2, 20, 0.92)',
  '--tt-panel-text': '#00ffcc',
  '--tt-panel-mode': '#ff00ff',
  '--tt-panel-divider': 'rgba(0, 255, 204, 0.3)',
  '--tt-panel-muted': '#00aaaa',
  '--tt-panel-value': '#ffff00',
  '--tt-panel-shadow': '0 0 16px rgba(0, 255, 204, 0.2)',
})

🌐 语言系统

🌐 Locale System

支持的语言

Supported Languages

| 语言 / Locale | 值 / Value | 效果 | |------|------|------| | 中文 / Chinese | 'zh' | 面板显示:"平移"、"旋转"、"缩放"、"局部"、"世界"、"轴向"…… | | English | 'en' | Panel shows: "Translate", "Rotate", "Scale", "Local", "World", "Axis"... |

运行时切换

Runtime Switching

// 中文 —— 适合中文用户
// Chinese — for Chinese-speaking users
panel.setLocale('zh')

// English — for international users
// 英文 —— 适合国际用户
panel.setLocale('en')

切换语言会即时生效,无需重新创建面板或刷新页面。 Switching locales takes effect immediately — no need to recreate the panel or refresh the page.


🧬 数据格式化逻辑

🧬 Data Formatting Logic

面板根据当前变换模式,自动选择不同的数据格式化策略。 The panel automatically selects different data formatting strategies based on the active transform mode.

平移模式

Translate Mode

显示相对拖拽起点的位移增量(4 位小数)。 Shows displacement delta relative to drag start (4 decimal places).

X  +2.3456
Y  -1.0000
Z  0.0000

旋转模式

Rotate Mode

显示当前旋转角度(转换为度数,保留 2 位小数,带 ° 符号)。 Shows current rotation angle (converted to degrees, 2 decimal places, with ° suffix).

X  45.00°
Y  0.00°
Z  -15.50°
  • 单轴旋转 (X/Y/Z):仅显示该轴角度
  • Single-axis rotation (X/Y/Z): shows only that axis angle
  • 全轴旋转 (XYZE):分解为 X/Y/Z 三个分量
  • Full rotation (XYZE): decomposed into X/Y/Z components
  • 平面旋转 (E):显示总旋转角度
  • Plane rotation (E): shows total rotation angle

缩放模式

Scale Mode

显示当前物体的缩放值(4 位小数)。 Shows current object scale values (4 decimal places).

X  1.5000
Y  1.5000
Z  0.8000

All 模式(仅 TTControls)

All Mode (TTControls only)

自动根据 getAllSubMode() 判断当前实际执行的是平移/旋转/缩放,选择对应的格式化器。 Automatically determines whether the actual operation is translate/rotate/scale via getAllSubMode(), and selects the corresponding formatter.


🏗️ 架构概览

🏗️ Architecture

TransformInfoPanel(主控类 / main class)
  ├── ITransformControls(接口层 / interface layer)
  │    ├── TTControls(直接满足 / naturally satisfies)
  │    └── NativeTransformControlsAdapter(适配器 / adapter)
  │         └── TransformControls(原生 Three.js 控件 / native Three.js control)
  ├── PanelUI(纯 DOM UI / pure DOM UI)
  │    ├── header: mode 标签 + space 标签
  │    ├── axis row: "Axis" 标签 + 当前轴名
  │    └── value rows: X / Y / Z 轴标签 + 数值
  ├── Formatters(数据格式化器 / data formatters)
  │    ├── TranslateFormatter ← 平移增量计算
  │    ├── RotateFormatter   ← 旋转角度计算
  │    └── ScaleFormatter    ← 缩放值读取
  ├── Event Listeners(事件监听 / event listeners)
  │    ├── mouseDown → 记录初始状态,显示面板
  │    ├── mouseUp   → 隐藏面板
  │    ├── change    → 刷新数据
  │    ├── mode-changed → 更新模式标签
  │    ├── axis-changed → 更新轴标签与可见行
  │    └── space-changed → 更新空间标签
  └── Animation Loop(动画循环 / animation loop)
       └── requestAnimationFrame → 每帧更新面板屏幕位置

层级说明

Layer Breakdown

| 层 / Layer | 职责 / Responsibility | |------|------| | 🎛️ 主控层 | 事件编排、格式化器调度、动画循环管理 | | Controller | Event orchestration, formatter dispatch, animation loop management | | 🔌 接口层 | ITransformControls 接口 + NativeTransformControlsAdapter 适配器,解耦数据源 | | Interface | ITransformControls interface + NativeTransformControlsAdapter, decouples data source | | 🖼️ UI 层 | 纯 DOM 构建,CSS 变量驱动样式,无框架依赖 | | UI | Pure DOM construction, CSS-variable-driven styling, zero framework | | 🧮 格式化层 | 三种模式的数据计算:增量平移、角度转换、缩放读取 | | Formatter | Per-mode data calculation: displacement delta, angle conversion, scale readout | | 📡 事件层 | 监听控件的 6 种事件,驱动面板显隐与数据刷新 | | Events | Listens to 6 control events to drive show/hide and data refresh | | 🖥️ 定位层 | 世界坐标 → 屏幕坐标投影 + requestAnimationFrame 持续跟随 | | Positioning | World→screen projection + requestAnimationFrame continuous tracking |


🧪 开发

🧪 Development

# 克隆仓库
# Clone the repo
git clone <your-repo-url>
cd packages/TransformInfoPanel

# 安装依赖
# Install dependencies
pnpm install

# 构建
# Build
pnpm build

技术栈

Tech Stack

  • Three.js — Vector3 投影计算 / Vector3 projection math
  • TypeScript — 类型安全 / type safety
  • Vite — 构建工具 / build tooling
  • DOM API — UI 渲染 / UI rendering

📐 面板样式规范

📐 Panel Style Specification

| 属性 / Property | 值 / Value | 说明 / Note | |------|------|------| | 定位方式 / Position | fixed 固定定位 | 相对于视口定位,不受页面滚动影响 | | z-index | 10000 | 确保面板在最顶层 | | 圆角 / Border Radius | 5px | 柔和的圆角 | | 字体 / Font Family | Segoe UI, Arial, sans-serif | 标签文字 | | 数值字体 / Value Font | Consolas, Courier New, monospace | 等宽字体,数值对齐 | | 字号 / Font Size | 12px | 紧凑但清晰 | | 模糊 / Backdrop Filter | blur(6px) | 毛玻璃效果 | | 指针事件 / Pointer Events | none | 面板不拦截鼠标事件 | | 对齐方式 / Transform | translate(-50%, -50%) | 以面板中心为锚点 | | 轴颜色 X / Axis Color X | #EB4659 | 红色系 / red | | 轴颜色 Y / Axis Color Y | #86CD35 | 绿色系 / green | | 轴颜色 Z / Axis Color Z | #3E8AEF | 蓝色系 / blue |


🗺️ 路线图

🗺️ Roadmap

  • [x] 平移 / 旋转 / 缩放数值显示 / Translate, Rotate, Scale value display
  • [x] 中英双语支持 / Chinese & English locale support
  • [x] 暗色 / 亮色主题 / Dark & Light theme presets
  • [x] CSS 变量全自定义 / Full CSS variable customization
  • [x] 智能轴行显隐 / Smart axis row show/hide
  • [x] 动画循环光标跟随 / Animation loop cursor tracking
  • [x] All 三合一模式兼容 / All 3-in-1 mode compatibility
  • [x] 安全的 dispose 生命周期 / Safe dispose lifecycle
  • [x] 原生 TransformControls 适配器 / Native TransformControls adapter
  • [ ] 更多语言支持 / More locales
  • [ ] 可配置数值精度 / Configurable number precision
  • [ ] 面板位置吸附(防止超出视口)/ Edge snapping (prevent off-screen)
  • [ ] 动画过渡效果 / Transition animations
  • [ ] 独立适配器泛型化(支持任意控件注入)/ Generic adapter pattern

📄 许可证

📄 License

MIT © benxiaokang


  ╔══════════════════════════════════════════════╗
  ║   数值不说谎,每一帧都值得被看见。             ║
  ║   Numbers don't lie — every frame is worth seeing. ║
  ╚══════════════════════════════════════════════╝