端開發(fā)過程中相信大家應(yīng)該都遇到過圖片上傳的問題,尤其是遇到千人千圖千種規(guī)格,那最好的解決方法就是在上傳過程中設(shè)定一定規(guī)格的裁剪功能,這樣更能達到預(yù)期的效果。所以今天寫一篇關(guān)于cropper.js圖片裁剪插件的用例。當(dāng)然,今天是基于它的V1版本的v1.5.12做的案例,cropper目前最新的是V2(Beta)版本,后續(xù)也會做一個關(guān)于v2版的用例。
本次的用例主要是用于移動端圖片選擇,以及相機拍照后的圖片選擇裁剪功能。詳細代碼請往下看,具體效果圖請看文章末尾。
首先我們需要知道怎么使用cropperJs(V1),當(dāng)然這也是基礎(chǔ)。
安裝方法有兩種,npm安裝和瀏覽器直接引入方法:
npm install cropper jquery
或者:
<link rel="stylesheet" href="css/cropper.css">
<script src="js/jquery.js"></script>
<script src="js/cropper.js"></script>
// 或者用cdn引入的方法
<link rel="stylesheet" href="https://unpkg.com/cropperjs/dist/cropper.css">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://unpkg.com/cropperjs/dist/cropper.js"></script>
在所有依賴引入后,就可以完全放心地使用它了。它的使用規(guī)則是通過new一個Cropper對象,然后里面可以傳兩個參數(shù)image,options。其中第一個參數(shù)為你要包裝的圖像或畫布元素,第二個參數(shù)為cropper內(nèi)置的一些屬性設(shè)置及方法。
new Cropper(image,options)
下面是完整的移動端裁剪案例源碼:
<div class="upload-box">
<!-- 回顯上傳圖片 -->
<div class="upload-img-box">
<img src="img/2.png" alt="">
</div>
<div class="upload-btn">
<button type="button" class="btn-box">相機(圖片)</button>
<input id="select-box" type="file" style="display: none;" />
</div>
</div>
<!-- 裁剪圖片彈窗 -->
<div class="module-cropper" style="display: none;">
<div class="module-cropper-content">
<div class="module-cropper-bg">
<!-- 包裝圖像或畫布元素 -->
<div class="cropper-img-box">
<img id="cropperImg" src="img/1.jpg" />
</div>
</div>
<div class="module-cropper-btn">
<span onclick="cancelCropper()">取消</span>
<span onclick="rotateCropper()">旋轉(zhuǎn)</span>
<span onclick="cropperSucess()">完成</span>
</div>
</div>
</div>
* {
margin: 0;
padding: 0;
}
body {
max-width: 750px;
margin: 0 auto;
}
.upload-box {
width: 100%;
overflow: hidden;
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%,-50%);
}
.upload-img-box {
width: 80%;
margin: 20px auto;
padding: 20px;
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 5px;
}
.upload-img-box img {
width: 100%;
}
.upload-btn {
width: 80%;
margin: 0 auto;
overflow: hidden;
text-align: center;
}
.btn-box {
width: 120px;
background: #2DCEC2;
line-height: 35px;
text-align: center;
color: #fff;
border-radius:5px;
border:none;
outline-style: none;
}
.module-cropper {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0,0,0,.8);
}
#cropperImg {
max-width: 100%;
}
.module-cropper-content {
width: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.module-cropper-bg {
width: 100%;
height: 80vh;
overflow: hidden;
position: relative;
}
.cropper-img-box {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
/* width: 100%; */
}
.module-cropper-btn {
width: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 5vh;
}
.module-cropper-btn span {
color: #fff;
font-size: 13px;
}
const image=document.getElementById('cropperImg');// 包裝圖像或畫布元素
let options={
aspectRatio: 16 / 9, // 裁剪框的寬高比,默認NAN,可以隨意改變裁剪框的寬高比
viewMode:0, // 0,1,2,3
dragMode:'move', // 'crop': 可以產(chǎn)生一個新的裁剪框 'move': 只可以移動 'none': 什么也不處理
// preview:".small", // 添加額外的元素(容器)以供預(yù)覽
responsive:true, //在調(diào)整窗口大小的時候重新渲染cropper,默認為true
restore:true, // 調(diào)整窗口大小后恢復(fù)裁剪的區(qū)域。
checkCrossOrigin:true, //檢查當(dāng)前圖像是否為跨域圖像,默認為true
modal:true, // 顯示圖片上方的黑色模態(tài)并在裁剪框下面,默認為true
guides:false, // 顯示在裁剪框里面的虛線,默認為true
center:true, // 裁剪框在圖片正中心,默認為true
highlight:true, // 在裁剪框上方顯示白色的區(qū)域,默認為true
background:false, // 顯示容器的網(wǎng)格背景(即馬賽克背景),默認為true,若為false,這不顯示
autoCrop:true, // 當(dāng)初始化時,顯示裁剪框,改成false裁剪框消失需要你重繪裁剪區(qū)域,默認為true
autoCropArea:0.8, // 定義自動裁剪面積大小(百分比)和圖片進行對比,默認為0.8
movable:true, // 是否允許可以移動后面的圖片,默認為true(但是如果dragMode為crop,由于和重繪裁剪框沖突,所以移動圖片會失效)
rotatable:true, // 是否允許旋轉(zhuǎn)圖像,默認為true
scalable:true, // 是否允許縮放圖像,默認為true
zoomable:true, // 是否允許放大圖像,默認為true
zoomOnTouch:true, // 是否可以通過拖動觸摸來放大圖像,默認為true
wheelZoomRatio:0.1, // 用鼠標移動圖像時,定義縮放比例,默認0.1
cropBoxMovable:true, // 是否通過拖拽來移動剪裁框,默認為true
cropBoxResizable:true, // 是否通過拖動來調(diào)整剪裁框的大小,默認為true
toggleDragModeOnDblclick:true, // 當(dāng)點擊兩次時可以在“crop”和“move”之間切換拖拽模式,默認為true
crop: function(event) {
}
}
let cropper=new Cropper(image,options); // 初始化cropper對象
// 調(diào)起input(相機圖片)事件
$(".btn-box").click(function(){
$('#select-box').click()
})
// input事件
$('#select-box').on('change',function(e){
let file=e.target.files[0];
let reader=new FileReader();
reader.onload=function(evt) {
let replaceSrc=evt.target.result;
// 更換cropper的圖片
cropper.replace(replaceSrc, false);
}
reader.readAsDataURL(file);
$(".module-cropper").show();
})
// 取消彈窗
function cancelCropper(){
$(".module-cropper").hide();
}
// 旋轉(zhuǎn)圖片
function rotateCropper(){
cropper.rotate(90);
}
// 圖片選擇完成
function cropperSucess(){
let baseSrc=cropper.getCroppedCanvas().toDataURL('image/jpeg', 0.7);
//console.log(baseSrc); // base64格式
$(".module-cropper").hide();
$(".upload-img-box").find("img").attr("src",baseSrc)
}
上面就是完整案例的代碼,效果圖可以看文章末尾。
上面案例中設(shè)置了一些cropper常用的屬性,當(dāng)然它還有很多屬性(類型包括string,Number,String,F(xiàn)unction)等,下面羅列一些內(nèi)置的屬性即屬性值:
aspectRatio: 16 / 9, // 裁剪框的寬高比,默認NAN,可以隨意改變裁剪框的寬高比
viewMode:0, // 0,1,2,3
dragMode:'move', // 'crop': 可以產(chǎn)生一個新的裁剪框 'move': 只可以移動 'none': 什么也不處理
preview:".small", // 添加額外的元素(容器)以供預(yù)覽
responsive:true, //在調(diào)整窗口大小的時候重新渲染cropper,默認為true
restore:true, // 調(diào)整窗口大小后恢復(fù)裁剪的區(qū)域。
checkCrossOrigin:true, //檢查當(dāng)前圖像是否為跨域圖像,默認為true
modal:true, // 顯示圖片上方的黑色模態(tài)并在裁剪框下面,默認為true
guides:false, // 顯示在裁剪框里面的虛線,默認為true
center:true, // 裁剪框在圖片正中心,默認為true
highlight:true, // 在裁剪框上方顯示白色的區(qū)域,默認為true
background:false, // 顯示容器的網(wǎng)格背景(即馬賽克背景),默認為true,若為false,這不顯示
autoCrop:true, // 當(dāng)初始化時,顯示裁剪框,改成false裁剪框消失需要你重繪裁剪區(qū)域,默認為true
autoCropArea:0.8, // 定義自動裁剪面積大小(百分比)和圖片進行對比,默認為0.8
movable:true, // 是否允許可以移動后面的圖片,默認為true(但是如果dragMode為crop,由于和重繪裁剪框沖突,所以移動圖片會失效)
rotatable:true, // 是否允許旋轉(zhuǎn)圖像,默認為true
scalable:true, // 是否允許縮放圖像,默認為true
zoomable:true, // 是否允許放大圖像,默認為true
zoomOnTouch:true, // 是否可以通過拖動觸摸來放大圖像,默認為true
wheelZoomRatio:0.1, // 用鼠標移動圖像時,定義縮放比例,默認0.1
cropBoxMovable:true, // 是否通過拖拽來移動剪裁框,默認為true
cropBoxResizable:true, // 是否通過拖動來調(diào)整剪裁框的大小,默認為true
toggleDragModeOnDblclick:true, // 當(dāng)點擊兩次時可以在“crop”和“move”之間切換拖拽模式,默認為true
minCanvasHeight:0, // canvas的最小高度,默認為0
minCanvasWidth:0, // canvas的最小寬度,默認為0
minContainerHeight:100, // 容器的最小高度,默認為100
minContainerWidth:200, // 容器的最小寬度,默認為200
minCropBoxWidth:0, // 裁剪層的最小寬度,默認為0
minCropBoxHeight:0,// 裁剪層的最小高度,默認為0
options類型為Function的屬性:
ready:function(){}, // 插件準備完成執(zhí)行的函數(shù)(只執(zhí)行一次)
crop:function(){}, // 剪裁框發(fā)生變化執(zhí)行的函數(shù)
zoom:function(){}, // 剪裁框縮放的時候執(zhí)行的函數(shù)
cropstart:function(){}, // 剪裁框開始移動執(zhí)行的函數(shù)
cropmove:function(){}, // 剪裁框移動時執(zhí)行的函數(shù)
cropend:function(){}, //剪裁框移動結(jié)束執(zhí)行的函數(shù)
// 替換圖像的src并重新構(gòu)建cropper,第一個參數(shù)為要替換的新的圖片地址,第二個參數(shù)onlyColorChanged類型為Boolean,默認為false,如果只是改變顏色,而不是大小,那么cropper只需要改變所有相關(guān)圖像的src,不需要重新構(gòu)建cropper。這可以用于應(yīng)用過濾器。
let cropper=new Cropper(image,options);
cropper.replace(replaceSrc, false);
// 手動顯示裁剪框
let cropper=new Cropper(image,options);
cropper.cropper({
autoCrop: false, //關(guān)閉自動顯示裁剪框
ready: function () {
$(this).cropper('crop');
}
});
// 將圖像和裁剪框重置為初始狀態(tài)
let cropper=new Cropper(image,options);
cropper.cropper('reset');
// 清除裁切框
let cropper=new Cropper(image,options);
cropper.clear();
// 銷毀cropper并從圖像中刪除整個cropper
let cropper=new Cropper(image,options);
cropper.cropper('destroy');
// 使用相對偏移量移動圖像(裁切框不移動)
// offsetX–類型:Number;在水平方向上移動(px)
// offsetY –類型:Number;在垂直方向上移動(px);如果不存在,其值和offsetX相同;
let cropper=new Cropper(image,options);
cropper.cropper('move', 1, 0);
// 將畫布(圖像包裝器)移動到一個絕對點
// X–類型:Number;畫布canvas距離left的值;
// Y –類型:Number;畫布canvas距離top的值;如果不存在,其值和X相同;
let cropper=new Cropper(image,options);
cropper.cropper('moveTo', 100, 10);
// 放大圖片,并使用相對比例。(裁切框不變化)
let cropper=new Cropper(image,options);
cropper.cropper('zoom', 0.1);
// 旋轉(zhuǎn)圖像以一定的角度
// 向右旋轉(zhuǎn) (degree > 0);向左旋轉(zhuǎn) (degree < 0);
let cropper=new Cropper(image,options);
cropper.cropper('rotate', 45);
// 輸出最終裁剪的區(qū)域位置和大小數(shù)據(jù)(根據(jù)原始圖像的自然大小
// rounded 類型:Boolean 默認:false;設(shè)置true可以獲取其所有數(shù)據(jù);
// 返回的數(shù)據(jù)類型:Object;
// - x裁切框距離左邊的距離
// - y裁切框距離頂部的距離
// - width裁切框的寬度
// - height裁切框的高度
// - rotate裁切框的旋轉(zhuǎn)的角度
// - scaleX縮放圖像的橫坐標
// - scaleY縮放圖像的縱坐標
let cropper=new Cropper(image,options);
cropper.cropper('getData', true)
// 輸出圖像image位置、大小和其他相關(guān)數(shù)據(jù)
// - leftimage距離左邊的距離
// - topimage距離頂部的距離
// - widthimage的寬度
// - heightimage的高度
// - naturalWidth image的原始寬度
// - naturalHeight image的原始高度
// - aspectRatio image的縱橫比
// - rotateimage的旋轉(zhuǎn)的角度
// - scaleX縮放圖像的橫坐標
// - scaleY縮放圖像的縱坐標
let cropper=new Cropper(image,options);
cropper.cropper('getImageData')
上面是我們應(yīng)該能用到的大部分方法及內(nèi)置屬性了,只能說cropper真的很強大,幾乎包含了我們實際開發(fā)中所需要的內(nèi)容。下面是開頭提到的案例截圖,需要的可以自取源碼。
主頁面,上傳按鈕及裁剪完成后回顯內(nèi)容
裁剪過程彈窗
裁剪完成回顯內(nèi)容
直譯就是剪裁路徑的意思,使用svg或者形狀定義一個html元素的可見區(qū)域的方法。
截圖來自于clip-path在線神器-http://bennettfeely.com/clippy 網(wǎng)站。
使用之前需要注意得幾點
1 使用clip-path要從同一個方向繪制,如果順時針繪制就一律順時針,逆時針就一律逆時針,因為polygon是一個連續(xù)線段,若線段彼此有交集,裁剪區(qū)域就會相減得情況發(fā)生,當(dāng)然如果你特意需要這樣的效果除外
2 如果繪制時采用比例的方式繪制,長寬就必須要先行設(shè)定,不然有可能繪制出來的長寬和我們想象的就會有差距,使用像素繪制就不會有這樣的現(xiàn)象了。
我們看到 我們是從這四個點開始剪裁得分別對應(yīng)的是
x1,y1=50% 0%
x2,y2=0% 50%
x3,y3=50% 100%
x4,y4=100% 50%
這個圖形的css就是clip-path:polygon( 50% 0% , 0% 50% , 50% 100% , 100% 50%)
讓我們看下完整的圖形
當(dāng)然這只是clip-path中多邊形的一種用法,他還包括
inset() -> 矩形
circle() -> 圓形
ellipse() -> 橢圓形
clip-path的作用不僅僅是如我上面介紹的那般簡單,它還有很多奇妙的用處,尤其配合動畫一起使用,感興趣的同學(xué)可以自己慢慢深入。
希望大家可以關(guān)注我,一起探索前端的知識。
ackground-clip 屬性
規(guī)定背景的繪制區(qū)域:
border-box 背景被裁剪到邊框盒。
padding-box 背景被裁剪到內(nèi)邊距框。
content-box 背景被裁剪到內(nèi)容框。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
div{
width: 300px;
height: 300px;
margin: 50px auto;
padding: 50px;
border: 50px solid rgba(255,0,0,0.5);
background-image: url(img/yangmi.jpg);
/*規(guī)定背景的繪制區(qū)域:*/
/*background-clip: border-box;*//*背景會填充到邊框*/
/*background-clip: padding-box;*/
background-clip: content-box;
}
</style>
</head>
<body>
<div>我是文字啊啊啊啊</div>
</body>
</html>
background-size 屬性
background-size: length|percentage|cover|contain;
length 設(shè)置背景圖像的高度和寬度。第一個值設(shè)置寬度,第二個值設(shè)置高度。如果只設(shè)置一個值,則第二個值會被設(shè)置為 "auto"。
percentage 以父元素的百分比來設(shè)置背景圖像的寬度和高度。第一個值設(shè)置寬度,第二個值設(shè)置高度。如果只設(shè)置一個值,則第二個值會被設(shè)置為 "auto"。
cover 把背景圖像擴展至足夠大,以使背景圖像完全覆蓋背景區(qū)域。背景圖像的某些部分也許無法顯示在背景定位區(qū)域中。
contain 把圖像圖像擴展至最大尺寸,以使其寬度和高度完全適應(yīng)內(nèi)容區(qū)域。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。