Vercel の UI SDK 0.1.0-beta.1 上に構築。API は変わる可能性があります。
Image cropper
Vercel の UI SDK 上の画像クロッパー。サイズ変更できる選択範囲、縦横比、丸いアバター枠、ズーム、回転、反転に対応します。
- コンポーネント
- 10 個のパーツ
- 6 個の例
@tabler/icons-react@ui-sdk/core@ui-sdk/reactclass-variance-authority
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-image-cropper.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @ui-sdk/react@0.1.0-beta.1 @ui-sdk/core@0.1.0-beta.1 @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/ui-sdk-image-cropper.tsx components/ui/button.tsx インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
UI SDK は ui-sdk というカスケードレイヤーに少しだけ独自の CSS を追加します。自分のクラスが優先されるよう、グローバルスタイルシートの先頭、Tailwind の import より上でこのレイヤーを宣言してください。
クロップは画像自体のピクセル単位の矩形で、回転と反転を含みます。cropImage に渡すとアップロードできるファイルになります。別サイトの画像には CORS が必要で、ないとブラウザーがピクセルの読み取りを許しません。
mode="frame" では選択範囲が固定され、その下の画像を動かしてズームします。shape="circle" で丸くなるので、cropImage にも shape: "circle" を渡します。
ImageCropperRotate は画像を時計回りに 90 度回転し、ImageCropperFlip は反転します。子を渡さない場合は英語ラベル付きのアイコンボタンです。
ファイル入力の写真をオブジェクト URL でクロップします。新しい写真で最初からやり直せるよう、クロッパーに key を付けます。
onCropCommit はドラッグやキー操作の終了時に実行されるので、そこで保存します。createImageCropperController() のコントローラーでどこからでもクロップを設定できます。
| キー | アクション |
|---|---|
| ←→↑↓ | 選択範囲を動かします。ハンドル上ではその辺を動かします。 |
| Shift← | 10 倍の距離を動かします。 |
| +- | クロップの中心を基準に拡大・縮小します。 |
| R | 画像を時計回りに 90 度回転します。Shift で逆回転します。 |
| Esc | ドラッグ中に、クロップをドラッグ開始時の位置に戻します。 |
クロッパーは aria-label で名前が付くグループです。選択範囲と各ハンドルはクロップを「300 by 300 pixels, at 50, 0」のように言葉で伝えるスライダーで、ズームは「125%」のように倍率を伝えます。これらの名前は英語なので、各パーツにページの言語で aria-label を渡してください。
グリッドはドラッグ中だけ表示され、モーション軽減時は表示されません。タッチ画面ではハンドルの当たり判定が広がり、ドラッグ中にページはスクロールせず、強制カラーモードでは選択範囲にシステム色の枠線が付きます。
各パーツは同名の UI SDK パーツをラップし、render やパーツの状態を受け取る関数にもできる className を含むすべての props を受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
src | string | – |
crop画像ピクセル単位のクロップ。rotation、flipX、flipY を含みます。 | ImageCrop | – |
defaultCrop | ImageCrop | – |
onCropChange | (crop, details) => void | – |
onCropCommitドラッグ、キー操作、ホイールが終わったときに実行されます。 | (crop, details) => void | – |
mode | "box" | "frame" | "box" |
aspectRatio | number | – |
shape | "rectangle" | "circle" | "rectangle" |
minWidth | number | – |
minHeight | number | – |
maxZoom | number | 10 |
disabled | boolean | false |
controllercreateImageCropperController() から作成します。 | ImageCropperController | – |
| 属性 | 説明 |
|---|---|
data-slot="image-cropper" | CSS でクロッパーを指定します。 |
data-mode | box または frame。 |
data-shape | rectangle または circle。 |
data-loading | 画像が読み込まれるまで付きます。 |
data-error | 画像の読み込みに失敗したときに付与されます。 |
data-dragging | ポインターでドラッグ中に付きます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | – |
| 属性 | 説明 |
|---|---|
data-slot="image-cropper-viewport" | CSS でビューポートを指定します。 |
--image-cropper-aspect-ratio | 読み込み後の画像の幅÷高さ。ビューポートはこれを縦横比に使います。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
alt必須。 | string | – |
render | ReactElement | (props, state) => ReactElement | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
aria-label | string | "Crop" |
render | ReactElement | (props, state) => ReactElement | – |
| 属性 | 説明 |
|---|---|
data-slot="image-cropper-selection" | CSS で選択範囲を指定します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
children既定は三分割の線です。 | ReactNode | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
positionサイズを変える辺または角。 | "n" | "e" | "s" | "w" | "ne" | "nw" | "se" | "sw" | – |
ImageCropperHandles は 8 つすべてを描画します。frame モードではハンドルは表示されません。
1(最大のクロップ)から maxZoom までのネイティブの range input。
| プロパティ | 型 | デフォルト |
|---|---|---|
children既定は Rotate というラベルのアイコンです。子を渡すと小さなテキストボタンになります。 | ReactNode | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
direction | "horizontal" | "vertical" | "horizontal" |
children既定は英語ラベル付きのアイコンです。 | ReactNode | – |