This is react-two.js - a React wrapper library for Two.js, providing declarative React components for the Two.js 2D drawing API. It supports SVG, Canvas, and WebGL rendering with a complete React virtual DOM implementation.
- TypeScript - Primary language with strict typing
- React 18.3+ - Peer dependency for component system
- Vite - Development server and build tool
- Two.js - Core graphics library (peer dependency from @jonobr1/two.js#dev)
- ESLint - Code linting with React-specific rules
- Vitest - Next-generation testing framework with React Testing Library
npm run dev # Start Vite dev server on port 3000
npm run build # Build library with TypeScript + Vite
npm run lint # Run ESLint on all files
npm run preview # Preview built library
# Testing Commands
npm test # Run all tests with Vitest
npm run test:watch # Run tests in watch mode
npm run test:ui # Run tests with UI interface
npm run test:coverage # Generate coverage report- Canvas - Main container component (
<Canvas>)- IMPORTANT: Canvas only accepts react-two.js components as children
- DOM elements (
<div>,<span>, etc.) cannot be used inside Canvas - This follows React Three Fiber's strict boundary pattern
- Warnings are issued in development mode for invalid children
- Context System -
useTwo()anduseFrame()hooks - Group - Container for organizing components
- 15+ Shape Components - All Two.js primitives wrapped
lib/
βββ main.ts # Main exports
βββ Provider.tsx # Canvas provider component
βββ Context.ts # React context + hooks
βββ Group.tsx # Group container
βββ [Shape].tsx # Individual shape components
βββ Properties.ts # Shared type definitions
- ES Modules only - Modern format
- TypeScript declarations - Full type support
- External dependencies - React and Two.js as peer deps
- Library entry -
lib/main.ts
Circle- Basic circle with radiusRectangle- Rectangle with width/heightRoundedRectangle- Rectangle with corner radiusEllipse- Oval shape with width/heightLine- Straight line between two pointsPath- Custom path with verticesPoints- Collection of pointsPolygon- Regular polygon with sidesStar- Star shape with inner/outer radiusArcSegment- Arc segment with anglesText- Text rendering component
Sprite- Image sprite componentImageSequence- Animated image sequenceLinearGradient- Linear gradient fillRadialGradient- Radial gradient fillTexture- Texture mapping componentGroup- Container for grouping components
All components support:
- Ref forwarding -
RefShapetypes for imperative access - Two.js properties - fill, stroke, linewidth, etc.
- Transform props - x, y, rotation, scale
- Animation support - via
useFrame()hook
const { width, height, instance } = useTwo();Provides access to Two.js instance and canvas dimensions.
useFrame((elapsed: number) => {
// Animation logic runs on every frame
if (ref.current) {
ref.current.rotation = elapsed * 0.5;
}
});Frame-based animation system for smooth animations.
Each component has a corresponding ref type:
RefCircle,RefRectangle,RefPath, etc.- Provides direct access to underlying Two.js objects
- Enables imperative animations and property access
- Strict type checking enabled
- Interface-based prop definitions
- Generic ref types for components
- Exported type definitions for consumers
interface ShapeProps {
// Two.js properties
fill?: string;
stroke?: string;
// Component-specific props
radius?: number;
// Standard props
x?: number;
y?: number;
}
export const Shape = forwardRef<RefShape, ShapeProps>((props, ref) => {
// Component implementation
});- React hooks rules enabled
- React refresh plugin active
- TypeScript ESLint integration
- Strict linting for consistent code quality
- Use
useFrame()for smooth 60fps animations - Prefer ref-based animations over state updates
- Batch property updates within single frame callback
- Two.js handles efficient canvas/SVG/WebGL rendering
- Group components to minimize scene graph updates
- Use appropriate Two.js rendering type for use case
- Create component file in
lib/directory - Implement React wrapper with forwardRef
- Add to
lib/main.tsexports - Update TypeScript definitions
- Test with example in
src/App.tsx
- Use Vite dev server for interactive testing
- Example implementations in
src/App.tsx - Manual testing with different Two.js renderer types
- TypeScript compilation for type checking
- Vite builds ES modules with bundled dependencies
- Generates TypeScript declaration files
- Outputs to
dist/directory
- Problem: DOM elements inside
<Canvas>cause warnings - Solution: Only use react-two.js components inside Canvas
- Pattern: Place DOM elements outside of Canvas
// β
Correct
<div>
<Canvas>
<Circle radius={50} />
</Canvas>
<div>UI controls here</div>
</div>
// β Incorrect - triggers warning
<Canvas>
<div>This will warn</div>
<Circle radius={50} />
</Canvas>- Ensure React 18.3+ is installed
- Two.js must be from @jonobr1/two.js#dev branch
- Check peer dependency warnings during install
- Use requestAnimationFrame via useFrame() hook
- Avoid frequent React state updates for animations
- Prefer direct Two.js object manipulation via refs
- Check component prop interfaces match Two.js API
- Verify ref types are correctly typed
- Ensure proper generic type usage
- Support for effects
- Make props cascade and updates more discrete
- Add helpers (aka gizmos)
- Vitest - Fast test runner with ES modules support
- React Testing Library - Component testing utilities
- jsdom - Browser environment for testing
- @testing-library/jest-dom - Custom DOM matchers
- Unit tests - Individual component logic and utilities
- Integration tests - Component + Two.js interactions (TODO)
- Visual tests - Canvas rendering verification (TODO)
Component testing requires sophisticated Two.js mocking due to:
- Canvas/SVG/WebGL rendering complexity
- Context provider dependencies (useTwo, useFrame)
- Direct Two.js object manipulation via refs
Basic utility and logic tests are working. Component tests need enhanced mocking strategy.
This library follows React patterns with Two.js integration. When adding features:
- Maintain TypeScript strict mode compliance
- Follow existing component patterns
- Write tests for new functionality
- Test across different Two.js renderer types
- Update documentation and examples
- Ensure proper ref forwarding and type safety