1小時搞定cropper.js製做頭像/圖片上傳、裁剪、併發送至後端

先給你們看一下最終效果。css

大多數功能都是由Cropper.js封裝好的,調整並製做了:ios

  • 上傳圖片
  • 對圖片的裁剪以及調整(旋轉、縮放)、
  • 實時預覽
  • 將裁剪後的數據保存爲blob發送至後端。

Q1:爲何選擇Cropper.js和如何安裝Cropper.js?

一開始製做這個需求思路有兩個,使用canvas原生或者尋找現成的庫,對比了一番以爲canvas實現時間耗費較長,且秉承着不重複造輪子的原則(實際上是菜),決定使用Cropper.js。官方封裝了不少參數、方法、事件,上手容易,文檔閱讀體驗較好、並且便於擴展。git

Cropper.js官方倉庫+文檔:github.com/fengyuanche…github

Installationnpm

npm install cropperjs
複製代碼

Q2:如何上傳圖片?

咱們實現上述功能須要的核心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()
    },
複製代碼

便可打開上傳文件的窗口,而後選擇你須要的圖片 瀏覽器

Q3:如何將圖片讀取顯示和使用Cropper.js添加裁剪控件?

上傳文件成功後,會觸發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方法:

new Cropper(element[, options])

第一個參數:element

  • 類型:HTMLImageElement 或 HTMLCanvasElement;
  • 做用:用於顯示裁剪功能;

第二個參數(可選):

  • 類型: Object;
  • 做用:用於添加具體參數設置

咱們須要用到的參數有:

{
    aspectRatio: 16 / 16,    //固定裁剪框的比例(橫/豎),此處16/16則固定爲正方形
    minContainerWidth:500,   //容器最小的寬度
    minContainerHeight:500,  //容器最小的高度
    dragMode:'move',         //設置裁剪框爲能夠移動
    preview:[ document.querySelector('.previewBox'),           //設置咱們須要添加實時預覽的地方
            document.querySelector('.previewBoxRound')]
            
    //更多參數請參照官方倉庫...咱們這裏用不着
}
複製代碼

先忽略實時預覽,完成到這裏咱們就可看到咱們上傳的圖片以及裁剪功能:

Q4:如何進行實時預覽?

上面建立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%;     /*設置爲圓形*/     
}
複製代碼

Q5:如何獲取裁剪數據併發送至後端?

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)
                    })
            })
    }
複製代碼

其餘須要注意的地方:

1.裁剪框尺寸問題

裁剪部分默認會根據上傳圖片的大小進行改變

  • 解決圖片太小的問題:
//在new Cropper的參數中設置
    
    minContainerWidth:500,   //容器最小的寬度
    minContainerHeight:500,  //容器最小的高度
複製代碼
  • 解決圖片過大的問題: 給添加固定寬度樣式
#cropImg{
        height: 450px;
        width: 450px;
        box-shadow: 0 0 5px #adadad;
    }
複製代碼

2.重複上傳的問題

再次上傳不一樣圖片的時候,仍是出現原來的圖片,只須要在上傳文件的時候,對以前存在的CROPPER進行摧毀就能夠了

function uploadImg(){
            document.querySelector('#imgReader').click()
            if(CROPPER){
                CROPPER.destroy()
            }
    },
複製代碼

3.其餘功能的實現

這裏列舉幾個我這裏用到的

  • CROPPER.rotate(90) :旋轉圖片,單位爲數字,90爲順時針旋轉90度
  • CROPPER.zoom(0.1) :縮放圖片,單位爲數字,0.1爲在原縮放基礎上增長0.1倍
  • CROPPER.reset() :重置對圖片的全部操做

還有不少其餘方法和事件能夠自行參照倉庫,一個普通的上傳頭像功能就這樣應該夠用了!這裏就不一一列舉啦

若是以爲寫得有很差的地方請多多指教,喜歡的話能夠點個贊哈!

相關文章
相關標籤/搜索