文档地址
github: https://github.com/fengyuanchen/cropperjs
csdn: https://blog.csdn.net/weixin_38023551/article/details/78792400
使用方法:
- 新建标签
<img ref="cropperImg">
- 初始化参数
options: {
viewMode: 2, // 0:无限制; 1:将裁剪框限制为不超过画布的大小, 2:限制最小画布尺寸以适应容器,如果画布和容器的比例不同,则最小画布将在其中一个维度中被额外的空格包围。, 3:限制最小画布尺寸以填充容器。如果画布和容器的比例不同,则容器将无法将整个画布适合其中一个尺寸。
dragMode: 'move', // 'crop':创建一个新的裁剪框 'move':移动画布 'none':do nothing
aspectRatio: 16/9, // 设置裁剪框的宽高比。默认情况下,裁剪框是空闲比率。
data: {}, // 如果您已经存储了以前的裁剪数据,将在构建时自动传递给setData方法。
preview: '', //添加额外的元素(容器)进行预览。
autoCropArea: 1, //介于0和1之间的数字。定义自动裁剪区域大小(百分比), 1: 完全按照最大宽度后最大高度设置剪切框
checkCrossOrigin: true,
movable: true, //启用移动图像。
rotatable: true, //启用旋转图像。
scalable: true, //启用缩放图像。
zoomable: true, //启用缩放图像。
zoomOnTouch: true, //启用通过拖动触摸缩放图像。
zoomOnWheel: true, //启用通过滚动鼠标放大图像。。
cropBoxMovable: true, // 启用通过拖动来移动裁剪框。
cropBoxResizable: true, // 启用通过拖动调整裁剪框的大小。。
toggleDragModeOnDblclick: false, //在裁剪器上点击两次时,启用“切割”和“移动”之间切换拖动模式。
minContainerWidth: 200, //容器的最小宽度。。
minContainerHeight: 100, //容器的最小高度。。。
ready: function () {
this.cropper && this.cropper.crop();
// 可以根据用户参入的比例, 进行更改剪切框比例
if (this.cropObj) {
this.cropper && this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
}
},
crop: function (e) {
}
},
- 初始化剪切区域
- 新建剪切区域, 新建完毕,
- 替换url(可根据用户传过来的url进行替换),
- 替换完毕后, 重置剪切区域
init() {
// this.cropper && this.cropper.destroy()
this.cropper = new Cropper(this.$refs.cropperImg, this.options);
this.replace(this.src)
this.cropper && this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
},
- 完整代码
<template>
<div class="b-cropper">
<img ref="cropperImg">
</div>
</template>
<script>
import '@/components/cropperjs/dist/cropper.min.css'
const Cropper_de = require('@/components/cropperjs/dist/cropper.min.js')
const Cropper = Cropper_de.Cropper
export default {
data() {
var self = this;
return {
cropper: null,
options: {
viewMode: 2, // 0:无限制; 1:将裁剪框限制为不超过画布的大小, 2:限制最小画布尺寸以适应容器,如果画布和容器的比例不同,则最小画布将在其中一个维度中被额外的空格包围。, 3:限制最小画布尺寸以填充容器。如果画布和容器的比例不同,则容器将无法将整个画布适合其中一个尺寸。
dragMode: 'move', // 'crop':创建一个新的裁剪框 'move':移动画布 'none':do nothing
aspectRatio: 16/9, // 设置裁剪框的宽高比。默认情况下,裁剪框是空闲比率。
data: {}, // 如果您已经存储了以前的裁剪数据,将在构建时自动传递给setData方法。
preview: '', //添加额外的元素(容器)进行预览。
autoCropArea: 1, //介于0和1之间的数字。定义自动裁剪区域大小(百分比)
checkCrossOrigin: true,
movable: true, //启用移动图像。
rotatable: true, //启用旋转图像。
scalable: true, //启用缩放图像。
zoomable: true, //启用缩放图像。
zoomOnTouch: true, //启用通过拖动触摸缩放图像。
zoomOnWheel: true, //启用通过滚动鼠标放大图像。。
cropBoxMovable: true, // 启用通过拖动来移动裁剪框。
cropBoxResizable: true, // 启用通过拖动调整裁剪框的大小。。
toggleDragModeOnDblclick: false, //在裁剪器上点击两次时,启用“切割”和“移动”之间切换拖动模式。
minContainerWidth: 200, //容器的最小宽度。。
minContainerHeight: 100, //容器的最小高度。。。
ready: function () {
this.cropper && this.cropper.crop();
if (this.cropObj) {
this.cropper && this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
}
},
crop: function (e) {
}
},
nativeFile: null,
}
},
/*
reset():将图像和裁剪框重置为初始状态。
crop(): 手动显示裁剪框。
clear():清除裁剪框。
enable():启用(解冻)裁剪器。
disable():禁用(冻结)裁剪器。
destroy():销毁裁剪器并从图像中删除实例。
move(offsetX[, offsetY]):用相对偏移移动画布(图像包装器)。
* */
props: {
src: {
type: String,
default: ""
},
cropObj: {
type: Object,
default: ()=>{
return {
left: 0,
top: 0,
width: 20,
height: 20.
}
}
},
},
watch: {
src (val) {
this.replace(val)
},
cropObj () {
this.cropper && this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
}
},
mounted () {
this.$nextTick(() => {
setTimeout(() => {
this.init();
})
})
},
methods: {
init() {
this.cropper = new Cropper(this.$refs.cropperImg, this.options);
this.replace(this.src)
this.cropper && this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
},
replace (url, onlyColorChanged) {
this.cropper.reset()
if (url && url.indexOf("http") == 0) {
url = '//' + url.split("//")[1] + '?v=3'
}
if (onlyColorChanged) {
this.cropper && this.cropper.replace(url, onlyColorChanged)
} else {
this.cropper && this.cropper.replace(url)
}
},
getNativeCanvas(url) {
return new Promise(resolve => {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var img = new Image();
img.crossOrigin = "Anonymous";//解决跨域图片问题,就是上面提及的
img.onload = function(){
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0, img.width, img.height);
resolve(canvas)
}
img.src = "//" + url.split("//")[1];
})
},
// 获取转换工具;
utils(){
let blobToDataURL = function(blob, callback) {
return new Promise(resolve => {
var a = new FileReader();
a.onload = function (e) {
callback && callback(e.target.result);
resolve(e.target.result)
}
a.readAsDataURL(blob);
})
}
let dataURLtoFile = function(dataurl, filename) {//将base64转换为文件
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
filename = filename ? filename : Math.ceil(Math.random())*1000 * 1000 + ".jpg"
return new File([u8arr], filename, {type:mime});
}
let dataURLToBlob = function(dataurl){
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
let getObjectURL = function(file) {
var url = null;
if (window.createObjectURL !== undefined) { // basic
url = window.createObjectURL(file);
} else if (window.URL !== undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL !== undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
}
let urlGetBolb = function (url) {
return new Promise((resolve => {
url = url && '//' + url.split("//")[1] + '?v=' + (Math.random() * 10)
var img = new Image();
var _this = this;
// img.setAttribute("crossOrigin",'anonymous') // 添加改代码, 防止跨域
img.onload = function () {
var xhr = new XMLHttpRequest();
xhr.open("get", url, true);
xhr.responseType = "blob";
xhr.onload = function() {
if (this.status == 200) {
var blob = this.response;
resolve(blob)
}
}
xhr.send()
}
img.onerror = () => {
};
// img.setAttribute("crossOrigin",'anonymous') // 添加改代码, 防止跨域
img.src =url
}))
}
return {
blobToDataURL,
dataURLtoFile,
dataURLToBlob,
getObjectURL,
urlGetBolb
}
},
getBrowserInfo(){
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
var isOpera = userAgent.indexOf("Opera") > -1;
//判断是否Opera浏览器
if (isOpera) {
return "Opera"
};
//判断是否Firefox浏览器
if (userAgent.indexOf("Firefox") > -1) {
return "FF";
}
//判断是否chorme浏览器
if (userAgent.indexOf("Chrome") > -1){
return "Chrome";
}
//判断是否Safari浏览器
if (userAgent.indexOf("Safari") > -1) {
return "Safari";
}
//判断是否IE浏览器
if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera) {
return "IE";
}
//判断是否Edge浏览器
if (userAgent.indexOf("Trident") > -1) {
return "Edge";
};
},
getImageData () {
return this.cropper.getImageData()
},
getData () {
return this.cropper.getData(true)
}
},
beforeDestroy () {
this.cropper.destroy()
},
}
</script>
<style lang="less">
.b-cropper{
width: 100%;
height: 100%;
display: block;
background: #fff;
.layer-header{
display: flex;
padding: 10px 20px;
>div{
flex: 1;
}
>div:first-child{
text-align: left;
}
>div:last-child{
text-align: right;
}
.cancel, .confirm{
font-size: 32px;
color: #555;
padding: 0 20px;
}
.confirm{
color: #BE001E;
}
}
.file{
display: none;
width: 0;
height: 0;
overflow: hidden;
}
}
</style>
- 功能分析
- watch
这里面有两点
src (val) {
this.replace(val)
},
cropObj () {
this.cropper && this.cropper.setAspectRatio( (this.cropObj.width / this.cropObj.height) )
}
分别是当src传入的时候, 更改src, 当 cropObj 传入的时候, 更改剪切区域
-
utils
这里面主要包含了, bold base64, bolb_url, file转化的工具 -
getBrowserInfo
获取浏览器信息 -
getImageData
获取原图信息 -
getData
获取剪切区域图片信息 -
beforeDestroy
当关闭这个组件, 将组建销毁。 -
replace
里面有几个重要的点
replace (url, onlyColorChanged) {
this.cropper.reset()
if (url && url.indexOf("http") == 0) {
url = '//' + url.split("//")[1] + '?v=3'
}
if (onlyColorChanged) {
this.cropper && this.cropper.replace(url, onlyColorChanged)
} else {
this.cropper && this.cropper.replace(url)
}
},
1. this.cropper.reset() 重置
2. url = '//' + url.split("//")[1] + '?v=3' 有时候我们是请求https的, 但是当前域却在http环境, 因此去掉http|https, 使用//反而更好, 这样能防止跨域。
3. this.cropper.replace(url) 替换图片;
网友评论