-
-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Feature Request: Helper/Gizmo Components for Interactive Transformations
Summary
Add interactive helper/gizmo components similar to React Three Fiber's useHelper API that provide visual bounding boxes and transformation handles for Two.js shapes. This would enable users to easily add drag-to-move, resize handles, and rotation controls to any shape.
Motivation
Inspired by:
- React Three Fiber's Helper/useHelper API
- Two.js bounding box demo
This feature would make it trivial to add transformation controls to shapes, useful for:
- Visual editors and design tools
- Interactive animations with user control
- Educational tools for understanding transformations
- Quick prototyping of interactive graphics
Proposed API
Hook Pattern
const circleRef = useRef<RefCircle>(null);
useHelper(circleRef, BoundingBoxHelper, { color: 'cyan' });
// Conditional rendering
useHelper(isSelected && circleRef, BoundingBoxHelper);Component Pattern
<Circle ref={circleRef} radius={50} x={100} y={100}>
<Helper
type={BoundingBoxHelper}
args={[{ color: 'cyan' }]}
/>
</Circle>Implementation Overview
Phase 1: Core Infrastructure
- Helper types and interfaces - Base helper interface, configuration types, interaction event types
- Event system - Mouse/touch event handling, coordinate transformation (screen → Two.js space), hit detection, drag state management
- useHelper hook - Lifecycle management, automatic updates, conditional rendering support
Phase 2: BoundingBoxHelper
-
Visual elements:
- Bounding box rectangle (stroke only)
- 8 corner/edge resize handles
- Rotation handle above box
- Center point indicator
-
Interactions:
- Drag inside box to translate
- Corner drag to scale (uniform or per-axis)
- Edge drag to scale (single-axis)
- Rotation handle drag to rotate
- Visual feedback on hover
-
Transform calculations:
getBoundingBox(shape)- Get current boundsscreenToTwo(x, y)- Convert mouse coordinatesapplyTranslation(shape, dx, dy)applyScale(shape, sx, sy, origin)applyRotation(shape, angle, pivot)
Phase 3: Helper Component Wrapper
<Helper>component for declarative usage- Context integration for canvas DOM access
- Shared event system across helpers
Phase 4: Advanced Features (Future)
- Multi-selection support
- Snap & grid system
- Keyboard modifiers (Shift, Alt, Ctrl)
- Additional helpers:
OriginHelper- Shows origin with axesVertexHelper- Path vertex editorGroupHelper- Hierarchy visualization
File Structure
lib/
├── helpers/
│ ├── index.ts # Export all helpers
│ ├── types.ts # Helper interfaces & types
│ ├── utils.ts # Shared utilities
│ ├── useHelper.ts # Main hook
│ ├── BoundingBoxHelper.ts # Bounding box implementation
│ └── events/
│ ├── EventManager.ts # Canvas event system
│ ├── DragHandler.ts # Drag interaction
│ ├── RotateHandler.ts # Rotation interaction
│ └── ScaleHandler.ts # Scale interaction
├── Helper.tsx # Component wrapper
└── main.ts # Add helper exports
Key Technical Challenges
-
Event Coordination - Two.js doesn't have built-in shape events
- Solution: Canvas-level event binding + custom hit detection
-
Coordinate Transforms - Screen coords ≠ Two.js world coords
- Solution: Transform utilities accounting for canvas position/size
-
Transform Composition - Shapes have compounding rotation/scale/translation
- Solution: Use Two.js matrix operations in appropriate coordinate spaces
-
React Ref Timing - Refs might not be immediately available
- Solution: Effect-based checks with proper cleanup
Benefits
- ✅ Matches familiar React Three Fiber patterns
- ✅ Extensible architecture for custom helpers
- ✅ Declarative API fits React paradigm
- ✅ Automatic cleanup on unmount
- ✅ Enables rapid prototyping of interactive tools
Timeline Estimate
- MVP (Phases 1-3): ~1 week
- Full Implementation: ~2-3 weeks
Related
This aligns with the roadmap item in CLAUDE.md: "Add helpers (aka gizmos)"
Metadata
Metadata
Assignees
Labels
No labels