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

ttcontrols

v0.5.1

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

  ╔══════════════════════════════════════════════════════════╗
  ║   ✦  TTControls  ·  下一代 Three.js 变换操控器  ✦          ║
  ║   ✦  TTControls  ·  A Next-Gen Transform Gizmo   ✦      ║
  ║     掌控你的物体,每次一个轴。                               ║
  ║     Take Control of Your Objects, One Axis at a Time.    ║
  ╚══════════════════════════════════════════════════════════╝

📜 概述

📜 Introduction

TTControls 是一个为 Three.js 打造的下一代变换控制器TTControls is a next-generation transform controller built for Three.js.

灵感源于 Three.js 官方 TransformControls,我们在其上做了全方位增强。 Inspired by the official Three.js TransformControls, we've reimagined it with a full suite of enhancements.

它支持平移旋转缩放三种模式,以及独创的 "All"(三合一)模式 —— 让三种手柄同时可见,如同全息控制面板。 It supports Translate, Rotate, Scale — plus a unique "All" (3-in-1) mode that renders all three gizmos simultaneously, like a holographic control panel.

TypeScript 编写,类型完整、事件丰富,是 Three.js 项目理想的交互编辑组件。 Written in pure TypeScript, with complete type definitions and a rich event system — the ideal editing component for any Three.js project.


✨ 特性

✨ Features


📦 安装

📦 Installation

# npm
npm install ttcontrols

# pnpm(推荐 / recommended)
pnpm add ttcontrols

# yarn
yarn add ttcontrols

同伴依赖

Peer Dependencies

| 依赖 / Dependency | 版本 / Version | |-------------------|----------------| | three | ≥ 0.170.0 |

⚠️ 请确保你的项目中已安装 three ⚠️ Make sure three are already installed in your project.


🚀 快速开始

🚀 Quick Start

最简示例

Minimal Example

import * as THREE from 'three'
import { TTControls } from 'ttcontrols'

// 1. 搭建场景
// 1. Set up scene
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)

// 2. 创建被操控的物体
// 2. Create an object to control
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshStandardMaterial({ color: 0xff6b9d })
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)

// 3. 实例化 TTControls
// 3. Instantiate TTControls
const controls = new TTControls(camera, renderer.domElement)

// 4. 绑定物体
// 4. Attach the object
controls.attach(cube)

// 5. 将手柄添加到场景
// 5. Add the gizmo helper to the scene
scene.add(controls.getHelper())

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

🎉 完成了!现在你的小方块可以自由拖拽、旋转、缩放了! 🎉 Done! Your cube can now be freely moved, rotated, and scaled!


📖 API 参考

📖 API Reference

构造函数

Constructor

new TTControls(camera: Camera, domElement?: HTMLElement | SVGElement)

| 参数 / Parameter | 类型 / Type | 说明 / Description | |------|------|------| | camera | THREE.Camera | 场景相机(透视/正交均可) | | | | Scene camera (perspective or orthographic) | | domElement | HTMLElement \| SVGElement | 监听指针事件的 DOM 容器(可选,可后续 connect) | | | | DOM element to listen for pointer events (optional, can be connected later) |


模式与空间

Modes & Space

// 设置变换模式
// Set transform mode
controls.mode = 'translate'   // 平移 / Translate
controls.mode = 'rotate'      // 旋转 / Rotate
controls.mode = 'scale'       // 缩放 / Scale
controls.mode = 'all'         // ✨ 三合一模式 / 3-in-1 mode

// 设置坐标空间
// Set coordinate space
controls.space = 'world'      // 世界空间 / World space
controls.space = 'local'      // 本地空间 / Local space

// 读取当前值
// Read current values
console.log(controls.mode)    // 'translate'
console.log(controls.space)   // 'world'
  三合一模式 (all) 布局:
  All (3-in-1) Mode Layout:
  ┌──────────────────────────────────────┐
  │  🟥 平移箭头 —— 最长、最外层              │
  │  🟥 Translate arrows: longest, outermost │
  │  🟩 旋转环   —— 居中                      │
  │  🟩 Rotate rings:   middle               │
  │  🟦 缩放方块 —— 最短、最内层              │
  │  🟦 Scale handles:  shortest, innermost   │
  │  三种手柄同时可见,互不遮挡 ✨            │
  │  All three gizmos visible, no occlusion. │
  └──────────────────────────────────────┘

吸附

Snap

// 平移吸附 —— 锁定到指定步长
// Translate snap — lock movement to a step size
controls.translationSnap = 0.5   // 以 0.5 为单位移动
controls.translationSnap = null  // 关闭吸附 / disable snap

// 旋转吸附 —— 角度步长(弧度)
// Rotate snap — angle step (in radians)
controls.rotationSnap = Math.PI / 12  // 每次旋转 15° / snap to 15° increments

// 缩放吸附
// Scale snap
controls.scaleSnap = 0.1   // 以 0.1 为单位缩放 / snap to 0.1 increments

// 缩放灵敏度(控制拖拽时的缩放速度,默认 0.2)
// Scale sensitivity (control drag scale speed, default 0.2)
controls.scaleSensitivity = 1     // 正常速度 / normal speed
controls.scaleSensitivity = 0.1   // 10% 速度,精细调节 / 10% speed, fine-tune
controls.scaleSensitivity = 0.01  // 1% 速度,极细微调 / 1% speed, micro-adjust

// 灵敏度 + 吸附组合使用,实现缓慢精确的缩放
// Combine sensitivity + snap for slow, precise scaling
controls.scaleSensitivity = 0.1
controls.scaleSnap = 0.05

轴控制

Axis Control

// 显示 / 隐藏特定轴
// Show / hide specific axis handles
controls.showX = false   // 隐藏 X 轴 / hide X axis
controls.showY = true
controls.showZ = true

// 当前激活的轴(只读,悬停或拖拽时自动更新)
// Active axis (read-only, updated on hover/drag)
console.log(controls.axis)   // 'X' | 'Y' | 'Z' | 'XY' | 'XZ' | 'XYZ' | 'XYZE' | null

范围限制

Range Limits

// 锁定位移边界
// Lock position boundaries
controls.minX = -10
controls.maxX = 10
controls.minY = 0          // 物体不能低于 Y=0 / object can't go below Y=0
controls.maxY = Infinity
controls.minZ = -5
controls.maxZ = 5

自定义颜色

Custom Colors

controls.setColors(
  0xEB4659,   // X 轴颜色(红)/ X axis (red)
  0x86CD35,   // Y 轴颜色(绿)/ Y axis (green)
  0x3E8AEF,   // Z 轴颜色(蓝)/ Z axis (blue)
  0xFFDD00    // 选中高亮色(黄)/ active highlight (yellow)
)

生命周期

Lifecycle

// 绑定物体,返回 this,支持链式调用
// Attach an object, returns this, supports chaining
controls.attach(myMesh)

// 解绑物体
// Detach the object
controls.detach()

// 重置当前拖拽(回到拖拽前状态)
// Reset current drag (back to pre-drag state)
controls.reset()

// 销毁控件(释放所有资源)
// Dispose — release all resources
controls.dispose()
// DOM 连接管理(适用于动态添加/移除 canvas)
// DOM connection management (for dynamically adding/removing canvas)
controls.connect(domElement)
controls.disconnect()

Helper 导出

Helper Export

// 获取控件场景子树,需手动添加到场景中
// Get the control's scene subtree (add to scene manually)
const helper = controls.getHelper()
scene.add(helper)

📡 事件系统

📡 Events

TTControls 提供 22+ 种细粒度事件,让你能精确感知每次状态变化。 TTControls exposes 22+ fine-grained event types, giving you full visibility into every state change.

| 事件名 / Event | 触发时机 / Trigger | Payload | |--------|----------|---------| | change | 任何状态变化 / Any state change | {} | | mouseDown | 开始拖拽 / Drag starts | { mode } | | mouseUp | 结束拖拽 / Drag ends | { mode } | | objectChange | 物体变换改变 / Object transform changed | {} | | mode-changed | 模式切换 / Mode switched | { value: TransformControlsMode } | | space-changed | 空间切换 / Space switched | { value: 'world' \| 'local' } | | axis-changed | 激活轴变化 / Active axis changed | { value: string \| null } | | dragging-changed | 拖拽状态变化 / Dragging state changed | { value: boolean } | | translationSnap-changed | 平移吸附变化 / Translation snap changed | { value: number \| null } | | rotationSnap-changed | 旋转吸附变化 / Rotation snap changed | { value: number \| null } | | scaleSnap-changed | 缩放吸附变化 / Scale snap changed | { value: number \| null } | | scaleSensitivity-changed | 缩放灵敏度变化 / Scale sensitivity changed | { value: number } | | size-changed | 手柄尺寸变化 / Handle size changed | { value: number } | | enabled-changed | 启用/禁用 / Enabled/disabled | { value: boolean } | | showX/Y/Z-changed | 轴可见性变化 / Axis visibility changed | { value: boolean } | | minX/maxX/...changed | 范围限制变化 / Range limit changed | { value: number } | | camera-changed | 相机变化 / Camera changed | { value: Camera } | | object-changed | 绑定物体变化 / Attached object changed | { value: Object3D } | | worldPosition-changed | 世界位置变化 / World position changed | { value: Vector3 } | | rotationAxis-changed | 旋转轴变化 / Rotation axis changed | { value: Vector3 } | | rotationAngle-changed | 旋转角变化 / Rotation angle changed | { value: number } |

// 事件监听示例
// Event listening examples
controls.addEventListener('mode-changed', (e) => {
  console.log(`模式切换为: ${e.value}`)
  console.log(`Mode switched to: ${e.value}`)
})

controls.addEventListener('dragging-changed', (e) => {
  if (e.value) {
    console.log('🎯 开始拖拽!/ Dragging started!')
  } else {
    console.log('✨ 拖拽结束~/ Dragging ended!')
  }
})

controls.addEventListener('axis-changed', (e) => {
  console.log(`当前轴: ${e.value ?? '无'}`)
  console.log(`Active axis: ${e.value ?? 'none'}`)
})

🎮 配套组件:TransformInfoPanel

🎮 Companion: TransformInfoPanel

TTControls 有一个好搭档 —— TransformInfoPanel! TTControls has a companion — TransformInfoPanel!

它是一个浮动信息面板,在拖拽手柄时显示实时变换数值。 A floating info panel that displays real-time transform values while you drag.

  ┌─────────────────────┐
  │  平移     LOCAL     │
  │  Translate  LOCAL   │
  │  Axis          X    │
  │  X   +1.2345        │
  │  Y   0.0000         │
  │  Z   -0.5678        │
  └─────────────────────┘
import { TransformInfoPanel } from 'transform-info-panel'

// 语言:'zh' | 'en'   主题:'dark' | 'light' | 自定义
// locale: 'zh' | 'en'   theme: 'dark' | 'light' | custom
const panel = new TransformInfoPanel(controls, {
  locale: 'zh',
  theme: 'dark',
  offset: [50, -100]     // 面板相对光标的偏移 / panel offset from cursor
})

🏗️ 架构概览

🏗️ Architecture

TTControls(主控类,继承 THREE.Controls)
TTControls (main class, extends THREE.Controls)
  ├── TransformControlsRoot(场景根节点 / scene root node)
  │    ├── TransformControlsGizmo(视觉手柄层 / visual handles)
  │    │    ├── gizmo['translate']  ← 平移手柄 / Translate handles
  │    │    ├── gizmo['rotate']     ← 旋转手柄 / Rotate handles
  │    │    ├── gizmo['scale']      ← 缩放手柄 / Scale handles
  │    │    ├── gizmo['all']        ← 三合一手柄 / 3-in-1 handles
  │    │    ├── picker['translate'] ← 不可见拾取层 / Invisible pick layer
  │    │    ├── picker['rotate']
  │    │    ├── picker['scale']
  │    │    └── picker['all']
  │    └── TransformControlsPlane(无限大操作平面 / infinite operating plane)
  └── 22+ 属性定义器 / 22+ property definers (defineProperty)

层级说明

Layer Breakdown

| 层 / Layer | 类 / Class | 职责 / Responsibility | |----|-----|------| | 🎛️ 主控层 | TTControls | 事件分发、生命周期管理、API 暴露 | | Controller | | Event dispatch, lifecycle, API exposure | | 🌳 场景层 | TransformControlsRoot | 每帧同步矩阵分解、相机参数 | | Scene | | Per-frame matrix decomposition, camera updates | | 🎨 视觉层 | TransformControlsGizmo | 构建手柄几何体、每帧更新可见性/缩放/高亮 | | Visual | | Geometry construction, per-frame visibility/scale/highlight | | 🎯 拾取层 | picker(内嵌于 Gizmo / embedded) | 不可见的大尺寸射线检测体 | | Picker | | Invisible oversized raycasting targets | | 📐 平面层 | TransformControlsPlane | 定义拖拽操作约束平面 | | Plane | | Drag constraint plane | | ⚙️ 逻辑层 | pointerDown/Move/Up/Hover | 平移/旋转/缩放的数学计算 | | Logic | | Math for translate/rotate/scale |


🧪 开发

🧪 Development

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

# 安装依赖
# Install dependencies
pnpm install

# 构建
# Build
pnpm build

技术栈

Tech Stack

  • Three.js — 3D 渲染与数学库 / 3D rendering & math
  • TypeScript — 类型安全 / type safety
  • Vite — 构建工具 / build tooling
  • Lit — Web Components 支持(配套面板使用)/ Web Components support (used by companion panel)

📐 几何体尺寸参考

📐 Geometry Size Reference

| 组件 / Component | 视觉尺寸 / Visual Size | 拾取尺寸 / Pick Size | |------|----------|----------| | 平移箭头 | 半径 0.015, 高 0.065 | 半径 0.045, 高 0.065 | | Translate Arrow | radius 0.015, height 0.065 | radius 0.045, height 0.065 | | 平移轴线 | 半径 0.006, 长 0.35 | 半径 0.022, 长 0.35 | | Translate Shaft | radius 0.006, length 0.35 | radius 0.022, length 0.35 | | 旋转环 | 半径 0.20, 管径 0.006, 弧 1.2π | 半径 0.20, 管径 0.035 | | Rotate Ring | radius 0.20, tube 0.006, arc 1.2π | radius 0.20, tube 0.035 | | 缩放方块 | 0.05 × 0.05 × 0.05 | 0.10 × 0.10 × 0.10 | | Scale Handle | 0.05 × 0.05 × 0.05 | 0.10 × 0.10 × 0.10 | | 平面拾取 | — | 0.10 × 0.10 | | Plane Pick | — | 0.10 × 0.10 |

💡 视觉几何体刻意做得比拾取体小,确保点击体验流畅,视觉上精致不累赘。 💡 Visual geometry is intentionally smaller than the pick geometry — smooth clicking, clean visuals.


🗺️ 路线图

🗺️ Roadmap

  • [x] 平移 / 旋转 / 缩放三模式 / Translate, Rotate, Scale modes
  • [x] All 三合一模式 / All 3-in-1 mode
  • [x] World / Local 双空间 / World & Local dual space
  • [x] 吸附系统 / Snap system
  • [x] 缩放灵敏度控制 / Scale sensitivity control
  • [x] 范围限制(Min/Max)/ Range limits
  • [x] 正交相机兼容 / Orthographic camera support
  • [x] 22+ 细粒度事件 / 22+ fine-grained events
  • [x] 自定义配色 / Custom colors
  • [x] 配套 TransformInfoPanel / Companion TransformInfoPanel
  • [ ] 撤销/重做历史栈 / Undo & redo history stack
  • [ ] 多物体同时操控 / Multi-object selection
  • [ ] 网格平面吸附 / Grid plane snapping
  • [ ] 自定义手柄形状 / Custom handle shapes
  • [ ] 触屏手势优化 / Touch gesture optimization

📄 许可证

📄 License

MIT © benxiaokang


  ╔══════════════════════════════════════════════╗
  ║   好的工具,让你忘记它的存在。                 ║
  ║   A good tool makes you forget it's there.   ║
  ╚══════════════════════════════════════════════╝