先給你們看一下最終效果。css
大多數功能都是由Cropper.js封裝好的,調整並製做了:ios
一開始製做這個需求思路有兩個,使用canvas原生或者尋找現成的庫,對比了一番以爲canvas實現時間耗費較長,且秉承着不重複造輪子的原則(實際上是菜),決定使用Cropper.js。官方封裝了不少參數、方法、事件,上手容易,文檔閱讀體驗較好、並且便於擴展。git
Cropper.js官方倉庫+文檔:github.com/fengyuanche…github
Installationnpm
npm install cropperjs
複製代碼
咱們實現上述功能須要的核心HTMl部分只有:canvas
<!-- 1.一個用於獲取上傳文件的input,type="file",而且監聽onchange事件 -->
<input
type="file"
accept="image/*"
id="imgReader"
onchange="loadingImg"
>
<!-- 2.一個用於給Cropper.js覆蓋使用的img -->
<img id="cropImg">
<!-- 3.兩個用於預覽的div -->
<div class="previewText">裁剪預覽</div>
<div class="previewBox"></div>
<div class="previewBoxRound"></div>
複製代碼
首先先將用於上傳的input隱藏起來,咱們並不須要它的樣式axios
.inpuFile{
display: none;
}
複製代碼
而後給你項目中的某個按鈕添加一個點擊事件,而且調用後端
function uploadImg(){
document.querySelector('#imgReader').click()
},
複製代碼
便可打開上傳文件的窗口,而後選擇你須要的圖片 瀏覽器
上傳文件成功後,會觸發onchange事件,調用loadingImg()bash
//引入Cropper.js
import 'cropperjs/dist/cropper.css';
import Cropper from 'cropperjs';
let CROPPER //建立一個cropper的全局對象
function loadingImg(eve){
//讀取上傳文件
let reader = new FileReader();
if(event.target.files[0]){
//readAsDataURL方法能夠將File對象轉化爲data:URL格式的字符串(base64編碼)
reader.readAsDataURL(eve.target.files[0]);
reader.onload = (e)=>{
let dataURL = reader.result;
//將img的src改成剛上傳的文件的轉換格式
document.querySelector('#cropImg').src = dataURL;
const image = document.getElementById('cropImg');
//建立cropper實例-----------------------------------------
CROPPER = new Cropper(image, {
aspectRatio: 16 / 16,
viewMode:0,
minContainerWidth:500,
minContainerHeight:500,
dragMode:'move',
preview:[ document.querySelector('.previewBox'),
document.querySelector('.previewBoxRound')]
})
}
}
}
複製代碼
new Cropper(element[, options])
第一個參數:element
第二個參數(可選):
咱們須要用到的參數有:
{
aspectRatio: 16 / 16, //固定裁剪框的比例(橫/豎),此處16/16則固定爲正方形
minContainerWidth:500, //容器最小的寬度
minContainerHeight:500, //容器最小的高度
dragMode:'move', //設置裁剪框爲能夠移動
preview:[ document.querySelector('.previewBox'), //設置咱們須要添加實時預覽的地方
document.querySelector('.previewBoxRound')]
//更多參數請參照官方倉庫...咱們這裏用不着
}
複製代碼
先忽略實時預覽,完成到這裏咱們就可看到咱們上傳的圖片以及裁剪功能:
上面建立cropper的時候,咱們在選項中添加了
preview:[ document.querySelector('.previewBox'),
document.querySelector('.previewBoxRound')]
複製代碼
preview就是用來設置咱們須要實時預覽的地方,可是設置完成以後要給上述的兩個div添加一下樣式,才能夠正常顯示
.previewBox,.previewBoxRound{
box-shadow: 0 0 5px #adadad;
width: 100px;
height: 100px;
margin-top: 30px;
overflow: hidden; /*這個超出設置爲隱藏很重要,不然就會整個顯示出來了*/
}
.previewBoxRound{
border-radius: 50%; /*設置爲圓形*/
}
複製代碼
function GetData(){
//getCroppedCanvas方法能夠將裁剪區域的數據轉換成canvas數據
CROPPER.getCroppedCanvas({
maxWidth: 4096,
maxHeight: 4096,
fillColor: '#fff',
imageSmoothingEnabled: true,
imageSmoothingQuality: 'high',
}).toBlob((blob) => {
//而後調用瀏覽器原生的toBlob方法將canvas數據轉換成blob數據
//以後就能夠愉快的將blob數據發送至後端啦,可根據本身狀況進行發送,我這裏用的是axios
const formData = new FormData();
// 第三個參數爲文件名,可選填.
formData.append('croppedImage', blob/*, 'example.png' */);
let config = {
headers:{'Content-Type':'multipart/form-data'}
}
this.$axios.post(flow_mission_UploadFile(),param,config)
.then((response)=>{
console.log(response)
})
.catch((err)=>{
console.log(err)
})
})
}
複製代碼
裁剪部分默認會根據上傳圖片的大小進行改變
//在new Cropper的參數中設置
minContainerWidth:500, //容器最小的寬度
minContainerHeight:500, //容器最小的高度
複製代碼
#cropImg{
height: 450px;
width: 450px;
box-shadow: 0 0 5px #adadad;
}
複製代碼
再次上傳不一樣圖片的時候,仍是出現原來的圖片,只須要在上傳文件的時候,對以前存在的CROPPER進行摧毀就能夠了
function uploadImg(){
document.querySelector('#imgReader').click()
if(CROPPER){
CROPPER.destroy()
}
},
複製代碼
這裏列舉幾個我這裏用到的
還有不少其餘方法和事件能夠自行參照倉庫,一個普通的上傳頭像功能就這樣應該夠用了!這裏就不一一列舉啦
若是以爲寫得有很差的地方請多多指教,喜歡的話能夠點個贊哈!