由于實在太多人遇到了問題, 特意提供了一個小demo供大家參考, demo中分別用React的class component形式和Hooks形式實現(xiàn)了兩個同樣功能的圖片裁剪彈窗. 參考代碼地址: https://github.com/qhwc2009/copper-learn
你可以把demo工程clone下來到本地, 然后執(zhí)行
$ yarn
, 執(zhí)行完畢后再執(zhí)行$ yarn start
啟動項目.
用到的組件
實現(xiàn)圖片裁切并上傳, 本文用到了:
- html input標(biāo)簽的type=file屬性
- react-cropper庫
實現(xiàn)步驟
1. 在外面的view頁面上, 利用input實現(xiàn)上傳的圖片暫存
<label className="add-img-btn">
<span>添加圖片</span>
<input
type="file"
accept="image/jpeg,image/jpg,image/png"
className="base-upload-input"
onChange={this.handleFileChange}
/>
</label>
可以把input 隱藏起來
之后, 把通過input上傳的文件暫存在state中
handleFileChange = (e) => {
const file = e.target.files[0]
if (file) {
if (file.size <= MAX_FILE_SIZE) {
this.setState({
selectedImageFile: file,
}, () => {
this.setState({
editImageModalVisible: true,
})
})
} else {
message.error("文件過大")
}
}
e.target.value = ''
}
2. 彈出圖片裁剪的Modal窗口(我把窗口抽離成了一個獨立的組件)
窗口可以自己寫, 這里貼出核心代碼
這里使用了react-cropper庫
彈出彈框來,之后
首先, 要把上一個步驟中儲存在state中的文件轉(zhuǎn)化成能讀取的URL
通過this.props.uploadedImageFile
屬性把之前存的圖片傳進來, 讀取, 讀取完畢設(shè)置上src, 給下一步用
componentDidMount() {
const fileReader = new FileReader()
fileReader.onload = (e) => {
const dataURL = e.target.result
this.setState({src: dataURL})
}
fileReader.readAsDataURL(this.props.uploadedImageFile)
}
接下來是圖片圖調(diào)用代碼
這里要使用上面讀取的src
<Cropper
src={this.state.src}
className="company-logo-cropper"
ref={cropper => this.cropper = cropper}
// Cropper.js options
viewMode={1}
zoomable={false}
aspectRatio={1} // 這個是設(shè)置比例的參數(shù) 我這里設(shè)置的1:1
guides={false}
preview='.cropper-preview'
/>
重要的屬性:
- src - 目標(biāo)圖片的url
- 其他的options 可以參考這里 (react版與jQuery版options是相通的)
- cropper-preview 這里指定類名為cropper-preview的div作為預(yù)覽的窗口
3. 提交裁剪好的圖片
handleSubmit = () => {
if (!this.state.submitting) {
let url = `/homepage_images`
// 拿到文件名
let filename = this.props.uploadedImageFile.name
message.info("正在上傳圖片")
// TODO: 這里可以嘗試修改上傳圖片的尺寸
this.cropper.getCroppedCanvas().toBlob(async blob => {
// 創(chuàng)造提交表單數(shù)據(jù)對象
const formData = new FormData()
// 添加要上傳的文件
formData.append('file', blob, filename)
// 提示開始上傳
this.setState({submitting: true})
// 上傳圖片
const resp = await http.post(url, formData)
// 拿到服務(wù)器返回的數(shù)據(jù)
this.props.onUploadedFile(resp.data.data)
// 提示上傳完畢
this.setState({submitting: false})
// 關(guān)閉彈窗
this.props.onClose()
})
}
}
-
實現(xiàn)效果
實現(xiàn)效果圖