Skip to content

A tiny Rust + WASM library that converts SVG path data to flattened polylines using the Lyon geometry library.

Notifications You must be signed in to change notification settings

PrintApp/SVG-Flatten

Repository files navigation

SVG Flatten

A tiny Rust + WASM library that converts SVG path data to flattened polylines using the Lyon geometry library.

Features

  • 🚀 Fast: Built with Rust and Lyon for optimal performance
  • 🎯 Adaptive flattening: Uses tolerance-based curve approximation (not fixed steps)
  • 📦 Tiny: Optimized WASM binary for minimal size
  • 🔧 Easy integration: Returns points ready for use with libraries like Clipper
  • SVG compatible: Supports most common SVG path commands (M, L, H, V, C, Q, Z)

Building

Prerequisites

  1. Install Rust: https://rustup.rs/
  2. Install wasm-pack: cargo install wasm-pack
  3. (Optional) Install wasm-opt for further optimization: https://github.com/WebAssembly/binaryen

Build Commands

Windows:

build.bat

Unix/Linux/macOS:

chmod +x build.sh
./build.sh

Manual build:

wasm-pack build --target web --out-dir pkg --release

Usage

JavaScript/Browser

<!DOCTYPE html>
<html>
<head>
    <script type="module">
        import init, { flatten_svg_path } from './pkg/svg_flatten.js';

        async function run() {
            await init();

            // SVG path data
            const pathData = "M10,10 C20,20 30,20 40,10 L50,5 Z";
            const tolerance = 0.1; // Lower = more points, higher = fewer points

            try {
                const flattened = flatten_svg_path(pathData, tolerance);
                
                // Get points as flat array [x1, y1, x2, y2, ...]
                const points = flattened.get_flat_array();
                console.log('Flattened points:', points);
                
                // Or access individual points
                for (let i = 0; i < flattened.length; i++) {
                    const x = flattened.get_x(i);
                    const y = flattened.get_y(i);
                    console.log(`Point ${i}: (${x}, ${y})`);
                }
                
                flattened.free(); // Clean up memory
            } catch (error) {
                console.error('Error flattening path:', error);
            }
        }

        run();
    </script>
</head>
<body>
    <h1>SVG Flatten Demo</h1>
    <p>Check the console for output</p>
</body>
</html>

Node.js

import init, { flatten_svg_path } from './pkg/svg_flatten.js';

async function example() {
    await init();

    const pathData = "M0,0 Q50,50 100,0";
    const tolerance = 1.0;

    const flattened = flatten_svg_path(pathData, tolerance);
    const points = flattened.get_flat_array();
    
    console.log('Points:', points);
    flattened.free();
}

example();

API Reference

flatten_svg_path(d: string, tolerance: number): FlattenedPath

Flattens an SVG path data string into a polyline.

Parameters:

  • d: SVG path data string (e.g., "M10,10 C20,20 30,20 40,10")
  • tolerance: Flattening tolerance. Lower values = more points, higher precision

Returns: FlattenedPath object

FlattenedPath Methods

  • length: Number of points in the flattened path
  • get_point(index): Get a point at the given index
  • get_x(index) / get_y(index): Get X/Y coordinate at index
  • get_flat_array(): Get all points as [x1, y1, x2, y2, ...] array
  • free(): Clean up memory (important!)

Supported SVG Commands

Command Description Status
M, m Move to
L, l Line to
H, h Horizontal line
V, v Vertical line
C, c Cubic Bézier curve
Q, q Quadratic Bézier curve
Z, z Close path
S, s Smooth cubic Bézier
T, t Smooth quadratic Bézier
A, a Elliptical arc

Tolerance Guidelines

  • 0.01-0.1: High precision, many points (good for small shapes)
  • 0.1-1.0: Medium precision, balanced (good for most use cases)
  • 1.0-5.0: Low precision, few points (good for large shapes or performance)

Integration with Clipper

The flattened points can be directly used with polygon clipping libraries:

// For clipper-lib or similar
const points = flattened.get_flat_array();
const polygonPath = [];
for (let i = 0; i < points.length; i += 2) {
    polygonPath.push({ X: points[i], Y: points[i + 1] });
}

License

MIT License - feel free to use in your projects!

About

A tiny Rust + WASM library that converts SVG path data to flattened polylines using the Lyon geometry library.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published