當下我們項目中需要一個可自由編輯圖片的功能,當圖片可能出現需要頻繁編輯,同時能滿足發現裁剪不滿意想要微調的時候,會發現如果我們處理圖片按照平常的習慣,如裁剪后上傳服務器或者轉base64,都是不符合需求的。那么該怎么處理比較好呢?如何以盡量少的網絡請求、少占用存儲來解決應用場景呢?那么,便想到了只用純數據來跟我們的功能打交道。
先安利個裁圖神器cropperjs,個人認為是個易上手,配置和api方法蠻齊全的一個組件庫。
項目內引入,一定不要漏了引用樣式
import Cropper from 'cropperjs';import 'cropperjs/dist/cropper.css';
這里我們以react為例
this.state = {width: 640, //圖片展示寬height: 360, //圖片展示高 imgWidth: 640, //圖片實際寬imgHeight: 360, //圖片實際高imgLeft: 0, //圖片左偏移imgTop: 0, //圖片上偏移editing: false //是否編輯中}//展示圖片的基本dom結構,我們使用外div內img的形式,來跟數據結合控制裁剪圖片的展示const { width, height, imgWidth, imgHeight, imgLeft, imgTop, editing } = this.state;const containerStyle = {width: `${width}px`,height: `${height}px`}const imgStyle = {width: `${imgWidth}px`,height: `${imgHeight}px`,left: `${imgLeft}px`,top: `${imgTop}px`}.img-container {overflow: hidden;position: relative;}.crop-img {position: absolute;left: 0;top: 0;}<div className="img-container" style={containerStyle}><img className="crop-img"src={picture} style={imgStyle} height="707" src="https://files.vevb.com/file_images/article/201906/2019621105324051.jpg?201952110543" style="border: 1px solid rgb(204, 204, 204); vertical-align: middle; padding: 1px; overflow: hidden; max-width: 696px; width: 650px; height: auto;" width="1271" />所以在這里,為了圖片編輯的自由度,建議分開展示dom與用以初始化cropper對象的dom,在這里編輯區域為全屏幕為例,根據項目實際功能區域進行調整
.edit-container {position: absolute;left: 0;right: 0;top: 0;bottom: 0;}<div className="img-container" style={containerStyle}><img className="crop-img"src={picture} style={imgStyle} height="707" src="https://files.vevb.com/file_images/article/201906/2019621105324052.jpg?201952110548" style="border: 1px solid rgb(204, 204, 204); vertical-align: middle; padding: 1px; overflow: hidden; max-width: 696px; width: 650px; height: auto;" width="800" />
重點介紹下我們用到的兩個api方法getCropBoxData和getCanvasData,getCanvasData是用來獲取圖片的實際數據的(當前的寬高,和相對于父元素可視區域的位移偏移量),getCropBoxData則是獲取相對于圖片區域的裁剪區相關數據。
那么后續的需求接著來了,我們怎么做到二次編輯的時候,能還原效果呢,嗯,其實在前面我們記錄裁圖數據的時候,把相應的數據關系再計算一遍就好了,在初始化cropper的options中增加配置
const options = {dragMode: 'move',background: false,//控件初始化后重置相應配置ready: () => {const { width, height, imgWidth, imgHeight, imgLeft, imgTop } = this.state;//根據實際需要出現裁圖功能進行定位,此處left和top僅為測試暫時默認值定義const left = 50; const top = 50;this.myCropper.setCanvasData({width: imgWidth,height: imgHeight,left: left,top: top});this.myCropper.setCropBoxData({left: left - imgLeft,top: top - imgTop,width: width,height: height})}}this.myCropper = new Cropper(this.myRef.current, options);這時候我們再點擊裁圖,就完美還原了,左邊和上邊的間隙就是setCanvasData的top和left,根據實際項目進行調整,setCropBoxData的left和top是相對于cropper-canvas的定位,才有了以上的計算形式。
此時,基本功能到此結束,如果說是應用在h5編輯中,設計到scale縮放的話,相關的數據計算都要算上scale的縮放值哦,不然就會出現展示圖片和編輯圖片大小不對等的狀況。同時還有許多功能就不做展示了,設置裁剪框比例,編輯縮放等,歡迎嘗試。
當然了,如果想要保存圖片,也有相應的方法到處裁剪圖片的數據
this.myCropper.getCroppedCanvas().toDataURL('image/jpeg')
最后,我們可以看到,在整個功能過程中,我們需要的只是裁剪的數據,讀寫快,也不需要進行額外的圖片存儲,減少文件服務器存儲的開銷與優化。
cropperjs github
感謝大家收看,歡迎討論和指正。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。
注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
新聞熱點
疑難解答