首页 > 语言 > JavaScript > 正文

一个基于react的图片裁剪组件示例

2024-05-06 15:19:55
字体:
来源:转载
供稿:网友

开始

写了一年多vue,感觉碰到了点瓶颈,学习下react找找感觉。刚好最近使用vue写了个基于cropperJS的图片裁剪的组件,便花费了几个晚上的功夫用react再写一遍。代码地址

项目是使用create-react-app来开发的,省去了很多webpack配置的功夫,支持eslint,自动刷新等功能,使用前npm install并npm start即可。推荐同样是新学习react的人也用用看。

项目写的比较简陋,自定义配置比较差,不过也是完成了裁剪图片的基本功能,希望可以帮助到初学react和想了解裁剪图片组件的朋友。

组件的结构是这样的。

<!--Cropper-->   <div>   <ImageUploader handleImgChange={this.handleImgChange} getCropData={this.getCropData}/>    <div className="image-principal">     <img src={this.state.imageValue} alt="" className="img" ref="img" onLoad={this.setSize}/>     <SelectArea ref="selectArea"></SelectArea>    </div>   </div><!--ImageUploader   -->   <form className="image-upload-form" method="post" encType="multipart/form-data" >    <input type="file" name="inputOfFile" ref="imgInput" id="imgInput" onChange={this.props.handleImgChange}/>    <button onClick={this.props.getCropData}>获取裁剪参数</button>   </form><!--SelectArea   -->   <div className="select-area" onMouseDown={ this.dragStart} ref="selectArea" >    <div className="top-resize" onMouseDown={ event => this.resizeStart(event, 'top')}></div>    <div className="right-resize" onMouseDown={ event => this.resizeStart(event, 'right')}></div>    <div className="bottom-resize" onMouseDown={ event => this.resizeStart(event, 'bottom')}></div>    <div className="left-resize" onMouseDown={ event => this.resizeStart(event, 'left')}></div>    <div className="right-bottom-resize" onMouseDown={ event => this.resizeStart(event, 'right')}></div>    <div className="left-top-resize" onMouseDown={ event => this.resizeStart(event, 'left')}></div>   </div>

ImageUploader & Cropper

ImageUploader主要做的就是上传图片,监听了input的change事件,并调用了父组件Cropper的的handleImgChange方法,该方法设置了绑定到img元素的imageValue,会使得img元素出发load事件。

 handleImgChange = e => {  let fileReader = new FileReader()  fileReader.readAsDataURL(e.target.files[0])  fileReader.onload = e => {   this.setState({...this.state, imageValue: e.target.result})  } }

load事件触发了Cropper的setSize方法,该方法可以设置了图片和裁剪选择框的初始位置和大小。目前裁剪选择框是默认设置是大小为图片的80%,中间显示。

 setSize = () => {  let img = this.refs.img  let widthNum = parseInt(this.props.width, 10)  let heightNum = parseInt(this.props.height, 10)  this.setState({   ...this.state,   naturalSize: {    width: img.naturalWidth,    height: img.naturalHeight   }  })  let imgStyle = img.style  imgStyle.height = 'auto'  imgStyle.width = 'auto'  let principalStyle = ReactDOM.findDOMNode(this.refs.selectArea).parentElement.style  const ratio = img.width / img.height  // 设置图片大小、位置  if (img.width > img.height) {   imgStyle.width = principalStyle.width = this.props.width   imgStyle.height = principalStyle.height = widthNum / ratio + 'px'   principalStyle.marginTop = (widthNum - parseInt(principalStyle.height, 10)) / 2 + 'px'   principalStyle.marginLeft = 0  } else {   imgStyle.height = principalStyle.height = this.props.height   imgStyle.width = principalStyle.width = heightNum * ratio + 'px'   principalStyle.marginLeft = (heightNum - parseInt(principalStyle.width, 10)) / 2 + 'px'   principalStyle.marginTop = 0  }  // 设置选择框样式  let selectAreaStyle = ReactDOM.findDOMNode(this.refs.selectArea).style  let principalHeight = parseInt(principalStyle.height, 10)  let principalWidth = parseInt(principalStyle.width, 10)  if (principalWidth > principalHeight) {   selectAreaStyle.top = principalHeight * 0.1 + 'px'   selectAreaStyle.width = selectAreaStyle.height = principalHeight * 0.8 + 'px'   selectAreaStyle.left = (principalWidth - parseInt(selectAreaStyle.width, 10)) / 2 + 'px'  } else {   selectAreaStyle.left = principalWidth * 0.1 + 'px'   selectAreaStyle.width = selectAreaStyle.height = principalWidth * 0.8 + 'px'   selectAreaStyle.top = (principalHeight - parseInt(selectAreaStyle.height, 10)) / 2 + 'px'  } }            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选