cropBox.jsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import React, {
  2. Component
  3. } from 'react';
  4. import $ from 'jquery';
  5. import Cropper from 'react-cropper';
  6. import 'cropperjs/dist/cropper.css';
  7. import {Button,message} from 'antd';
  8. class CropBox extends Component {
  9. constructor(props) {
  10. super(props);
  11. this.state = {
  12. src: '',
  13. imgName:'',
  14. close: this.props.close ? this.props.close : true,
  15. url: this.props.url ? this.props.url : '',
  16. uploadData: this.props.uploadData ? this.props.uploadData : {},
  17. aspectRatio: this.props.aspectRatio ? this.props.aspectRatio : ''
  18. }
  19. this.onChange = this.onChange.bind(this);
  20. this.cropImage = this.cropImage.bind(this);
  21. this.convertBase64UrlToBlob = this.convertBase64UrlToBlob.bind(this);
  22. this.submitUpload = this.submitUpload.bind(this);
  23. this.closeBox = this.closeBox.bind(this);
  24. }
  25. componentWillReceiveProps(nextProps) {
  26. this.setState({
  27. close: nextProps.close
  28. })
  29. }
  30. onChange(e) {
  31. e.preventDefault();
  32. let files;
  33. if (e.dataTransfer) {
  34. files = e.dataTransfer.files;
  35. } else if (e.target) {
  36. files = e.target.files;
  37. }
  38. let reader = new FileReader();
  39. reader.onload = () => {
  40. this.setState({
  41. src: reader.result
  42. });
  43. };
  44. this.setState({
  45. imgName:files[0].name
  46. })
  47. reader.readAsDataURL(files[0]);
  48. }
  49. cropImage() {
  50. if (typeof this.cropper.getCroppedCanvas() == 'undefined'||this.cropper.getCroppedCanvas()==undefined) {
  51. message.warning('请选择图片!')
  52. return;
  53. }
  54. let img64Data = this.cropper.getCroppedCanvas().toDataURL();
  55. let imgblobDates = this.convertBase64UrlToBlob(img64Data); //二进制文件格式
  56. let imgfileDate = this.dataURLtoFile(img64Data,this.state.imgName); //文件流格式
  57. this.submitUpload(imgfileDate,img64Data);
  58. }
  59. submitUpload(imgBlob,img64Data) {
  60. if(imgBlob.size>(2097152/2)){
  61. message.warning('图片不能超过1M.');
  62. return false;
  63. }
  64. this.props.closeFun(true);
  65. let _this = this,dataList={};
  66. //转换为文件流传输
  67. /* let fd = new FormData();
  68. for(let key in this.state.uploadData) {
  69. fd.append(key, this.state.uploadData[key]);
  70. }
  71. fd.append('file',imgBlob); */
  72. dataList.filename=this.state.imgName;
  73. dataList.sign=this.state.uploadData['sign'];
  74. dataList.picturebase=img64Data.split(',')[1];
  75. $.ajax({
  76. url: this.state.url,
  77. type: 'POST',
  78. dataType: 'json',
  79. // processData: false, // 注意:让jQuery不要处理数据
  80. // contentType: false, // 注意:让jQuery不要设置contentType
  81. data:dataList,
  82. success: function (data) {
  83. if(data.error&&data.error.length>0){
  84. message.error(data.error[0].message);
  85. }else{
  86. if(_this.props.getUrl) {
  87. _this.props.getUrl(data.data);
  88. }
  89. message.success('上传成功');
  90. }
  91. _this.setState({
  92. close: true,
  93. src: ''
  94. })
  95. },
  96. error: function(err) {
  97. message.error(err)
  98. }
  99. });
  100. }
  101. //将base64转换为文件
  102. dataURLtoFile(dataurl, filename) {
  103. var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
  104. bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
  105. while(n--){
  106. u8arr[n] = bstr.charCodeAt(n);
  107. }
  108. return new File([u8arr], filename, {type:mime});
  109. }
  110. //base64转二进制文件格式
  111. convertBase64UrlToBlob(urlData) {
  112. var bytes=window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte
  113. //处理异常,将ascii码小于0的转换为大于0
  114. var ab = new ArrayBuffer(bytes.length);
  115. var ia = new Uint8Array(ab);
  116. for (var i = 0; i < bytes.length; i++) {
  117. ia[i] = bytes.charCodeAt(i);
  118. }
  119. return new Blob( [ab] , {type : 'image/png'});
  120. }
  121. selFile(){
  122. document.querySelector('.crop-input input[type=file]').click();
  123. }
  124. closeBox() {
  125. this.setState({
  126. close: true
  127. })
  128. this.props.closeFun(true)
  129. }
  130. render() {
  131. return (
  132. <div className = "crop-box" style = {this.state.close ? {"display": "none"} : {"display": "block"}}>
  133. <div className="crop-box-bg"></div>
  134. <div className="crop-box-content">
  135. <div className="crop-input">
  136. <Button type="primary" style={{marginTop:10}} onClick={this.selFile.bind(this)}>选择图片</Button>
  137. <input type="file" className="selectFile" onChange={this.onChange} key = {this.state.src}/>
  138. <div className="crop-close" onClick = {this.closeBox}>x</div>
  139. </div>
  140. <div className="crop-area">
  141. <Cropper key = {this.state.src}
  142. style={{ height: 400, width: 400 }}
  143. aspectRatio = {this.state.aspectRatio}
  144. preview = ".img-preview"
  145. guides={true}
  146. src={this.state.src}
  147. ref={cropper => { this.cropper = cropper; }}
  148. />
  149. </div>
  150. <div className="btnGrounpCrop">
  151. <Button type="primary" className = "crop-sure-btn" onClick={this.cropImage}>确认裁剪</Button>
  152. <Button onClick = {this.closeBox}>取消</Button>
  153. </div>
  154. </div>
  155. </div>
  156. );
  157. }
  158. }
  159. export default CropBox;