Giter Club home page Giter Club logo

react-image-crop's People

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

react-image-crop's Issues

Crop disappears after a few seconds

Issue
Crop range disappears roughly 2 seconds following a selection.

Expected Result
Crop range stays until new range generated or user clicks on other element.

Code

<ReactCrop
    crop={{aspect:1}}
    src={this.state.imagePreviewUrl}
    onComplete={(c,p)=>this.cropComplete(c,p)}
    keepSelection
/>

If you need more info I'd be happy to provide a GIF demonstrating this issue.

Calling toDataURL on network image crop

Assuming I will to initialize the cropper with some image URL and I want to be able to edit it (meaning to crop the image and call canvas.toDataURL based on the cropped image). The problem is, I will get

Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

while calling canvas.toDataURL because the server didn't send "Access-Control-Allow-Origin: * response header. In order for the server to send such header I need to load the image with crossOrigin = 'anonymous' attribute set. Would it be OK to make it configurable via props that underlying the (I use '.ReactCrop--image-copy' image to load it onto canvas and get dataURL) has crossOrigin = 'anonymous' attribute set? (I can issue a PR if such change is OK.)

Max height

The responsive aspect of this is great, but I'm not seeing a way to limit height for tall images. Is there an easy path to doing this?

Pixel coords for the image crop

Apparently the additional parameter pixelCrop of onChangeComplete is always undefined.

And also, is there any way to set the crop on pixel units? Instead of converting it from pixel units to percentage every time in order to use it?

Inline Styles

what are your thoughts on using inline styles for this component? any objections if I implement it?

Rotation support

Any plans to add support for rotating the image? Or does anyone have experience rotating the image, while maintaining the proper directionality of the cropper? Basically I'm thinking something along the lines of the following:

  • Strip out EXIF rotation data before onImageLoaded callback is fired
  • Add support for a rotation prop (or potentially crop attribute), which accepts a number of degrees to rotate the image clockwise

I'd like to work on this, but I'd want to find out from the project maintainers if this is potentially out of scope for this project (or impossible, if I'm missing something). Thanks!

EDIT: Realizing that EXIF manipulation is definitely out of scope here. But it would be nice if I could specify a particular CSS transform for how the image is displayed based on a rotation prop.

Circular crop is flaky

Create a ReactCrop with crop.aspect=1 and ellipse=true. Try shrinking and growing the circle. At some point when the circle is small and you're trying to make it larger, it will suddenly invert around its upper handle and/or become very small.

Aspect ratio in Chrome throws console errors

I'm using the latest (1.0.0-rc3) version of react-image-crop with the following crop attributes:

const cropAttributes = {
  width: 100,
  height: 12,
  x: 0,
  y: 0,
  aspect: 1663/200
}

and I'm receiving the following error in the Chrome console:
Error: <polygon> attribute points: Expected number, "0 0, 1 0, 1 NaN, 0 NaN".

Interestingly enough, this error has no effect on the crop. Everything works as expected, the aspect ratio is locked, the height, width, and coordinates are also correct, even with different values.

It seems that the inclusion of aspect in the attributes is the only thing that causes this error. Also, if the aspect is the only attribute specified, no error occurs:

const cropAttributes = {
  aspect: 1663/200
}

I suspect this might be an issue with webkit but I'm not 100% certain.

Cannot pass styles props to images

I am looking to create a cropper which will be able to zoom an image via css while not scaling the selection marque. I would like to be able to pass a property of css styles which will be applied to the image behind the marque. Then, when the image is cropped, it will identify the correct portion of the image to crop and pass the updated pixel values in the callback. On first pass, I thought it may just be a matter of passing a style variable to be applied to the image. However now that I have thought this out, it seems as though the prop would need to be a value which would be included in calculations in the project to both calculate the scaling of the image as well as calculation of pixels based on the scale.

As we would like to use this library in our project, I am going to create a fork and start playing around with how to potentially solve this. It should be able to be done without making a breaking change by adding one or possibly two addition props to the root element allowing for scaling of the background image.

One other consideration would be about how to determine where the image is scaled (anchor).

I'd be curious to hear any thoughts you have on this topic.

How to access the cropped image?

Is there an elegant way to take the cropped state and access the cropped image? I would like to crop the image and submit the cropped image to a server and subsequently send to amazon S3 for storage. How can I access the image after cropping to attach to an ajax request?

Cropping by top corners

Tried that in Chrome. Grabbing the corner and trying to make the crop area smaller, causes moving the whole crop area to some other part of the image. Pretty nasty ;)

License?

Can you please mention License? Is it licensed under MIT?

minHeight and minWidth not working

Hi,

i set the minHeight and minWidth arguments(in percentage) expecting the component to force a minimum crop area but apparently it does nothing. Any suggestions on how to use that?

Setting aspect and just one of width or height won't show crop selection

Hi, I'm not sure if this is by design, but the following example in the readme:

var crop = {
    width: 30,
    aspect: 16/9
}

won't display the crop selection because height is falsy, which sets this.cropInvalid to true.

However, later on in ensureAspectDimensions, since width and aspect are both set, the value for height becomes fixed to something valid anyway, and the same if only height and aspect are set. Because of this, do you think the crop selection should be rechecked for validity after ensureAspectDimensions?

Thanks for your time!

Displaying vertical images

It seems that ReactCrop displays vertical images preserving their original size. Is there a way to fit image inside the parent

?

Right out of the box, Cropper will make any landscape image to be adjusted to cropper's width and height. Basically image dimensions are adjusted so that they fit. Example:

screen shot 2017-04-18 at 2 21 12 pm

Vertical images on the other hand would be shown in their full height.

My image: http://pngimg.com/uploads/tree/tree_PNG230.png

This is how it looks on a screen:
screen shot 2017-04-12 at 1 33 25 pm

Please let me know if I need to provide any other extra information.

Workaround for opacity background around .ReactCrop--crop-selection in IE (11/Edge)

Hi guys!

Here is a quick workaround for making the opacity background around the selection box work in IE.

Just using box shadow you can make the rest of the element have a dark opacity or whatever color you would like. You can check the following example:

.ReactCrop--crop-selection {
  ...
  box-shadow: 0 0 0 9999px rgba(0,0,0,.5);
}

Its up to you to make the decision of either make box shadow work just on IE or remove the background.

When using the box-shadow I suggest that you wrap the image container with a element which have overflow: hidden css rule, to not make the box shadow bleed across all the page.

I have a codepen where i just did a box using the box shadow.

Cheers!

Initial crop props does not seem to work

I initialize the component like this

const cropData = {
  keepSelection: true,
  aspect: 1,
  top: 0,
  left: 0,
  width: 100
};

<ReactCrop src={ src } crop={ cropData } />

However the selection is not visible on the image (the image is well over 600 x 600). And when the user clicks outside a selection, the selection is discarded.

Initial crop selection is lost after focus is changed to another input in case user haven't changed the crop selection

Hello, first of all thank you for very nice library.

I am facing issue with following workflow:

  1. User selects image file from his or her computer to input with file type
  2. Initial image is loaded as blob to react-image-crop, which is rendered only after image is selected
  3. I would like to have only squared images, therefore I am showing crop rectangle right after image is shown with aspect=1
    4a) If user doesn't perform any changes to the cropping area and goes to the next input, initial selection is lost and the whole image is selected. Afterwards it is not longer possible to apply any changes to crop selection
    4b) If user perform changes to the cropping area, final selection persists after moving to the next input. It is also possible to perform new changes. In other words, everything works as expected.

Initial selections works fine:
initial

Initial selection lost and cropping interface doesn't work anymore after moving to the next input:
after

My source code:

import React, { Component, PropTypes } from 'react';
import Crop from 'react-image-crop';

export default class CropWrapper extends Component {
  static propTypes = {
    initialValue: PropTypes.any,
    src: PropTypes.string,
    onChange: PropTypes.func
  }

  componentWillMount() {
    const { x, y, width, height } = this.props.initialValue;

    this.state = { x, y, width, height, aspect: 1 };
  }

  componentDidMount() {
    require('react-image-crop/dist/ReactCrop.css');
  }

  handleCropChange = (crop) => {
//    this.props.onChange(crop);
    this.setState(crop);
  }

  handleCropComplete = (crop) => {
//    this.props.onChange(crop);
    this.setState(crop);
  }

  render() {
    const { x, y, width, height, aspect } = this.state;

    return (
      <Crop
        src={this.props.src}
        crop={{ x, y, width, height, aspect }}
        keepSelection={true}
        onChange={this.handleCropChange}
        onComplete={this.handleCropComplete}
      />
    );
  }
}

It appears RC4 has broken non-ES6 require() calls

I just upgraded to RC4 and noticed when doing require('react-image-crop') I get back an object with a default property, rather than the ReactImageCrop component as I would expect. I think this is the result of using an ES6 export default construct, which unfortunately doesn't transpile well to old-fashioned require() calls.

PS.: Thanks for your great work!

Babel5 Builds break in the latest change.

There is still a lot of us that haven't switched from Babel5 to 6.
The latest commit broke all my builds and I get this error:

ERROR in ./~/react-image-crop/index.js
Module parse failed: /usr/src/app/node_modules/react-image-crop/index.js Line 2: Unexpected token
You may need an appropriate loader to handle this file type.
| //http://stackoverflow.com/a/33683495/414062
| import ReactCrop from './dist/ReactCrop';
| export default ReactCrop;
| 

Please consider doing something like this:

var ReactCrop = require('./dist/ReactCrop');
module.exports = ReactCrop;

I've tested it and can confirm that this works in Babel 5.

Crop lost when parent state changes

I have a ReactCrop component inside of another component within my app, and without fail whenever I change the state of the parent component with setState(), the ReactCrop component seems to reset and lose its crop box. I am not changing any of the props or state related to the ReactCrop component, the state I am changing is completely unrelated. I've tried adding a unique key to the ReactCrop component and it has not helped. Any ideas why this might be?

Overlay in Safari

Hi,

I'm having issues with the crop box not showing on Safari (9.1.2).

Functionality is fine; I can drag and the crop box will appear, but it does not auto appear on loading even though I have defined the crop settings.

No issues on Chrome so it's definitely a Safari issue.

Cropping output does not meet `aspect`

I'm trying to crop a relatively large image 2832 × 1602, and I set the aspect to 1/1. But the pixelCrop I got after cropping is Object {x: 0, y: 0, width: 1600, height: 1602}. Width and height are not consist with the aspect I set.

I checked the ReactCrop source code, seems pixelCrop is calculated from percentage values width and height, and the width and height are wrong as well.

I had to add the code below to make sure the cropping have correct size.

  handleOnChange(crop) {
    const { aspect, width, height } = crop;
    const newCrop = { ...crop };
    // ReactCrop is producing wrong ratio, fix the percentage according to aspect
    if (aspect) {
      // Adjust the smaller one to make sure we have enough size
      const { imageWidth, imageHeight } = this.state;
      if (width < height) {
        const newWidth = height * imageHeight * aspect / imageWidth;
        newCrop.width = newWidth > 100 ? 100 : newWidth;
      } else {
        const newHeight = width * imageWidth / aspect / imageHeight;
        newCrop.height = newHeight > 100 ? 100 : newHeight;
      }
    }
    this.setState({ crop: newCrop });
  }

Crop selection window not sizing with highlighted area vertically

This is an awesome tool. It works really well. However, I am experiencing an issue where when the image is uploaded and the crop selection default is put on top of it, the boundaries of the selection and the highlight do not match up. I also noticed that when you shift the selection vertically, the top attribute changes but it doesn't match the crop selection. This mismatching looks wonky.

crop: {height: 50, width: 50} is what I am setting, although I have tried using aspect and other combinations of the crop props as well.
screen shot 2017-02-14 at 1 47 47 pm
^^ shows the first issue
screen shot 2017-02-14 at 1 48 30 pm
screen shot 2017-02-14 at 1 48 53 pm
^^shows the second issue (top not updating correctly with dotted selection)

@dominictobias any guidance would be appreciated. Thanks for making this lib.

Access-Control-Allow-Origin

Hi,

Sometimes(i can't reproduce it though) i get a CORS exception while loading the image in the canvas, as result the image is rendered(with the crop) in a very small square area.
All the images i use are loaded from a S3 bucket(i already added the CORS configuration to it).

Am i the only one who is having this issue?

Internal element state overrides updating props

My use-case may not be normally covered by react-image-crop, but it seems like a normal workflow. I want to create a crop widget and occasionally update the crop parameters based on saved data on a server. This means I need to set the crop property once, then some time later set it to something else. It appears that the internal crop state is overriding the property at:

 36   getInitialState(props = this.props) {
 37     const crop = assign({}, this.defaultCrop, props.crop, this.state ? this.state.crop : {});
 38
 39     this.cropInvalid = (!crop.width || !crop.height);
 40
 41     return {
 42       crop: crop
 43     };
 44   },

This means that after initially setting crop via props it can't be set again making my use-case not work.

I've created an updated version of the plugin that does not keep crop in internal state. Everything I tested seems to work, but I didn't read all of the code to understand what, if any, feature I might have ruined. I wanted to open this ticket to start a conversation on the topic to see if a PR would be useful or not.

Limit crop container element to max height

I can limit the container div to max-width but no to max-height.
For example if my crop container has to be 300px * 300px, I want to be able to fit the image by its ratio.

How can I manage this?

Fixing the Crop size but allowing the user to position the crop

Hello, I was having a look at this component and I was wondering if it would be possible to fix the size of the crop but allowing the user to position the crop anywhere on the image ? The minHeight and minWidth property allow us to do this in part but the user would still be able to increase the crop.

Will it be possible to achieve this in the current state of the component or would it need additional max height and Width props ?

onCropComplete pixelCrop returns object with `0` values.

I set image url and show ReactCrop component. If user don't change anything and confirm, this.crop will have 0 values, so backend will receive this wrong values.

onImageLoaded = (crop, img, pixelCrop) => {
  console.log('onImageLoaded', pixelCrop); // returns Object {x: 0, y: 0, width: 0, height: 0}
  this.crop = pixelCrop;
}

          <ReactCrop
            src={this.props.user.avatarForCrop}
            crop={this.state.crop}
            onImageLoaded={this.onImageLoaded}
            onComplete={this.onCropComplete}
            minWidth={this.state.crop.width}
            keepSelection
          />

Disabling new drag crops

Wondering if you think it would be suitable to add an option to disable resetting your crop by dragging on an unselected area of the image. Illustrative gif of what I'm talking about:

drag-crop

A couple reasons I would like to disable this:

  1. On mobile it is very easy to "fat finger" trying to drag one of the handles, and start drawing a new crop.
  2. When adding a minWidth/minHeight, the interaction can be very jittery when drawing a new crop. See gif below:

drag-crop-mins3

Glancing through the source, it looks like it would be as simple as adding a conditional here based on a prop: https://github.com/DominicTobias/react-image-crop/blob/master/lib/ReactCrop.jsx. I'd be happy to make that PR if you agree with this.

Thanks for your consideration!

Keeping crop values i.e. top, left, width, height in states?

Hi,

Got the cropping tool working and was able to style it to my needs, but I can't seem to be able and figure out how to grab those % values you set on a div i.e. top, left, width and height and keep them inside the state every time crop is performed. I assume through onChange(crop), but I wanted to ask you if it is possible to see a snippet showing its correct implementation.

Css Animation of crop selection eats a lot of cpu

Hey there,

I noticed (running in chromium on ubuntu) that the 2 ReactCrop instances on my page are eating up around 20% of each of my 4 cpus.

Digging deeper I finally found out that it's the css-animation (marching ants) on the .ReactCrop--crop-selection element that is causing my machine to sweat.

I'm not sure if its an issue with my particular setup or a general issue. Disabling the animation is making fixing the problem for me. I can live without the animation, but am curious to any input on why such a simple animation is using up so much resources.

Thank you for your work, and best wishes,

Andreas

onChange not called when passed updated prop `crop.aspect`

In our application, we allow the user to set an aspect ratio. When we re-render the ImageCrop with the new aspect, the cropped area changes to match the new aspect ratio, but neither the onComplete or onChange callbacks fire (which is fair enough)

At the moment we can access the new crop using a reference to the component via this._imageCropper.state.crop in the aspect setState callback, but it'd be much nicer and less hacky if we had a onAspectRatioChanged or similar callback for when the crop changes due to a new aspect ratio making it invalid, or other prop changes.

We're updating the aspect ratio by doing a this.setState({ aspect: newAspect }) in our component, and passing it down into ReactCrop like this:

<ReactCrop
  ref={ elem => { this._imageCropper = elem } }
  src={ src }
  crop={ {
    ...(meta && meta.crop),
    aspect,
  } }
  onChange={ (crop, pixelCrop) => {
    this.setState({ meta: { crop, pixelCrop } })
  } }
  onComplete={ (crop, pixelCrop) => {
    this.setState({ meta: { crop, pixelCrop } })
  } }
  />

(Idea) Trigger event when image is loaded

Hey @dominictobias,
Sorry to raise an issue but couldn't find another way to submit an idea.
I was wondering if the library should be triggering an event (onLoaded/onComplete) when the image is loaded. The reason when I'm asking is that if the aspect property is passed in, essentially the crop state will change, but it's not reported back to the parent component.
By now I'm avoiding this by doing the calculations myself and triggering the preview component, but it feels wrong since react-image-crop is doing the calculations.
Let me know thoughts

Aspect

The latest changes broke the library.
If an aspect is set just moving the crop area around makes it disappear on mouse up.
Here's a gif explaining the problem.
bug
No errors on the console.
I've found the problem, will open a pull request soon with the fix.

Strange overlay issue

In my app I'm getting an issue when selecting large images, where the crop doesn't match the highlight:

screen shot 2016-02-25 at 14 33 47

I have set:

.ReactCrop--image {
  max-width: 100%;
}

...and have tried all sorts of combinations for crop params. Also, how do I go about selecting the default selected crop to be either 100% of width (if portrait) or 100% of height (if landscape) and keeping the aspect ratio 1/1 (square)?

svg clipPath refuses to repaint in webkit

My fix, hopefully temporary:

  /*
  Fix for webkit not re-rendering svg mask
  */
  componentDidUpdate(){
    var sel = this.imageCopyRef;

    sel.style.display='none';
    sel.offsetHeight; // no need to store this anywhere, the reference is enough
    sel.style.display='block';  
  }

Width does not go up to 100% when using aspect ratio

This is not a huge problem in my case, but it's bugging me =)

When an aspect ratio is set (for example 16/9), the width will not go up to 100% when you maximize the crop area. Instead I get values like 99.999999999... I'm guessing the height has a higher priority in the aspect-ratio-check or something?

How to disable dimension of crop area and make available only dragging?

Hi. Thanks for this repo.
I would like to use reac-image-crop for setting cover image. That means i need fixed crop size in pixel, let's say 500 x 300 px. So, i don't need ability to change crop width or height. User should only have ability to drag pre-defined crop area to capture certain part of image.
How can i achive this? i know there is maxWidth prop, but it use percentage and hence it doesn't allow me to get immutable 500 x 300 crop zone.
Is there any other solution for my case? Thanks!

minWidth and minHeight

Hi, I was trying your awesome component and all seems to work great except the minWidth and minHeight options. Looking at the code I see in ReactCrop.jsx at line 476:

clamp(num, min, max) {
    return Math.min(Math.max(num, min), max);
}

used at line 171 with minWidth option:

newWidth = this.clamp(newWidth, this.props.minWidth || 0, maxWidth);

and at 196 with minHeight:

newHeight = this.clamp(newHeight, this.props.minHeight || 0, maxHeight);

Below, at 245 and 246:

crop.x = this.clamp(newX, 0, 100 - newSize.width);
crop.y = this.clamp(newY, 0, 100 - newSize.height);

It seems to be calculating the cropping area without taking into account the minWidth and minHeight. All next clamp executions also define the min values as 0.
I've tried to change those min parameters with this.props.minWidth || 0, but then I get a weird behaviour (width becomes fixed). Any workaround?

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.