這篇文章主要介紹了javascript實現自由編輯圖片代碼詳解,在當下的的前端項目中,圖片功能可以說是非常常見的,圖片的展示、圖片的裁剪編輯、圖片的上傳等,那麼我們的項目便來了個需求。,需要的朋友可以參考下
當下我們項目中需要一個可自由編輯圖片的功能,當圖片可能出現需要頻繁編輯,同時能滿足發現裁剪不滿意想要微調的時候,會發現如果我們處理圖片按照平常的習慣,如裁剪後上傳服務器或者轉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} alt="pic" ></img> </div>
簡單來說就是外層元素控制裁剪展示的寬高,同時根據項目需求的元素定位也掛在這,內部img掛載圖片實際大小和偏移。
cropperjs初始化後的元素,是會與初始化對象img處在同一dom層級,也就是說如果我們直接對展示img進行初始化的話,編輯區域展示將會受父元素,如圖,放大圖片時候會不方查看超出部分
所以在這裏,爲了圖片編輯的自由度,建議分開展示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} alt="pic" ></img> </div> //cropper初始化 this.myRef = React.createRef(); this.myCropper = new Cropper(this.myRef.current, options); //options配置 const options = { dragMode: 'move', //使裁剪時圖片可拖動 background: false, //因爲我們現在是全屏可編輯,需要隱藏掉默認的背景 } //當然還有許多常見的配置項,如編輯框尺寸比例等,大家可自行查看api //裁剪保存 save() { const cropBoxData = this.myCropper.getCropBoxData(); //獲取裁剪框數據 const canvasData = this.myCropper.getCanvasData(); //獲取圖片數據 this.setState({ width: cropBoxData.width, height: cropBoxData.height, imgLeft: canvasData.left - cropBoxData.left, imgTop: canvasData.top - cropBoxData.top, imgWidth: canvasData.width, imgHeight: canvasData.height }) }
這樣的話 我們就可以完全在自定義的全屏內編輯,保存效果如下,到這裏我們就完成了第一部分功能,裁剪並保存數據和展示
重點介紹下我們用到的兩個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')
最後,我們可以看到,在整個功能過程中,我們需要的只是裁剪的數據,讀寫快,也不需要進行額外的圖片存儲,減少文件服務器存儲的開銷與優化。
感謝大家收看,歡迎討論和指正。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持神馬文庫。