A real-time string art generator that converts images into beautiful string art patterns. Built with Rust compiled to WebAssembly for high-performance image processing, and React for an interactive web interface.
- Real-time Generation: Watch string art being created line by line
- WebAssembly Performance: Fast image processing using Rust compiled to WASM
- Interactive UI: Drag & drop image upload with live preview
- Multiple Quality Presets: Fast, Balanced, and High Quality modes
- Real-time Progress: Live updates showing generation progress
- Canvas Visualization: Interactive canvas with string path visualization
- Image Comparison: Toggle between original image and string art result
- Core Algorithm: Greedy string art path generation
- Image Processing: Advanced preprocessing with subject extraction, shadow removal
- WASM Interface: Streaming progress callbacks for real-time updates
- Configuration: Flexible configuration system with presets
- Modern React: TypeScript, Hooks, and functional components
- Real-time Updates: Live canvas updates during generation
- Responsive Design: Mobile-friendly interface
- Progress Tracking: Detailed progress information with completion percentage
- Rust (latest stable)
- Node.js (v20.19.0+ or v22.12.0+)
wasm-pack(install withcargo install wasm-pack)
-
Clone the repository
git clone <your-repo-url> cd StringArt
-
Install React dependencies
cd string-art-demo npm install cd ..
-
Build the WASM package
./build-wasm.sh
-
Start the development server
cd string-art-demo npm run dev -
Open your browser Navigate to
http://localhost:5173
The WASM module is built using wasm-pack with the following command:
cd StringArtRustImpl
wasm-pack build --target web --features wasm --out-dir ../string-art-wasmOr use the provided build script:
./build-wasm.shStringArt/
βββ StringArtRustImpl/ # Rust WASM module
β βββ src/
β β βββ lib.rs # Main library entry point
β β βββ wasm.rs # WASM interface and bindings
β β βββ greedy_generator.rs # Core string art algorithm
β β βββ image_processing.rs # Image preprocessing
β β βββ ...
β βββ Cargo.toml # Rust dependencies
βββ string-art-demo/ # React frontend
β βββ src/
β β βββ App.tsx # Main React component
β β βββ hooks/
β β β βββ useStringArt.ts # WASM integration hook
β β βββ components/
β β βββ ImageUploader.tsx
β β βββ StringArtCanvas.tsx
β βββ package.json # Node.js dependencies
βββ build-wasm.sh # Build script
βββ README.md # This file
The Rust code exposes these main interfaces to JavaScript:
// Main string art generator
#[wasm_bindgen]
pub struct StringArtWasm {
// ... implementation
}
#[wasm_bindgen]
impl StringArtWasm {
#[wasm_bindgen(constructor)]
pub fn new(image_data: &[u8], config: Option<WasmStringArtConfig>) -> Result<StringArtWasm, JsValue>;
pub fn generate_path_streaming(
&mut self,
max_lines: usize,
line_darkness: f64,
min_improvement_score: f64,
progress_callback: &js_sys::Function,
) -> Result<Vec<usize>, JsValue>;
pub fn get_nail_coordinates(&self) -> Vec<JsValue>;
// ... more methods
}interface StringArtConfig {
num_nails: number; // Number of nails around the circle
image_size: number; // Target image size for processing
extract_subject: boolean; // Extract main subject from background
remove_shadows: boolean; // Remove shadows from the image
preserve_eyes: boolean; // Preserve eye details
preserve_negative_space: boolean; // Preserve negative space
negative_space_penalty: number; // Penalty for drawing in negative space
negative_space_threshold: number; // Threshold for negative space detection
}- Fast: 360 nails, basic processing (quick results)
- Balanced: 720 nails, full processing (good quality/speed balance)
- High Quality: 1440 nails, full processing (best quality)
- Upload an Image: Drag and drop or click to select an image file
- Choose Quality: Select from Fast, Balanced, or High Quality presets
- Generate: Click "Generate String Art" to start the process
- Watch Progress: Monitor real-time progress with live canvas updates
- View Results: Toggle between original image and string art result
- Greedy Path Finding: Iteratively selects the next nail that maximizes improvement
- Image Preprocessing: Subject extraction, shadow removal, contrast enhancement
- Real-time Updates: Streaming progress callbacks for live visualization
- WASM Compilation: Rust compiled to WebAssembly for near-native performance
- Streaming Results: Real-time path updates without blocking the UI
- Efficient Canvas: Optimized canvas rendering for smooth animations
- Modern browsers with WebAssembly support
- Chrome, Firefox, Safari, Edge (latest versions)
const {
wasmModule, // Loaded WASM module
isLoading, // Loading state
error, // Error state
generateStringArt, // Function to generate string art
presets, // Configuration presets
} = useStringArt();interface ProgressInfo {
lines_completed: number; // Number of lines completed
total_lines: number; // Total number of lines to generate
pub current_path: number[], //All completed lines till now
score: number; // Current improvement score
completion_percent: number; // Completion percentage (0-100)
path_segment: [number, number]; // Current path segment
}- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by the mathematical beauty of string art
- Built with modern web technologies for educational and artistic purposes
- Thanks to the Rust and WebAssembly communities for excellent tooling
-
WASM Module Not Loading
- Ensure you've built the WASM package:
./build-wasm.sh - Check browser console for CORS or loading errors
- Ensure you've built the WASM package:
-
Build Errors
- Verify Rust and wasm-pack are installed
- Update dependencies:
cargo updateandnpm update
-
Performance Issues
- Try the "Fast" preset for quicker results
- Ensure your browser supports WebAssembly
- Use browser dev tools to monitor WASM module loading
- Check the Network tab for WASM file loading issues
- Use the Console to see progress callback outputs
For questions, issues, or contributions, please open an issue on GitHub or contact the maintainers.
Happy String Art Creating! π¨