Giter VIP home page Giter VIP logo

react-avatar-editor's Introduction

react-avatar-editor

npm version Downloads Build Status Design

Avatar / profile picture cropping component (like on Facebook). Resize, crop and rotate your uploaded image using a simple and clean user interface.

Features

  • Fully typed, written in TypeScript
  • Provide your own input controls
  • Resize
  • Crop
  • Rotate
  • Rounded or square image result

Install

Just use your favorite package manager to add react-avatar-editor to your project:

yarn add react-avatar-editor

npm i --save react-avatar-editor

pnpm add react-avatar-editor

Usage

import React from 'react'
import AvatarEditor from 'react-avatar-editor'

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

export default MyEditor

Props

Prop Type Description
image String|File The URL of the image to use, or a File (e.g. from a file input).
width Number The total width of the editor.
height Number The total height of the editor.
border Number|Number[] The cropping border. Image will be visible through the border, but cut off in the resulting image. Treated as horizontal and vertical borders when passed an array.
borderRadius Number The cropping area border radius.
color Number[] The color of the cropping border, in the form: [red (0-255), green (0-255), blue (0-255), alpha (0.0-1.0)].
backgroundColor String The background color of the image if it's transparent.
style Object Styles for the canvas element.
scale Number The scale of the image. You can use this to add your own resizing slider.
position Object The x and y co-ordinates (in the range 0 to 1) of the center of the cropping area of the image. Note that if you set this prop, you will need to keep it up to date via onPositionChange in order for panning to continue working.
rotate Number The rotation degree of the image. You can use this to rotate image (e.g 90, 270 degrees).
crossOrigin String The value to use for the crossOrigin property of the image, if loaded from a non-data URL. Valid values are "anonymous" and "use-credentials". See this page for more information.
className String|String[] className property passed to the canvas element
onLoadFailure(event) function Invoked when an image (whether passed by props or dropped) load fails.
onLoadSuccess(imgInfo) function Invoked when an image (whether passed by props or dropped) load succeeds.
onImageReady(event) function Invoked when the image is painted on the canvas the first time.
onMouseUp() function Invoked when the user releases their mouse button after interacting with the editor.
onMouseMove(event) function Invoked when the user hold and moving the image.
onImageChange() function Invoked when the user changed the image. Not invoked on the first render, and invoked multiple times during drag, etc.
onPositionChange() function Invoked when the user pans the editor to change the selected area of the image. Passed a position object in the form { x: 0.5, y: 0.5 } where x and y are the relative x and y coordinates of the center of the selected area.
disableBoundaryChecks Boolean Set to true to allow the image to be moved outside the cropping boundary.
disableHiDPIScaling Boolean Set to true to disable devicePixelRatio based canvas scaling. Can improve performance of very large canvases on mobile devices.

Accessing the resulting image

The resulting image will have the same resolution as the original image, for that you can use getImage, regardless of the editor's size. If you want the image sized in the dimensions of the canvas you can use getImageScaledToCanvas.

import React from 'react'
import AvatarEditor from 'react-avatar-editor'

const MyEditor = () => {
  const editor = useRef(null);

  render() {
    return (
      <div>
        <AvatarEditor
          ref={editor}
          image="http://example.com/initialimage.jpg"
          width={250}
          height={250}
          border={50}
          scale={1.2}
        />
        <button onClick={() => {
          if (this.editor) {
            // This returns a HTMLCanvasElement, it can be made into a data URL or a blob,
            // drawn on another canvas, or added to the DOM.
            const canvas = editor.current.getImage()

            // If you want the image resized to the canvas size (also a HTMLCanvasElement)
            const canvasScaled = editor.current.getImageScaledToCanvas()
          }
        }}>Save</button>
      </div>
    )
  }
}

export default MyEditor

Adding drag and drop

We recommend using react-dropzone. It allows you to add drag and drop support to anything really easy. Here is an example how to use it with react-avatar-editor:

import React, { useState } from 'react'
import AvatarEditor from 'react-avatar-editor'
import Dropzone from 'react-dropzone'

const MyEditor = () => {
  const [image, setImage] = useState('http://example.com/initialimage.jpg')

  return (
    <Dropzone
      onDrop={(dropped) => setImage(dropped[0])}
      noClick
      noKeyboard
      style={{ width: '250px', height: '250px' }}
    >
      {({ getRootProps, getInputProps }) => (
        <div {...getRootProps()}>
          <AvatarEditor width={250} height={250} image={image} />
          <input {...getInputProps()} />
        </div>
      )}
    </Dropzone>
  )
}

Accessing the cropping rectangle

Sometimes you will need to get the cropping rectangle (the coordinates of the area of the image to keep), for example in case you intend to perform the actual cropping server-side.

getCroppingRect() returns an object with four properties: x, y, width and height; all relative to the image size (that is, comprised between 0 and 1). It is a method of AvatarEditor elements, like getImage().

Note that: getImage() returns a canvas element and if you want to use it in src attribute of img, convert it into a blob url.

const getImageUrl = async () => {
  const dataUrl = editor.getImage().toDataURL()
  const res = await fetch(dataUrl)
  const blob = await res.blob()

  return window.URL.createObjectURL(blob)
}

// Usage
const imageURL = await getImageUrl()

<img src={imageURL} ... />

Contributing

For development you can use following build tools:

  • npm run build: Builds the minified dist file: dist/index.js
  • npm run watch: Watches for file changes and builds unminified into: dist/index.js
  • npm run demo:build: Builds the demo based on the dist file dist/index.js
  • npm run demo:watch: Run webpack-dev-server. Check demo website localhost:8080

Kudos

Kudos and thanks to dan-lee for the work & many contributions to this project! Also oyeanuj, mtlewis and hu9o and all other awesome people contributing to this in any way.

react-avatar-editor's People

Contributors

aumayr avatar benwiley4000 avatar chengyin avatar codedmart avatar dan-lee avatar dedadev avatar dev-nima avatar fivenp avatar ggwzrd avatar hu9o avatar jakerichan avatar jyash97 avatar kimon89 avatar kpbp avatar kukagg avatar mahdihadrich avatar mateuszitelli avatar mosch avatar mtlewis avatar nmn avatar oyeanuj avatar pvcresin avatar rdw avatar rkjuve avatar ruipserra avatar shakaman avatar sktt avatar tibotiber avatar vitbokisch avatar yamafaktory avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-avatar-editor's Issues

React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method...

I'm using javascript es5 + react 0.14.0.

I keep getting this warning when I do a simple render for the AvatarEditor component:

"React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of ImageCropper."

My code:

var React = require('react'),
  AvatarEditor = require('react-avatar-editor');

 var ImageCropper = React.createClass({
  render: function() {
    return (
        <AvatarEditor
          image="http://example.com/initialimage.jpg"
          width={250}
          height={250}
          border={50}
          color={[255, 255, 255, 0.6]} // RGBA
          scale={1.2} />
    );
  }
});

module.exports = ImageCropper;

Could anyone tell me what's happening and what I may be doing incorrectly? Really hoping to get started on this :(

Add ability to position (x, y, scale) provided image in editor

Use-case for this would be loading an original image in the editor with previously used crop information.
E.g. a user has uploaded an avatar - and would then like to come back later and edit their crop window, not start from scratch every time.

Not sure if I'm missing the way to do this - but couldn't find a trivial implementation.
Seems like supplying (relative?) x and y props in addition to the current scale prop would be a nice solution.

Thanks

onMouseUp() does not do what it should do ?

The onMouseUp() function should be called whenever the user release the mouse after interacting with the editor, but in (my) practice the function is called after every mouseUp event, anywhere in the window, also outside of the editor. This makes the function unusable for what (I think) it is meant for, namely signaling the caller that the image has changed.
Is there a way to change this behaviour, or is there any other way to get a callback whenever the image has changed?

Add Support For Rotation

Would be great to be able to rotate the image in 90 degree, especially as when using a phone camera the image is rarely the correct way around.

Validate file type?

Is there a way to validate if they are uploading an actual image? I don't want to have to wait till everything reaches the backend to perform the first steps of validation.

Specifiable border color

The color of the translucent border impacts the overall look of the page. It'd be very useful to have the option to change it.

0.4.5 && 0.4.6 broke use in nodejs / iojs for isomorphic app

0.4.5 and 0.4.6 broke use in nodejs / iojs for isomorphic applications:

0.4.5

Error: Cannot find module 'react-draggable'
    at Function.Module._resolveFilename (module.js:322:15)
    at Function.Module._load (module.js:264:25)
    at Module.require (module.js:351:17)
    at require (module.js:370:17)
    at TOUCH (/Users/iam4x/MNW/adserver/react-front/node_modules/react-avatar-editor/index.js:9:52)
    at Object.<anonymous> (/Users/iam4x/MNW/adserver/react-front/node_modules/react-avatar-editor/index.js:14:2)
    at Module._compile (module.js:446:26)
    at Module._extensions..js (module.js:464:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/iam4x/MNW/adserver/react-front/node_modules/babel/lib/babel/api/register/node.js:113:7)
    at Module.load (module.js:341:32)

0.4.6

/Users/iam4x/MNW/adserver/react-front/node_modules/react-avatar-editor/index.js:9
        module.exports = factory(require('react'));
                         ^
ReferenceError: document is not defined
    at /Users/iam4x/MNW/adserver/react-front/node_modules/react-avatar-editor/index.js:15:36
    at TOUCH (/Users/iam4x/MNW/adserver/react-front/node_modules/react-avatar-editor/index.js:9:26)
    at Object.<anonymous> (/Users/iam4x/MNW/adserver/react-front/node_modules/react-avatar-editor/index.js:14:2)
    at Module._compile (module.js:446:26)
    at Module._extensions..js (module.js:464:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/iam4x/MNW/adserver/react-front/node_modules/babel/lib/babel/api/register/node.js:113:7)
    at Module.load (module.js:341:32)
    at Function.Module._load (module.js:296:12)
    at Module.require (module.js:351:17)
    at require (module.js:370:17)

I haven't time right now for debugging, I'll stick with 0.4.2 for now, if someone can look into it!

Support react 0.13

Now that react 0.13 exists it would be great if you could add support for this.

Zoom out issue

Is it possible to zoom out as well?

When we are uploading an image of 1000 x 200 size the width of the image is set to show in the editor. Portion of the image is hidden (height wise). I can only shift the image around but now zoom out.

I wish to zoom out at this point to be able to show the entire height of the picture.

I set the default scale to 5 on a scale of 1 - 10. This did not work either.

Thanks in advance.

Dependencies issue

Hey,

I'm not sure why, but when trying to install the package, I get the following dependencies error:

[vagrant@vagrant-centos65 js]$ npm install --save-dev react-avatar-editor
npm http GET https://registry.npmjs.org/react-avatar-editor
npm http 304 https://registry.npmjs.org/react-avatar-editor
npm ERR! peerinvalid The package react does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants react@^0.12
npm ERR! peerinvalid Peer [email protected] wants react@>=0.12.0
npm ERR! peerinvalid Peer [email protected] wants react@>=0.12.0 <0.14.0
npm ERR! peerinvalid Peer [email protected] wants [email protected]

I have [email protected] installed, so it shouldn't complain because you specified react: ^0.12 as a dependency. I'm not sure what to do here, is there a way to fix this properly?

Note that without react-avatar-editor, everything is installing fine.

Thanks

Add export-scaling factor

As of now the editor is mapped to the actual image that will be exported.

It would great if you could edit the image at a resolution that is different from the image that is exported. This is particularly good for things like editing a cover-image. You don't often want to edit the image at it's full size, but you still want to export the cropped version at a high resolution.

More controllable of border size

Now it only accept single number and the border with always be square, by looking at facebook avatar editor they have different border-width for top and bottom and left & right.

It could be nice if border option can support an array like
border=all
border=[top, right, bottom, left]
border=[vertical, horizontal]

etc

Thanks

Use gulp for building

There are two tasks in the package.json that do not work if you don't have the exact environment running.

These task should get moved to gulp.

Add Bower support

Hello,

Awesome app. Any chance of updating this repo to support bower? Thanks.

How to clear the image?

In my UI I need to be able to clear the image. I tried setting the the image prop to null, but this results in a browser error message:
modules.js?hash=da04394โ€ฆ:51036 Uncaught TypeError: Cannot read property 'match' of null

Setting the image prop to an empty string results in a call to 'onLoadFailure'. Is there something I can do in my 'onLoadFailure' function to clear the image?
Or is there another way to clear the image?

Is `calculatePosition` giving out the right x and y?

I'm running issues with images being rendered out of bound on the y-axis - the image's y origin will be at the bottom border (max y).

After some tracing I think calculatePosition function may be the one that causing the issue. However, since I couldn't figure out what is the intend of the original code, I figured it is better to open an issue instead of the pull request.

I did this change:

diff --git a/index.js b/index.js
index d75e0e2..3ad6739 100644
--- a/index.js
+++ b/index.js
@@ -120,8 +120,8 @@
                 var lastX = this.state.image.x;
                 var lastY = this.state.image.y;

-                var x = Math.round((width  + lastX <= borderX) ? lastX + (borderX - (width  + lastX)) : lastX);
-                var y = Math.round((height + lastY <= borderY) ? lastY + (borderY - (height + lastY)) : lastY);
+                var x = Math.round((height + lastX <= borderX) ? lastX + (borderX - (height + lastX)) : lastX);
+                var y = Math.round((width  + lastY <= borderY) ? lastY + (borderY - (width  + lastY)) : lastY);

                 return {
                     x: x,

and for my use case this did resolve the bug I saw.

I found it strange that while borderX is calculated based on dimensions.height, here calculating x was done with width, instead of height.

Cross-Origin Resource Sharing policy

I'm not able to load any image from external url. I'm getting the following error.

Image from origin 'http://some.url.com/image.path.png' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

Commenting out this line fixed it.

if (!this.isDataURL(imageURL)) imageObj.crossOrigin = 'anonymous';

https://github.com/mosch/react-avatar-editor/blob/master/index.es5.js#L116

Read property is undefined in mobile devices

I am integrating this plugin in mobile devices, while I am touching the image I got this error message in console log:

  • Uncaught TypeError: Cannot read property '0' of undefined, this reference to this code in the plugin
    var mousePositionX = TOUCH ? event.targetTouches[0].pageX : e.clientX;
  • Uncaught TypeError: Cannot read property 'files' of undefined, refer to
    reader.readAsDataURL(e.dataTransfer.files[0]);

Calling plugin:

return (
;
);

Anything wrong?

React.initializeTouchEvents has been removed from React

React.initializeTouchEvents was removed starting with React v0.14. This function is no longer needed in react-avatar-editor; touch support is built into React. Importing react-avatar-editor into my existing React project throws an error.

https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html#breaking-changes

Temporary fix (ES6/JSX syntax):

import Avatar from 'react-avatar-editor/dist/index';
React.initializeTouchEvents = React.initializeTouchEvents ||( () => {} );

react 0.14 support ?

amazing work, but react 0.14.x is not support ...

React.findDOMNode is deprecated. Please use ReactDOM.findDOMNode from require('react-dom') instead.

Can not drag image in Mobile device

If you open react avatar editor in mobile device(or turn on mobile debugging in Chrome), the image is not dragable. Error as: Uncaught TypeError: Cannot read property 'files' of undefinedReact. at line 302

Mouse Drag on a Dell computer with touch screen

Hello there,

Great work !
So, I've an issue on my computer. This one has a touch screen.
The result is that when I plug a mouse I can't move the image inside with the cursor but I notced that I can with the touch screen.

I hope you while understand. Sorry for my english :)

Add automated tests

This projects lacks automated tests.
I would like to help but I'm not familiar with tests. Any pointers are appreciated!

Support for < 1 scale?

Seems to go a lil crazy if you try to set min scale to anything below 1 (if it drops the image size to be smaller than the editor window).

Image format (JPEG)

I think it would be nice to be able to choose the image format: now it is "image/png" even when the source is JPEG, thus the resulting base64 image is big. Is it possible?

Object.assign is not a function

Hi! I tried to use this module in my app and stacked with error in browser console: 'Uncaught TypeError: Object.assign is not a function'

Snippet of your code were error happens
Object.assign(defaultStyle,this.props.style)}

New npm release

There has been some good changes since the last npm release. Can we get a new release on npm please. Thanks!

onUpload never fires

Hello!

I'm playing around with this and it's really nice. There seems to be a bug however as onUpload never fires. I did this

handleUpload: function(){
  console.log( 'upload' );
}
<AvatarEditor
  border={ 0 }
  color={ [ 255, 255, 255, 0.6 ] }
  height={ height }
  image={ this.props.image.uri }
  onUpload={ this.handleUpload }
  scale={ scale }
  width={ width }
/>

but handleUpload never fires.

I've looked through the code and either i'm missing something or you forgot to bind the onUpload method when you added it in 01797ec

I'd write a pull request but for some reason the particular project I'm working on fails to build with browserify when I compile so I can't test it.

But something like this.props.onUpload(e.target.result); on line 314 should work, right?

Zoom in/out not working on IE10&11

After test in some browsers I noticed the only one that is not working is IE (I tried 10 and 11 only).
I was thinking that I could have implemented something wrong but I noticed the same problem in your demo page.

Getting cropping rect information for server-side handling

What public method should I use to get the relative cropping information in case I want to do the actual cropping/resizing server-side?

This would include (x,y) coordinates in the orignal image and the width/height of the cropped rect, being relative to the current scaling.

The initial image size should mimic background-image "cover" instead of "contain"

This is an example:
http://jsfiddle.net/chengyin/Lfdbodtr/2/

When the cropping field isn't a square, interesting things happen. In this case, the image will be contained in the viewport, instead of covering the whole viewport. Without scaling, the image can't even be moved around.

Since the desired function for this component is to crop the image to fill up a certain size, I do not think the behavior here is expected.

Providing dimensions of canvas itself OR Ability to use % in dimensions

As per my understanding, canvas's own width/height are different than its coord system's width/height (or the area of the canvas where image is drawn).
The former is often more comfortably specified in CSS % or em.

If I provide

// What I wish here is to use % for the height/width dimensions of the AvatarEditor
<AvatarEditor
    border={4}
    style={{width: '100%', height: '100%'}}
    image={this.props.img} />

then the image is drawn distorted, as if it was first drawn as a minified version and then stretched off to reach 100% in both dimensions. Ideally, the image should be drawn after the canvas is rendered to the desired style.

Another way to express my wish is to be able to use % in specifying width height of the AvatarEditor, as often that is a simpler way to pass them down as props. For example, I want to use this component as a cover editor, similar to Facebook cover image; I would want to simply use width: 100% there.

I hope my description is clear.

support react 15.x

Hi,

first thanks for this great and easy-to-use avatar editor:)

Is it possible to introduce support for react 15.x?
React already started working on react 16-alpha...

Thanks for a short reply.

LMq

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.