npm package: @onemorestudio/drawing_utils
Description: Drawing utilities for MediaPipe tasks-vision API with normalized coordinates support
Author: One More Studio
Latest version: 1.0.0

# @onemorestudio/drawingutils

Drawing utilities for MediaPipe tasks-vision API with normalized coordinates support.

This package provides a modern, lightweight alternative to the deprecated `@mediapipe/drawing_utils` package, designed specifically for the new `@mediapipe/tasks-vision` API.

## Features

- ✅ **Normalized Coordinates** - Works with MediaPipe's 0-1 coordinate system
- ✅ **Modern API** - Compatible with `@mediapipe/tasks-vision`
- ✅ **Zero Dependencies** - Pure JavaScript, no external dependencies
- ✅ **TypeScript Support** - Full TypeScript definitions included
- ✅ **Multiple Models** - Supports Hand, Pose, and Face landmarks
- ✅ **Lightweight** - Minimal bundle size

## Installation

```bash
npm install @onemorestudio/drawingutils
```

## Usage

### Basic Hand Tracking

```javascript
import { HandLandmarker, FilesetResolver } from "@mediapipe/tasks-vision";
import {
  drawConnectors,
  drawLandmarks,
  HAND_CONNECTIONS,
} from "@onemorestudio/drawingutils";

// Setup MediaPipe
const vision = await FilesetResolver.forVisionTasks("./wasm");
const handLandmarker = await HandLandmarker.createFromOptions(vision, {
  baseOptions: {
    modelAssetPath: "./hand_landmarker.task",
    delegate: "GPU",
  },
  runningMode: "VIDEO",
  numHands: 2,
});

// In your render loop
const results = handLandmarker.detectForVideo(video, timestamp);

if (results.landmarks) {
  results.landmarks.forEach((landmarks) => {
    // Draw hand connections
    drawConnectors(ctx, landmarks, HAND_CONNECTIONS, {
      color: "#00FF00",
      lineWidth: 3,
    });

    // Draw hand landmarks
    drawLandmarks(ctx, landmarks, {
      color: "#FF0000",
      radius: 5,
      lineWidth: 2,
    });
  });
}
```

### Pose Tracking

```javascript
import { PoseLandmarker } from "@mediapipe/tasks-vision";
import {
  drawConnectors,
  drawLandmarks,
  POSE_CONNECTIONS,
} from "@onemorestudio/drawingutils";

// After getting pose results
if (results.landmarks) {
  results.landmarks.forEach((landmarks) => {
    drawConnectors(ctx, landmarks, POSE_CONNECTIONS, {
      color: "#00FFFF",
      lineWidth: 2,
    });

    drawLandmarks(ctx, landmarks, {
      color: "#FF00FF",
      radius: 4,
    });
  });
}
```

## API Reference

### Functions

#### `drawLandmarks(ctx, landmarks, options)`

Draw landmark points on canvas.

**Parameters:**

- `ctx` (CanvasRenderingContext2D) - Canvas 2D context
- `landmarks` (Array) - Array of landmark objects with `x`, `y` properties (normalized 0-1)
- `options` (Object) - Drawing options
  - `color` (string) - Stroke color (default: "#FF0000")
  - `fillColor` (string) - Fill color (default: same as color)
  - `radius` (number) - Circle radius in pixels (default: 5)
  - `lineWidth` (number) - Stroke width (default: 2)

#### `drawConnectors(ctx, landmarks, connections, options)`

Draw connections between landmarks.

**Parameters:**

- `ctx` (CanvasRenderingContext2D) - Canvas 2D context
- `landmarks` (Array) - Array of landmark objects
- `connections` (Array) - Array of `[startIndex, endIndex]` pairs
- `options` (Object) - Drawing options
  - `color` (string) - Line color (default: "#00FF00")
  - `lineWidth` (number) - Line width (default: 2)

#### `drawBoundingBox(ctx, boundingBox, options)`

Draw a bounding box.

**Parameters:**

- `ctx` (CanvasRenderingContext2D) - Canvas 2D context
- `boundingBox` (Object) - Bounding box with normalized coordinates
  - `originX` (number) - X origin (0-1)
  - `originY` (number) - Y origin (0-1)
  - `width` (number) - Width (0-1)
  - `height` (number) - Height (0-1)
- `options` (Object) - Drawing options
  - `color` (string) - Stroke color (default: "#00FF00")
  - `lineWidth` (number) - Line width (default: 2)
  - `fillColor` (string) - Fill color (optional)
  - `fillOpacity` (number) - Fill opacity 0-1 (default: 0.2)

#### `drawLabel(ctx, text, position, options)`

Draw a text label.

**Parameters:**

- `ctx` (CanvasRenderingContext2D) - Canvas 2D context
- `text` (string) - Text to draw
- `position` (Object) - Position with normalized coordinates
  - `x` (number) - X position (0-1)
  - `y` (number) - Y position (0-1)
- `options` (Object) - Drawing options
  - `color` (string) - Text color (default: "#FFFFFF")
  - `font` (string) - Font string (default: "16px Arial")
  - `backgroundColor` (string) - Background color (optional)
  - `padding` (number) - Background padding (default: 4)

### Constants

#### `HAND_CONNECTIONS`

Array of hand landmark connection pairs for the 21-point hand model.

#### `POSE_CONNECTIONS`

Array of pose landmark connection pairs for the 33-point pose model.

#### `FACE_MESH_TESSELATION`

Array of face mesh connection pairs (simplified key contours).

### Utility Functions

#### `normalizedToCanvas(point, canvasWidth, canvasHeight)`

Convert normalized coordinates (0-1) to canvas pixel coordinates.

#### `canvasToNormalized(point, canvasWidth, canvasHeight)`

Convert canvas pixel coordinates to normalized coordinates (0-1).

## Examples

### Custom Styling

```javascript
// Neon style
drawConnectors(ctx, landmarks, HAND_CONNECTIONS, {
  color: "#00FFFF",
  lineWidth: 4,
});

drawLandmarks(ctx, landmarks, {
  color: "#FF00FF",
  fillColor: "#FFFFFF",
  radius: 6,
  lineWidth: 3,
});
```

### With Bounding Box

```javascript
if (results.landmarks && results.worldLandmarks) {
  // Draw bounding box
  const boundingBox = {
    originX: 0.2,
    originY: 0.2,
    width: 0.6,
    height: 0.6,
  };

  drawBoundingBox(ctx, boundingBox, {
    color: "#FFFF00",
    lineWidth: 3,
    fillColor: "#FFFF00",
    fillOpacity: 0.1,
  });
}
```

### With Labels

```javascript
results.landmarks.forEach((landmarks, index) => {
  drawConnectors(ctx, landmarks, HAND_CONNECTIONS);
  drawLandmarks(ctx, landmarks);

  // Add label
  drawLabel(ctx, `Hand ${index + 1}`, landmarks[0], {
    color: "#FFFFFF",
    font: "bold 18px Arial",
    backgroundColor: "#000000",
    padding: 6,
  });
});
```

## Compatibility

- Works with `@mediapipe/tasks-vision` v0.10.0+
- Compatible with all modern browsers supporting Canvas API
- Node.js 14.0.0+

## Migration from @mediapipe/drawing_utils

The API is designed to be similar to the old `@mediapipe/drawing_utils`, but with support for normalized coordinates:

```javascript
// Old (deprecated)
import { drawConnectors, drawLandmarks } from "@mediapipe/drawing_utils";
import { HAND_CONNECTIONS } from "@mediapipe/hands";

// New
import {
  drawConnectors,
  drawLandmarks,
  HAND_CONNECTIONS,
} from "@onemorestudio/drawingutils";
```

The main difference is that this package automatically handles the coordinate conversion from normalized (0-1) to canvas pixels.

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues and questions, please open an issue on [GitHub](https://github.com/onemorestudio/drawingUtils/issues).