user7025244
user7025244

Reputation:

Rotating image preview with ReactJS

I'm trying to rotate a preview of an image with ReactJS. So I'm first allowing an upload function that renders the preview, and then before the user hits upload I want them to have the option to rotate the image to their liking. This is what I'm using to preview the image:

class ImageUpload extends React.Component {
constructor(props) {
  super(props);
  this.state = {file: '',imagePreviewUrl: ''};
}

_handleImageChange(e) {
  e.preventDefault();

let reader = new FileReader();
let file = e.target.files[0];

reader.onloadend = () => {
  this.setState({
    file: file,
    imagePreviewUrl: reader.result
  });
}

reader.readAsDataURL(file)
}

render() {
let {imagePreviewUrl} = this.state;
let $imagePreview = null;
if (imagePreviewUrl) {
  $imagePreview = (<img src={imagePreviewUrl} />);
} else {
  $imagePreview = (<div className="previewText"></div>);
}

return (
  <div className="previewComponent">
    <form onSubmit={(e)=>this._handleSubmit(e)}>
      <input className="fileInput" 
        type="file" 
        onChange={(e)=>this._handleImageChange(e)} />
      <button className="submitButton" 
        type="submit" 
        onClick={(e)=>this._handleSubmit(e)}>Upload Image</button>
    </form>
    <input type="button" value="< rotate" onClick="" />
    <input type="button" value="rotate >" onClick="" />
    <div className="imgPreview">
      {$imagePreview}
    </div>
  </div>
)
}}

ReactDOM.render(<ImageUpload/>, document.getElementById("mainApp"));

And this is what I was trying to use to rotate the image:

class RotateIMG extends React.Component{
constructor(props){
super(props);
this.state = {
  rotation: 0
}

this.rotate = this.rotate.bind(this);
this.rotateleft = this.rotateleft.bind(this);
}

rotate(){
  let newRotation = this.state.rotation + 90;
  if(newRotation >= 360){
    newRotation =- 360;
  }
    this.setState({
      rotation: newRotation,
    })
  }

  rotateleft(){
    let newRotation = this.state.rotation - 90;
    if(newRotation >= 360){
      newRotation =- 360;
    }
    this.setState({
      rotation: newRotation,
    })
  }

  render(){
    const { rotation } =  this.state;
    return <div><img style={{transform: `rotate(${rotation}deg)`}} src={"//blog-assets.risingstack.com/2016/Jan/react_best_practices-1453211146748.png"} width="600" />
      <input onClick={this.rotateleft} type="button" value="left" />
      <input onClick={this.rotate} type="button" value="right" />
    </div>
  }
}

const element = <RotateIMG /> 

ReactDOM.render(element, document.getElementById('root'));

As far as I can tell both of these seem to work fine on their own, but I have no idea where to start in terms of making them work together, or if that is even possible. Any help would be greatly appreciated!

Upvotes: 2

Views: 4229

Answers (1)

Chase DeAnda
Chase DeAnda

Reputation: 16441

Looks like you are really close! You actually have a good structure setup for conditional rendering in your render method, now instead of returning a div, return the RotateIMG component:

import RotateIMG from './rotateIMG.js';
...
render() {
    const { imagePreviewUrl } = this.state;
    let $imagePreview = null;
    if (imagePreviewUrl) {
      $imagePreview = <RotateIMG src={imagePreviewUrl} />;
    } else {
      $imagePreview = <div className="previewText"></div>;
    }
    ...
}

Then you'll need to tweak your RotateIMG component to make sure it's exported and stop rendering it directly to the root.

export default class RotateIMG extends React.Component{
  ...
  render(){
    const { rotation } =  this.state;
    return <div><img style={{transform: `rotate(${rotation}deg)`}} src={this.props.src} width="600" />
      <input onClick={this.rotateleft} type="button" value="left" />
      <input onClick={this.rotate} type="button" value="right" />
    </div>
  }
}

Remove the following from the RotateIMG component

const element = <RotateIMG /> 

ReactDOM.render(element, document.getElementById('root'));

Upvotes: 2

Related Questions