由于业务需要用户上传图片并且需要用户自行对上传的图片做尺寸裁剪,本次目的是让用户操作方便、简单,起初翻阅了几个类似功能的库后准备使用 腾讯前端团队的AlloyCrop.js ,在移动端体验很差似乎仓库也没有在维护了,找到了另外俩个库:
-
Croppie.js
https://github.com/foliotek/croppie -
Croppr.js
https://jamesooi.design/Croppr.js/
这俩款库都支持移动端和pc端,API文档也都写得清晰明了,这里就用Croppie。
安装
NPM:
npm install croppie
Bower:
bower install croppie
或者直接引入
<link rel="stylesheet" href="croppie.css" />
<script src="croppie.js"></script>
使用
- 简单用法
<div class="demo"></div>
<script>
$('.demo').croppie({
url: 'demo/demo-1.jpg',
});
</script>
<!--更简单用法 -->
<img class="my-image" src="demo/demo-1.jpg" />
<script>
$('.my-image').croppie();
</script>
初始化对象
- 在页面中添加一个容器
<div id="demo"></div>
- 不依赖jQuery的用法
//参数1:页面上的容器Node
//参数2:插件配置项
var c = new Croppie(document.getElementById('demo'), opts);
// 调用方法
//参数:方法接收的参数
c.method(args);
- 依赖jQuery的用法
//参数:插件配置项
$('#demo').croppie(opts);
// 调用方法
//参数1:方法名
//参数2:方法接收的参数
$('#demo').croppie(method, args);
配置项:
-
boundary
object {width:number,height:number}
外部容器大小
默认值
用户自定义定容器填充满
-
customClass
string
自定义外部容器class类名,自定义样式
默认值
''
-
enableExif
boolean
是否启用exif纠正图片旋转方向,ps:开启此属性需要自行引入
Exif.js
库
(ios相机拍出的照片会出现旋转的情况常用exif读取图片EXIF元数据然后做相应的旋转纠正,详情参阅 exif.js)默认值
false
-
enableOrientation
boolean
是否启用自定义图像旋转方向,此选项和
bind
方法的orientation
属性配合使用默认值
false
-
enableResize
boolean
是否启用视口大小拖动调整
默认值
false
-
enableZoom
boolean
是否启用缩放功能,关闭后底部滑块也会跟随关闭
默认值
true
-
enforceBoundary
boolean
Experimental
限制缩放,使图像不能小于视口
默认值
true
-
mouseWheelZoom
bool/string
是否启用鼠标滚轮放大或缩小,也可设置为
'ctrl'
设置后需要按住ctrl+滚轮
才能缩放图片默认值
true
-
showZoomer
boolean
显示隐藏底部控制滑块
默认值
true
-
viewport
object
内部容器大小,图像可见部分即裁剪部分大小。
默认值
{ width: 100, height: 100, type: 'square' }
type
可选值:'square' 'circle'
,type=circle
的时候一般会与result
方法的circle=true
参数配合使用
方法
-
get()
返回
object
获取相对于图片的裁切点和缩放值 -
bind({ url, points, orientation, zoom })
返回
Promise
动态将图像载入进容器
参数:
url
string
图像的url地址(可以是base64
或者URL.createObjectURL
创建的地址)
points
array
数组形式选择展示图片的哪些部位[topLeftX, topLeftY, bottomRightX, bottomRightY]
zoom
number
缩放值,1<
缩小>1
放大
orientation
number
自定义图片旋转方向,在exif调整方向之后应用。需要开启enableOrientation
选项orientation
的可选值:
1
默认
2
水平翻转
3
旋转180°
4
垂直翻转
5
水平翻转,然后向左旋转90°
6
顺时针旋转90°
7
水平翻转,然后向右旋转90°
8
逆时针旋转90° -
destroy()
销毁一个croppie实例并将其从DOM中移除
-
result({ type, size, format, quality, circle })
获取最终裁切出的图像
返回Promise
参数
type
string
期望输出什么类型的数据,默认'canvas'
type
可选值
'base64'
返回base64
数据
'html'
返回div
内部嵌套img
并且div
被设置了隐藏溢出样式
'blob'
返回blob
对象
'rawcanvas'
返回canvas
元素,可以在获取结果图像之前进行自定义操作size
string|object
裁剪图像的大小,默认为'viewport'
size
可选值
'viewport'
生成的图像的大小与视口的宽度和高度相同
'original'
生成的图像的大小将为图像的原始比例
{width, height}
定义宽度和高度的对象。如果仅指定一个尺寸,则将使用视口宽高比计算另一个尺寸。format
string
指定图像格式,默认为'png'
format
可选值
'jpeg'|'png'|'webp'
quality
number
图片的质量0 ~ 1
,1
质量最高 , 默认1
circle
boolean
是否裁剪为一个圆,默认false
,一般会与viewport.type = 'circle'
配合使用 -
rotate(degrees)
将图像旋转指定的度数。仅在启用enableOrientation选项的情况下起作用(请参见“选项”)。
有效度数:90
,180
,270
,-90
,-180
,-270
-
setZoom(value)
设置Croppie实例的缩放。传入的值仍限制为Croppie设置的最小值/最大值。
设置浮点值以缩放裁剪图像。必须介于裁剪设置的最小值和最大值之间。
功能实现
首先在页面插入一些节点作为剪切图片的操作面板。并简单设置一下样式,以及rem单位划分
<style>
*{padding: 0; margin: 0;}
html,body{ width: 100%; height: 100%; }
body{background: #fff;position: relative;}
.croppie-box{ height: 100%; width: 100%; position: absolute; left: 0; top: 0; z-index: 9999; display: none;}
.croppie-box .button{ position: absolute; right: 3rem; bottom: 2rem; width: 8rem; height: 2.5rem; z-index: 99; border-radius: 2px; text-align: center; line-height: 2.5rem; font-size: 1rem; }
.croppie-box .button.ok{ color:#002531; background: rgb(43, 202, 253);}
.croppie-box .button.cancel{ background-color: #ccc; color:#444; left: 3rem;}
</style>
<script>
var htmlWidth = document.documentElement.clientWidth || document.body.clientWidth;
var htmlHeight = document.documentElement.clientHeight || document.body.clientHeight;
var htmlDom = document.documentElement;
var WIDTH = htmlWidth;
if(htmlWidth>htmlHeight){
WIDTH = 750;
htmlDom.style.cssText = 'width:750px;margin:0 auto;background:#000;'
}
htmlDom.style.fontSize= WIDTH/25 + 'px';
</script>
<div class="croppie-box">
<div class="croppie"></div>
<div class="button ok">确定</div>
<div class="button cancel">取消</div>
</div>
<input type="file" name="" class="upload">
<img class="img" style="width: 100%;height: auto;padding: 2rem;box-sizing: border-box;display: block;" src="" alt="">
将需要用到的节点全部存起来
var croppie = undefined,
fileInput = document.querySelector('.upload'),
okBtn = document.querySelector('.button.ok'),
cancelBtn = document.querySelector('.button.cancel'),
croppieBox = document.querySelector('.croppie-box'),
resultImg = document.querySelector('.img');
scale = (WIDTH-50) / 5;//计算一个倍数简单适配一下不同手机屏幕
定义俩个待会儿需要用到的方法
croppieBox.show = function(){
this.style.cssText = 'display:block;'
}
croppieBox.hide = function(){
this.style.cssText = 'display:none;'
}
业务要求用户需要裁剪一个5:4比例的图片。
创建Croppie实例,并且不需要底部滑块所以隐藏掉
croppie = new Croppie(croppieBox.querySelector('.croppie'),{
showZoomer:false,//隐藏滑块
viewport: {
width: 5*scale,//乘上倍数 保证裁剪框大小是5:4
height: 4*scale
},
enableExif: true//纠正旋转角度
})
给file绑定一个事件然后把file选择的图片读取到croppie容器里面进行裁剪,zoom设置为0.00001是为了让图片载入的时候能够把一个边完全贴合容器。
fileInput.addEventListener('change', function (e) {
croppieBox.show();
croppie.bind({
url: window.URL.createObjectURL(e.target.files[0]),
zoom:0.00001,
})
});
接下来给俩个按钮绑定事件,result方法的size属性需要注意如果选择'viewport'得到的图片会比较模糊因为宽高是根据裁剪视口大小来的(即图像宽通常 < window.innerWidth)。当然可以自行设定{widnth,height}拿固定值(需要注意裁剪的比例如果指定的大小和裁剪比例不一致会导致图片拉伸),在这里的业务场景比较适合用原始图像的宽高所以选择了'original',点击确定调用result方法生成一个blob对象,接下来拿到blob之后就可以自己随意操作了
okBtn.addEventListener('click', function (ev) {
croppie.result({
type: 'blob',
size: 'original',
}).then(function (resp) {
resultImg.setAttribute('src',window.URL.createObjectURL(resp))
fileInput.value='';
croppieBox.hide();
});
});
cancelBtn.addEventListener('click', function (ev) {
croppieBox.hide();
fileInput.value='';
});
网友评论