This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Two.js is a renderer-agnostic 2D drawing API for modern browsers. It provides a unified interface for creating graphics across multiple rendering contexts: WebGL, Canvas2D, and SVG.
src/two.js- Main Two.js class and entry point that imports all modules- The Two class extends Events and provides factory methods for creating shapes
- Multi-renderer architecture: Canvas, SVG, and WebGL renderers in
src/renderers/ - Scene graph: Hierarchical structure using Groups and Elements
- Automatic renderer selection: Based on domElement type or explicit type specification
Element- Base class for all drawable objectsShape- Extended Element with transformation and stylingGroup- Container for organizing and transforming multiple objectsPath- Complex shapes defined by anchor points and curvesVector- 2D vector mathematicsMatrix- 2D transformation matricesAnchor- Control points for paths with B�zier curve handles
Located in src/shapes/:
- Basic shapes: Rectangle, Circle, Ellipse, Line, Star, Polygon
- Complex shapes: ArcSegment, RoundedRectangle, Points
- All shapes inherit from Path or Shape classes
Located in src/effects/:
- Gradients: LinearGradient, RadialGradient with Stop objects
- Images: Texture, Sprite, ImageSequence for bitmap rendering
- All effects can be applied as fill or stroke to shapes
npm run build- Build all versions (UMD, ESM, minified) using esbuildnpm run dev- Development server with esbuild on port 8080npm run lint- ESLint with auto-fixnpm run docs:generate- Generate documentation from JSDoc commentsnpm run docs:dev- Local documentation server with Vuepressnpm run docs:build- Build static documentation site
- Build script:
utils/build.js - Uses esbuild for fast bundling and minification
- Outputs:
build/two.js(UMD),build/two.module.js(ESM),build/two.min.js(minified) - Includes license header and module.exports compatibility
The Two class provides factory methods for creating and adding objects to the scene:
makeRectangle(),makeCircle(),makeText(), etc.- All factory methods automatically add objects to the scene
- Return the created object for further manipulation
- All objects inherit from Events class
- Common events: update, render, resize, play, pause
- Use
bind(),unbind(),trigger()for event handling
- Origin (0,0) at top-left by default
- Positive Y axis points down
- Transformations applied via translation, rotation, scale properties
- Use
release()method to unbind events and free memory - Automatically handles nested objects, vertices, and effects
- Important for preventing memory leaks in long-running applications
- Tests located in
tests/directory - Test suites in
tests/suite/organized by functionality - HTML test runners:
tests/index.html,tests/noWebGL.html - TypeScript compilation tests in
tests/typescript/withindex.tsthat imports and uses Two.js API
- Manual browser testing via HTML files:
tests/index.htmlandtests/noWebGL.html - TypeScript compilation testing:
npx tsc --noEmit --skipLibCheck tests/typescript/index.tsto verify types work correctly
src/two.js- Main class with factory methods and core logicsrc/constants.js- Global constants, types, and configurationsrc/utils/interpret-svg.js- SVG parsing and import functionalityutils/build.js- Build system configurationsrc/**/*.d.ts- TypeScript definitions collocated with source files (e.g.,src/vector.d.tsalongsidesrc/vector.js)src/two.d.ts- Main TypeScript entry point that aggregates all type exports
Production: None (library designed to be dependency-free) Development: esbuild, ESLint, TypeScript, Vuepress for documentation
Designed for modern browsers with ES6+ support. Uses feature detection for renderer capabilities.
- Always run
npm run build && npm run lintbefore committing - Test changes in
tests/index.htmlfor visual verification - Use
npm run devfor development server on port 8080 - Check TypeScript types with
npm run types - Test across all three renderers (Canvas, SVG, WebGL) for compatibility
- Use ES6+ features consistently
- Prefer
constoverletwhere possible - Factory methods should always return the created object
- All classes should extend appropriate base classes (Element, Shape, etc.)
- Use JSDoc comments for public API methods
- Use 2-space indentation for JavaScript files
- Place new components in appropriate src/ subdirectories
- Application runs lots of functions on requestAnimationFrame (or per animation frame) so:
- Reduce the amount of objects and functions created within methods
- Prefer caching variables to the module scope
- Do not use function based iterators (prefer native for loops, etc.)
- All shapes inherit from Path or Shape classes
- Use factory methods (makeRectangle, makeCircle) instead of direct constructors
- Effects (gradients, textures) are applied via fill/stroke properties
- Memory management: always call release() for complex objects
- Event binding: use bind/unbind pattern, avoid anonymous functions
- Factory methods automatically add objects to the scene
- When adding new shapes, ensure they extend the correct base class
- WebGL renderer has different capabilities than Canvas/SVG
- Always test across all three renderers for compatibility
- SVG imports may need manual matrix calculations
- Memory leaks: unbind events in cleanup using release() method
- Coordinate system: origin (0,0) at top-left, positive Y axis points down
- Open
tests/index.htmlin browser for manual testing - Test new features across Canvas, SVG, and WebGL renderers
- Check
tests/noWebGL.htmlfor fallback scenarios - TypeScript compilation tests: Run
npx tsc --noEmit --skipLibCheck tests/typescript/index.tsto verify TypeScript definitions work correctly - Manual browser testing required - no automated test runner
- New shapes go in
src/shapes/and follow existing naming pattern - Effects belong in
src/effects/ - Utilities in
src/utils/should be pure functions - Export new classes in
src/two.jsmain file - TypeScript definitions: Create a
.d.tsfile alongside each source file (e.g.,src/vector.d.tsnext tosrc/vector.js)- Each
.d.tsfile contains adeclare module 'two.js/src/...'block matching the module path - Import statements go at the END of the module declaration
- Main type exports are aggregated in
src/two.d.ts
- Each
- Renderers are in
src/renderers/- modify with caution
- Minimize object creation in animation loops
- Use object pooling for frequently created/destroyed objects
- Batch DOM updates when possible
- Prefer transform operations over position updates
- Use release() method to prevent memory leaks in long-running applications
- Node.js: Requires canvas polyfill for headless rendering
- TypeScript: Import specific modules for tree-shaking
- Bundlers: ESM build recommended for modern bundlers
- Browser: UMD build for direct script inclusion
- All visual tests run in the browser via HTML files
- TypeScript tests verify that the type definitions work correctly by compiling sample code – this is work in progress
- Manual testing approach - no automated test runners or CI integration