返回排行榜

mosch/react-avatar-editor

TypeScriptreact-avatar-editor.launchport.dev

Small avatar & profile picture component. Resize and crop uploaded images using a intuitive user interface.

reactavatarcropjavascriptimageprofile-picture-component
Star 增长趋势
Star
2.5k
Forks
380
周增长
Issues
6
1k2k
2023年1月2024年3月2025年5月2026年7月
制品库npmnpm install react-avatar-editor
README

react-avatar-editor

npm version Downloads

Avatar / profile picture cropping component for React. Resize, crop and rotate your uploaded image using a simple and clean user interface.

Features

  • Fully typed, written in TypeScript
  • Works with React 17, 18, and 19
  • Resize, crop, and rotate
  • Rounded or square crop area
  • Built-in loading indicator
  • useAvatarEditor hook for easy access to the editor API
  • Zero runtime dependencies

Install

npm i react-avatar-editor

Usage

Basic

import AvatarEditor from 'react-avatar-editor'

function MyEditor() {
  return (
    <AvatarEditor
      image="https://example.com/photo.jpg"
      width={250}
      height={250}
      border={50}
      color={[255, 255, 255, 0.6]}
      scale={1.2}
      rotate={0}
    />
  )
}

With useAvatarEditor hook

The useAvatarEditor hook provides a clean API to access the editor's methods without managing refs manually. All methods return null if the editor isn't ready or no image is loaded.

import AvatarEditor, { useAvatarEditor } from 'react-avatar-editor'

function MyEditor() {
  const editor = useAvatarEditor()

  const handleSave = () => {
    const canvas = editor.getImageScaledToCanvas()
    if (canvas) {
      const dataUrl = canvas.toDataURL()
      // upload dataUrl to your server
    }
  }

  return (
    <div>
      <AvatarEditor
        ref={editor.ref}
        image="https://example.com/photo.jpg"
        width={250}
        height={250}
        border={50}
        scale={1.2}
      />
      <button onClick={handleSave}>Save</button>
    </div>
  )
}

Hook methods

Method Returns Description
ref RefObject Pass this to the ref prop of AvatarEditor.
getImage() HTMLCanvasElement | null The cropped image at the original resolution.
getImageScaledToCanvas() HTMLCanvasElement | null The cropped image scaled to the editor dimensions.
getCroppingRect() object | null The crop area as { x, y, width, height } (0–1 range).

With ref (alternative)

If you prefer using refs directly:

import { useRef } from 'react'
import AvatarEditor, { type AvatarEditorRef } from 'react-avatar-editor'

function MyEditor() {
  const editor = useRef<AvatarEditorRef>(null)

  return (
    <div>
      <AvatarEditor
        ref={editor}
        image="https://example.com/photo.jpg"
        width={250}
        height={250}
      />
      <button
        onClick={() => {
          const canvas = editor.current?.getImageScaledToCanvas()
        }}
      >
        Save
      </button>
    </div>
  )
}

With drag and drop

Using react-dropzone:

import AvatarEditor from 'react-avatar-editor'
import Dropzone from 'react-dropzone'

function MyEditor() {
  const [image, setImage] = useState('https://example.com/photo.jpg')

  return (
    <Dropzone onDrop={([file]) => setImage(file)} noClick noKeyboard>
      {({ getRootProps, getInputProps }) => (
        <div {...getRootProps()}>
          <AvatarEditor width={250} height={250} image={image} />
          <input {...getInputProps()} />
        </div>
      )}
    </Dropzone>
  )
}

Animated rotation

The rotate prop can be animated using any animation library. Here's an example with motion:

import { useState } from 'react'
import { useMotionValue, useSpring, useMotionValueEvent } from 'motion/react'
import AvatarEditor from 'react-avatar-editor'

function MyEditor() {
  const [rotate, setRotate] = useState(0)
  const [animatedRotate, setAnimatedRotate] = useState(0)

  const rotateMotion = useMotionValue(0)
  const rotateSpring = useSpring(rotateMotion, { stiffness: 200, damping: 25 })

  useMotionValueEvent(rotateSpring, 'change', (v) => setAnimatedRotate(v))

  if (rotateMotion.get() !== rotate) {
    rotateMotion.set(rotate)
  }

  return (
    <>
      <AvatarEditor
        image="https://example.com/photo.jpg"
        rotate={animatedRotate}
      />
      <button onClick={() => setRotate((r) => r - 90)}>↺</button>
      <button onClick={() => setRotate((r) => r + 90)}>↻</button>
    </>
  )
}

Props

Prop Type Default Description
image string | File The URL or File object of the image to edit.
width number 200 Width of the crop area in pixels.
height number 200 Height of the crop area in pixels.
border number | number[] 25 Border size around the crop area. Use an array [horizontal, vertical] for different values.
borderRadius number 0 Border radius of the crop area. Set to width / 2 for a circle.
color number[] [0, 0, 0, 0.5] RGBA color of the crop mask overlay.
borderColor number[] RGBA color of the 1px border around the crop area. No border if omitted.
backgroundColor string Background color for transparent images (CSS color string).
scale number 1 Zoom level. 1 = fit, > 1 = zoom in, < 1 = zoom out (requires disableBoundaryChecks).
rotate number 0 Rotation in degrees.
position { x, y } Center of the crop area (0–1 range). Set this + onPositionChange for controlled panning.
style CSSProperties Additional CSS styles for the canvas element.
crossOrigin string crossOrigin attribute for the image. Use "anonymous" for CORS images.
showGrid boolean false Show a rule-of-thirds grid overlay.
gridColor string "#666" Color of the grid lines.
disableBoundaryChecks boolean false Allow the image to be moved outside the crop boundary.
disableHiDPIScaling boolean false Disable devicePixelRatio scaling. Can improve performance on mobile.
disableCanvasRotation boolean true When false, the canvas resizes to fit the rotated image.
onLoadStart () => void Called when image loading begins.
onLoadSuccess (image) => void Called when the image loads successfully.
onLoadFailure () => void Called when the image fails to load.
onImageReady () => void Called when the image is first painted on the canvas.
onImageChange () => void Called on every visual change (drag, scale, rotate, etc.).
onMouseUp () => void Called when the user releases the mouse after dragging.
onMouseMove (event) => void Called on every mouse/touch move while dragging.
onPositionChange (position) => void Called when the crop position changes. Receives { x, y }.
onRequestScaleChange (scale) => void Called when the user presses +/- keys to zoom. Receives the requested new scale value.
keyboardStep number 1 Pixels to move per arrow key press. Shift multiplies by 10.

Contributing

pnpm install          # install dependencies
pnpm build            # build the library
pnpm lint             # run oxlint
pnpm fmt              # format with oxfmt
pnpm demo:dev         # run demo at localhost:3000

Kudos

Thanks to all contributors:

dan-lee, mtlewis, jakerichan, hu9o, ggwzrd, nmn, kukagg, benwiley4000, ruipserra, rdw, sktt, RKJuve, tibotiber, aumayr, yamafaktory, codedmart, chengyin, MahdiHadrich, jyash97, fivenp, pvcresin, shakaman, oyeanuj, dev-nima, kpbp, DedaDev, vitbokisch, pekq, MateusZitelli, kimon89, xaviergonz, jbrumwell, luisrudge, bytor99999, Mitelak, sahanDissanayake, sle-c, YacheLee, yogthesharma, taro-shono, tanguyantoine, lulzsun, mloeks, metacortex, exiify, thinhvoxuan, tvankith, yarikgenza, zhipenglin, TheMcMurder, notjosh, xulww, jimniels, jeffkole, deadlyicon, velezjose, lixiaoyan, brigand, florapdx, kuhelbeher, chris-rudmin, bluej100, dehbmarques, kimorq

相关仓库
freeCodeCamp/freeCodeCamp

freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.

TypeScriptnpmBSD 3-Clause "New" or "Revised" Licenselearn-to-codenonprofits
contribute.freecodecamp.org
452.4k45.6k
react/react

The library for web and native user interfaces.

JavaScriptnpmMIT Licensejavascriptreact
react.dev
246.7k51.3k
facebook/react

The library for web and native user interfaces.

JavaScriptnpmMIT Licensejavascriptreact
react.dev
233k47.8k
vercel/next.js

The React Framework

JavaScriptnpmMIT Licensereactserver-rendering
nextjs.org
141.1k31.5k
react/react-native

A framework for building native applications using React

C++MIT Licenseandroidapp-framework
reactnative.dev
126.2k25.2k
facebook/react-native

A framework for building native applications using React

C++MIT Licenseandroidapp-framework
reactnative.dev
120.9k24.5k
shadcn-ui/ui

A set of beautifully-designed, accessible components and a code distribution platform. Works with your favorite frameworks. Open Source. Open Code.

TypeScriptnpmMIT Licensecomponentsnextjs
ui.shadcn.com
119.5k9.5k
justjavac/free-programming-books-zh_CN

:books: 免费的计算机编程类中文书籍,欢迎投稿

GNU General Public License v3.0pythonjavascript
weibo.com/justjavac
117.7k28.2k
nextlevelbuilder/ui-ux-pro-max-skill

An AI SKILL that provide design intelligence for building professional UI/UX multiple platforms

PythonPyPIMIT Licenseai-skillsantigravity
uupm.cc
108.6k11.6k
react/create-react-app

Set up a modern web app by running one command.

JavaScriptnpmMIT Licensereactzero-configuration
create-react-app.dev
103.3k26.9k
facebook/create-react-app

Set up a modern web app by running one command.

JavaScriptnpmMIT Licensereactzero-configuration
create-react-app.dev
103.1k27k
ant-design/ant-design

An enterprise-class UI design language and React UI library

TypeScriptnpmMIT Licensereactui-kit
ant.design
98.8k54.7k