# Introduction

> [llms.txt](https://zriz.dev/llms.txt)

zriz is an image cropper for React with a straighten dial, like the crop tool in iOS Photos.

The page at https\://zriz.dev/docs/introduction runs this cropper: a 3:2 photo, the straighten dial with rotate and flip, and open, reset and download in the corners.

## What it does

| Feature | What you get |
| - | - |
| [Straighten](https://zriz.dev/docs/dial.md) | A dial turns the photo up to 45° each way and glides on after a flick. The photo zooms in by the least amount that keeps every corner of the crop filled |
| [Move and zoom](https://zriz.dev/docs/viewport.md) | Drag, pinch, trackpad and wheel. Pull past an edge and the photo stretches, then springs back when you let go |
| [Rotate and flip](https://zriz.dev/docs/buttons.md) | Animated quarter turns and mirroring, and a reset that undoes every change |
| [Aspect ratio](https://zriz.dev/docs/aspect-ratio.md) | Free, the photo's own ratio or any ratio you name, with a portrait and landscape swap |
| [Circle crop](https://zriz.dev/docs/avatar.md) | A round mask for avatars, exported as a PNG with transparent corners |
| [Export](https://zriz.dev/docs/exporting.md) | A file made off the main thread, or a plan your server uses to cut the original with sharp |
| [Accessibility](https://zriz.dev/docs/accessibility.md) | Keys on every control, labels and announcements in your own words, and shorter motion when the system asks |
| [Styling](https://zriz.dev/docs/styling.md) | An optional stylesheet, CSS variables, a data attribute for every state, dark mode and Tailwind |
| [Plain data](https://zriz.dev/docs/value.md) | The crop is a small object you can save, restore, undo or send |
| [Without React](https://zriz.dev/docs/vanilla-js.md) | The same core binds to plain elements, so it runs in any framework |

## Build it from parts

Import the parts as one namespace from `@zriz/react/cropper`, and the hooks from `@zriz/react`. These pages call the parts by their short names, such as `Root`.

Each part renders one outer element, which takes your props, `className` and ref. `Image`, `Mask` and `Area` go inside `Viewport`. The dial, zoom and buttons can sit anywhere inside `Root`, so your layout decides where they go:

```tsx
<Cropper.Root src={photo} onValueCommit={save}>
  <Cropper.Viewport style={{ maxWidth: 400, height: 300 }}>
    <Cropper.Image />
    <Cropper.Mask />
    <Cropper.Area aria-label="Crop area" />
  </Cropper.Viewport>
  <Cropper.DialValue />
  <Cropper.Dial aria-label="Straighten">
    <Cropper.DialTicks />
  </Cropper.Dial>
</Cropper.Root>
```

`onValueCommit` hands you the crop each time a change ends.

The demo above runs this code. It adds handles, a grid, rotate, flip and reset, shows the angle to one decimal and uses the styles from the zriz site.
