0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactで画像の切り取り(クロップ) react-image-crop

Posted at

Reactで画像の一部をクロップする機能を実装しました。自分のメモ程度にまとめました。

ライブラリ

実装の都合上react-image-crop の方が合っていたのでこちらを使用しました。他にcrop用のライブラリはあります。
react-easy-crop

実装

ライブラリをインストールします。
npm i react-image-crop --save

インストールするとReactCropタグが使用できます。このタグでcropするためのイメージを囲みます。
ReactCropタグの中に別の要素も配置できるので画像の上にテキストや図形なども配置したい場合は、react-image-crop が合っているかもしれません。

function CropDemo({ src }) {
  const [crop, setCrop] = useState<Crop>()
  return (
    <ReactCrop crop={crop} onChange={c => setCrop(c)}>
      <Image src={src} />
    </ReactCrop>
  )
}

cropの四角の座標、width,heightがcropの値として更新されるようになります。
このようにすることでcropする四角の初期値を設定できます。unitはpxか%で指定できます。

const [crop, setCrop] = useState<Crop>({
  unit: '%',
  x: 25,
  y: 25,
  width: 50,
  height: 50
})

実際はこのようなカスタムフックを作成しました。
スタイルはReactCropタグでstyle属性より指定することもできます。
初期値は%ですが、一度でも操作するとunitの値はpxになります。一度でも操作した場合に保存することができるようにisEnableSaveの条件式を指定しました。

import { useState } from 'react';
import { Crop } from 'react-image-crop';

export const useImageCrop = () => {
  const [crop, setCrop] = useState<Crop>({
    unit: '%',
    x: 50,
    y: 50,
    width: 15,
    height: 15,
  });

  const isEnableSave =
    crop.width > 0 && crop.height > 0 && crop.unit === 'px';
  const cropSelectionElement = document.querySelector(
    '.ReactCrop__crop-selection'
  ) as HTMLElement;
  if (cropSelectionElement) {
    cropSelectionElement.style.border = '2px solid #fff';
    cropSelectionElement.style.opacity = '1';
    cropSelectionElement.style.backgroundImage = 'none';
    cropSelectionElement.style.animation = 'none';
  }
  return {
    crop,
    setCrop,
    isEnableSave
  };
};

keepSelection属性を追加しcropする四角の枠が常に表示され続けるようにしました。これがないと別のところをクリックした場合四角が消えてしまいます。

<ReactCrop 
 crop={crop}
 onChange={(c) => setCrop(c)}
 keepSelection
 minHeight={1}
 minWidth={1}
 style={{
  cursor: 'initial',
 }}
>

画像の拡大縮小や回転してcropすることも可能ですが、座標を取得して何か別の操作をしたい場合などは補正する必要が出てきます。
保存の処理があるなら保存時に補正するか、onChangeで補正した値をsetCrop(c)としてcropを更新していくなどの処理が必要になってくるかもしれません。

まとめ

他にもいろいろな属性が追加できるようです。
割と簡単に実装できました。
こちらでライブラリのdemoが参照できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?