移动端vue3中使用vue-cropper(Vue2也可以)
- 用v3+h5开发移动端时,需要图片裁剪功能
- [ 查看演示 Demo ]
一、安装使用
1. 安装
# npm 安装
npm install vue-cropper
npm install vue-cropper@next
2. 使用
<!-- template -->
<div class="cropper" >
<!-- ...参考为参考文档 -->
<VueCropper ref="cropper" ... />
</div>
// script
import { VueCropper } from "vue-cropper";
/* style */
.cropper{
width: 100vw;
height: calc(100vh - 370px);
}
/* */
.vue-cropper[data-v-26736c2c] {
position: relative;
width: 100%;
height: 100%;
box-sizing: border-box;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
direction: ltr;
touch-action: none;
text-align: left;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)
}
.cropper-box[data-v-26736c2c],
.cropper-box-canvas[data-v-26736c2c],
.cropper-drag-box[data-v-26736c2c],
.cropper-crop-box[data-v-26736c2c],
.cropper-face[data-v-26736c2c] {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
user-select: none
}
.cropper-box-canvas img[data-v-26736c2c] {
position: relative;
text-align: left;
user-select: none;
transform: none;
max-width: none;
max-height: none
}
.cropper-box[data-v-26736c2c] {
overflow: hidden
}
.cropper-move[data-v-26736c2c] {
cursor: move
}
.cropper-crop[data-v-26736c2c] {
cursor: crosshair
}
.cropper-modal[data-v-26736c2c] {
background: rgba(0, 0, 0, .5)
}
.cropper-view-box[data-v-26736c2c] {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
outline: 1px solid #39f;
outline-color: #3399ffbf;
user-select: none
}
.cropper-view-box img[data-v-26736c2c] {
user-select: none;
text-align: left;
max-width: none;
max-height: none
}
.cropper-face[data-v-26736c2c] {
top: 0;
left: 0;
background-color: #fff;
opacity: .1
}
.crop-info[data-v-26736c2c] {
position: absolute;
left: 0px;
min-width: 65px;
text-align: center;
color: #fff;
line-height: 20px;
background-color: #000c;
font-size: 12px
}
.crop-line[data-v-26736c2c] {
position: absolute;
display: block;
width: 100%;
height: 100%;
opacity: .1
}
.line-w[data-v-26736c2c] {
top: -3px;
left: 0;
height: 5px;
cursor: n-resize
}
.line-a[data-v-26736c2c] {
top: 0;
left: -3px;
width: 5px;
cursor: w-resize
}
.line-s[data-v-26736c2c] {
bottom: -3px;
left: 0;
height: 5px;
cursor: s-resize
}
.line-d[data-v-26736c2c] {
top: 0;
right: -3px;
width: 5px;
cursor: e-resize
}
.crop-point[data-v-26736c2c] {
position: absolute;
width: 8px;
height: 8px;
opacity: .75;
background-color: #39f;
border-radius: 100%
}
.point1[data-v-26736c2c] {
top: -4px;
left: -4px;
cursor: nw-resize
}
.point2[data-v-26736c2c] {
top: -5px;
left: 50%;
margin-left: -3px;
cursor: n-resize
}
.point3[data-v-26736c2c] {
top: -4px;
right: -4px;
cursor: ne-resize
}
.point4[data-v-26736c2c] {
top: 50%;
left: -4px;
margin-top: -3px;
cursor: w-resize
}
.point5[data-v-26736c2c] {
top: 50%;
right: -4px;
margin-top: -3px;
cursor: e-resize
}
.point6[data-v-26736c2c] {
bottom: -5px;
left: -4px;
cursor: sw-resize
}
.point7[data-v-26736c2c] {
bottom: -5px;
left: 50%;
margin-left: -3px;
cursor: s-resize
}
.point8[data-v-26736c2c] {
bottom: -5px;
right: -4px;
cursor: se-resize
}
@media screen and (max-width: 500px) {
.crop-point[data-v-26736c2c] {
position: absolute;
width: 20px;
height: 20px;
opacity: .45;
background-color: #39f;
border-radius: 100%
}
.point1[data-v-26736c2c] {
top: -10px;
left: -10px
}
.point2[data-v-26736c2c],
.point4[data-v-26736c2c],
.point5[data-v-26736c2c],
.point7[data-v-26736c2c] {
display: none
}
.point3[data-v-26736c2c] {
top: -10px;
right: -10px
}
.point4[data-v-26736c2c] {
top: 0;
left: 0
}
.point6[data-v-26736c2c] {
bottom: -10px;
left: -10px
}
.point8[data-v-26736c2c] {
bottom: -10px;
right: -10px
}
}
二、文档
1. props
| 名称 | 功能 | 默认值 | 可选值 | |
|---|---|---|---|---|
| img | 裁剪图片的地址 | 空 | url 地址, base64, blob | |
| outputSize | 裁剪生成图片的质量 | 1 | 0.1 ~ 1 | |
| outputType | 裁剪生成图片的格式 | jpg (jpg 需要传入jpeg) | jpeg, png, webp | |
| info | 裁剪框的大小信息 | true | true, false | |
| canScale | 图片是否允许滚轮缩放 | true | true, false | |
| autoCrop | 是否默认生成截图框 | false | true, false | |
| autoCropWidth | 默认生成截图框宽度 | 容器的 80% | 0 ~ max | |
| autoCropHeight | 默认生成截图框高度 | 容器的 80% | 0 ~ max | |
| fixed | 是否开启截图框宽高固定比例 | true | true, false | |
| fixedNumber | 截图框的宽高比例 | [1, 1] | [ 宽度 , 高度 ] | |
| full | 是否输出原图比例的截图 | false | true, false | |
| fixedBox | 固定截图框大小 | 不允许改变 | false | true, false |
| canMove | 上传图片是否可以移动 | true | true, false | |
| canMoveBox | 截图框能否拖动 | true | true, false | |
| original | 上传图片按照原始比例渲染 | false | true, false | |
| centerBox | 截图框是否被限制在图片里面 | false | true, false | |
| high | 是否按照设备的dpr 输出等比例图片 | true | true, false | |
| infoTrue | true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | false | true, false | |
| maxImgSize | 限制图片最大宽度和高度 | 2000 | 0 ~ max | |
| enlarge | 图片根据截图框输出比例倍数 | 1 | 0 ~ max(建议不要太大不然会卡死的呢) | |
| mode | 图片默认渲染方式 | contain | contain , cover, 100px, 100% auto |
2. 可用回调方法
@realTime实时预览事件@imgMoving图片移动回调函数@cropMoving截图框移动回调函数@imgLoad图片加载的回调, 返回结果success,error
@realTime 实时预览事件
realTime(data) {
var previews = data
var h = 0.5
var w = 0.2
this.previewStyle1 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: h
}
this.previewStyle2 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: w
}
// 固定为 100 宽度
this.previewStyle3 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: 100 / preview.w
}
// 固定为 100 高度
this.previewStyle4 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: 100 / preview.h
}
this.previews = data
}
<div class="show-preview" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden',
'margin': '5px'}">
<div :style="previews.div">
<img :src="option.img" :style="previews.img">
</div>
</div>
<p>中等大小</p>
<div :style="previewStyle1">
<div :style="previews.div">
<img :src="previews.url" :style="previews.img">
</div>
</div>
<p>迷你大小</p>
<div :style="previewStyle2">
<div :style="previews.div">
<img :src="previews.url" :style="previews.img">
</div>
</div>
@imgMoving 图片移动回调函数
返回的参数内容
{
moving: true, // moving 是否在移动
axis: {
x1: 1, // 左上角
x2: 1,// 右上角
y1: 1,// 左下角
y2: 1 // 右下角
}
}
@cropMoving 截图框移动回调函数
返回的参数内容
{
moving: true, // moving 是否在移动
axis: {
x1: 1, // 左上角
x2: 1,// 右上角
y1: 1,// 左下角
y2: 1 // 右下角
}
}
2. 内置方法 和 属性
通过 this.$refs.cropper 调用
属性
| 属性 | 说明 |
|---|---|
| this.$refs.cropper.cropW | 截图框宽度 |
| this.$refs.cropper.cropH | 截图框高度 |
方法
| 方法 | 说明 |
|---|---|
| this.$refs.cropper.startCrop() | 开始截图 |
| this.$refs.cropper.stopCrop() | 停止截图 |
| this.$refs.cropper.clearCrop() | 清除截图 |
| this.$refs.cropper.changeScale() | 修改图片大小 正数为变大 负数变小 |
| this.$refs.cropper.getImgAxis() | 获取图片基于容器的坐标点 |
| this.$refs.cropper.getCropAxis() | 获取截图框基于容器的坐标点 |
| this.$refs.cropper.goAutoCrop | 自动生成截图框函数 |
| this.$refs.cropper.rotateRight() | 向右边旋转90度 |
| this.$refs.cropper.rotateLeft() | 向左边旋转90度 |
获取截图内容
获取截图的 base64 数据
this.$refs.cropper.getCropData(data => {
// do something
console.log(data)
})
获取截图的 blob 数据
this.$refs.cropper.getCropBlob(data => {
// do something
console.log(data)
// blob转 file
var result = new File([data], '文件名', { type: data.type, lastModified: Date.now() });
console.log(result)
})