SimpleCrop
:github.com/newbieYoung… 是一個在功能
和交互
上覆刻移動設備原生圖片裁剪功能的 Web 圖片裁剪組件;css
左側是 IOS 系統相冊中原生的圖片裁剪功能,右側爲 SimpleCrop 移動端示例。html
能夠掃描二維碼體驗:git
或者訪問如下連接:github
newbieyoung.github.io/Simple-Crop…web
之因此會作這個項目主要是由於已知的圖片裁剪組件並不能徹底知足本身的要求,好比:canvas
Croppie
:github.com/foliotek/cr…只支持旋轉固定角度。瀏覽器
AlloyCrop
:github.com/AlloyTeam/A…徹底不支持旋轉。bash
所以和目前流行的 Web 圖片裁剪組件相比,其優點在於如下幾點:spa
安裝使用教程能夠點擊連接 github.com/newbieYoung… 查看。3d
要實現任意角度旋轉
、雙指中心縮放
、邊界判斷
、自動吸附
等功能,關鍵點以下:
a1 + a2 + a3 + a4 < 360
b1 + b2 + b3 + b4 = 360
複製代碼
判斷點是否在矩形外能夠經過鏈接矩形四個頂點和判斷點,而後計算四條連線之間的夾角,若是夾角之和小於 360 度,那麼該判斷點在矩形外;反之若是夾角之和等於 360 度,那麼該判斷點在矩形內。
當旋轉裁剪圖片時須要進行適當的放大才能保證裁剪框不超出,這裏就須要計算這個放大倍數。
先讓裁剪圖片不進行放大旋轉,而後判斷裁剪框四個頂點有哪些超出了裁剪圖片,接着根據超出的頂點計算放大倍數,以下:
須要的注意的是上述方法也能夠用來判斷點是否在矩形外,並且這種方法比計算夾角和的方法計算量要少。
另外旋轉圖片除了要進行適當放大,防止裁剪框不超出;在裁剪圖片中心點沒有變更時
還能夠進行適當縮小,去掉多餘空隙;
適當縮小和適當放大的計算方式相似,輔助圖以下:
SimpleCrop 中有大量的位移變換計算,出於方便的考慮我在開發時都默認變換基準點爲圖片中心點,也就是說transform-origin:50% 50%
;可是這樣會對雙指縮放以雙指中心爲基準點的實現帶來必定的困擾;
就縮放變換而言,相同倍數不一樣基準點的區別僅僅在於變換後的位置不同了;所以解決方案也很簡單,求出位移差而後進行縮放變換以後再進行位移變換便可。
在旋轉裁剪圖片時咱們能夠對其進行適當的放大從而保證裁剪框不會超出裁剪圖片;可是在縮小裁剪圖片卻不能這麼作,而應該採用移動裁剪圖片
的方式保證裁剪框不超出裁剪圖片。
移動距離
的計算能夠先得到點到矩形中心的向量,而後計算該向量在矩形邊框上的投影向量,最後能夠用投影向量的長度減去邊框長度的一半獲得。
有些狀況只使用位移變換並不能解決問題,以下:
此時先要把裁剪圖片放大至能徹底包含裁剪框
,而後再進行位移變換。
獲取最終的裁剪圖片須要用到 Canvas 的 drawImage 方法,可是其參數支持有限;
void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
複製代碼
所以裁剪圖片時須要先把圖中xy
座標系轉換爲x1y1
座標系,得到 top、left、width、height 參數後,再執行 drawImage 方法;
這裏須要注意兩個問題:
其一是當咱們把座標系轉換爲 x1y1 時,爲了徹底把裁剪圖片繪製進去,每每會把容器 Canvas 的寬度和高度設置成超過裁剪圖片;可是 Canvas 的尺寸在瀏覽器中是有最大限制的,超出後瀏覽器會報警告canvas area exceeds the maximum limit
並且繪製的結果爲空白;要解決這個問題就要求咱們適當控制容器 Canvas 的寬度和高度,只要保證能徹底包含裁剪框便可;在 SimppleCrop 中會默認等於裁剪圖片的寬度和高度;
其二則是裁剪圖片方向角的問題,在 IOS 中使用系統相機豎着拍照時獲得的照片的方向角元數據是橫着的,在網頁中使用 img 標籤顯示不會有問題,可是當使用 Canvas 繪製時若是不處理一下就不能正常繪製;可使用 Exif.js github.com/exif-js/exi… 獲取圖片元數據,而後借鑑 JavaScript-Load-Image github.com/blueimp/Jav… 中的處理方法便可。
最後上述全部內容都基於須要實時獲取裁剪圖片進行 CSS3 Transform 變換後的新座標,有興趣能夠查看CSS3 2D Transform Matrix。