赞
踩
先给大家看一下最终效果。
大多数功能都是由Cropper.js封装好的,调整并制作了:
一开始制作这个需求思路有两个,使用canvas原生或者寻找现成的库,对比了一番觉得canvas实现时间耗费较长,且秉承着不重复造轮子的原则(其实是菜),决定使用Cropper.js。官方封装了很多参数、方法、事件,上手容易,文档阅读体验较好、而且便于扩展。
Cropper.js官方仓库+文档:github.com/fengyuanche…
Installation
- npm install cropperjs
- 复制代码
我们实现上述功能需要的核心HTMl部分只有:
- <!-- 1.一个用于获取上传文件的input,type="file",并且监听onchange事件 -->
- <input
- type="file"
- accept="image/*"
- id="imgReader"
- onchange="loadingImg"
- >
-
- <!-- 2.一个用于给Cropper.js覆盖使用的img -->
- <img id="cropImg">
-
- <!-- 3.两个用于预览的div -->
- <div class="previewText">裁剪预览</div>
- <div class="previewBox"></div>
- <div class="previewBoxRound"></div>
- 复制代码
首先先将用于上传的input隐藏起来,我们并不需要它的样式
- .inpuFile{
- display: none;
- }
- 复制代码
然后给你项目中的某个按钮添加一个点击事件,并且调用
- function uploadImg(){
- document.querySelector('#imgReader').click()
- },
- 复制代码
即可打开上传文件的窗口,然后选择你需要的图片
上传文件成功后,会触发onchange事件,调用loadingImg()
- //引入Cropper.js
- import 'cropperjs/dist/cropper.css';
- import Cropper from 'cropperjs';
-
- let CROPPER //创建一个cropper的全局对象
-
- function loadingImg(eve){
-
- //读取上传文件
- let reader = new FileReader();
- if(event.target.files[0]){
-
- //readAsDataURL方法可以将File对象转化为data:URL格式的字符串(base64编码)
- reader.readAsDataURL(eve.target.files[0]);
- reader.onload = (e)=>{
- let dataURL = reader.result;
- //将img的src改为刚上传的文件的转换格式
- document.querySelector('#cropImg').src = dataURL;
-
- const image = document.getElementById('cropImg');
-
- //创建cropper实例-----------------------------------------
- CROPPER = new Cropper(image, {
- aspectRatio: 16 / 16,
- viewMode:0,
- minContainerWidth:500,
- minContainerHeight:500,
- dragMode:'move',
- preview:[ document.querySelector('.previewBox'),
- document.querySelector('.previewBoxRound')]
- })
- }
- }
- }
- 复制代码
new Cropper方法:
new Cropper(element[, options])
第一个参数:element
第二个参数(可选):
我们需要用到的参数有:
- {
- aspectRatio: 16 / 16, //固定裁剪框的比例(横/竖),此处16/16则固定为正方形
- minContainerWidth:500, //容器最小的宽度
- minContainerHeight:500, //容器最小的高度
- dragMode:'move', //设置裁剪框为可以移动
- preview:[ document.querySelector('.previewBox'), //设置我们需要添加实时预览的地方
- document.querySelector('.previewBoxRound')]
-
- //更多参数请参照官方仓库...我们这里用不着
- }
- 复制代码
先忽略实时预览,完成到这里我们就可看到我们上传的图片以及裁剪功能:
上面创建cropper的时候,我们在选项中添加了
- preview:[ document.querySelector('.previewBox'),
- document.querySelector('.previewBoxRound')]
- 复制代码
preview就是用来设置我们需要实时预览的地方,但是设置完成之后要给上述的两个div添加一下样式,才可以正常显示
- .previewBox,.previewBoxRound{
- box-shadow: 0 0 5px #adadad;
- width: 100px;
- height: 100px;
- margin-top: 30px;
- overflow: hidden; /*这个超出设置为隐藏很重要,否则就会整个显示出来了*/
- }
- .previewBoxRound{
- border-radius: 50%; /*设置为圆形*/
- }
- 复制代码
- function GetData(){
- //getCroppedCanvas方法可以将裁剪区域的数据转换成canvas数据
- CROPPER.getCroppedCanvas({
- maxWidth: 4096,
- maxHeight: 4096,
- fillColor: '#fff',
- imageSmoothingEnabled: true,
- imageSmoothingQuality: 'high',
- }).toBlob((blob) => {
- //然后调用浏览器原生的toBlob方法将canvas数据转换成blob数据
-
- //之后就可以愉快的将blob数据发送至后端啦,可根据自己情况进行发送,我这里用的是axios
- const formData = new FormData();
- // 第三个参数为文件名,可选填.
- formData.append('croppedImage', blob/*, 'example.png' */);
- let config = {
- headers:{'Content-Type':'multipart/form-data'}
- }
-
- this.$axios.post(flow_mission_UploadFile(),param,config)
- .then((response)=>{
- console.log(response)
- })
- .catch((err)=>{
- console.log(err)
- })
- })
- }
- 复制代码
1.裁剪框尺寸问题
裁剪部分默认会根据上传图片的大小进行改变
- //在new Cropper的参数中设置
-
- minContainerWidth:500, //容器最小的宽度
- minContainerHeight:500, //容器最小的高度
- 复制代码
- #cropImg{
- height: 450px;
- width: 450px;
- box-shadow: 0 0 5px #adadad;
- }
- 复制代码
2.重复上传的问题
再次上传不同图片的时候,还是出现原来的图片,只需要在上传文件的时候,对之前存在的CROPPER进行摧毁就可以了
- function uploadImg(){
- document.querySelector('#imgReader').click()
- if(CROPPER){
- CROPPER.destroy()
- }
- },
- 复制代码
3.其他功能的实现
这里列举几个我这里用到的
还有很多其他方法和事件可以自行参照仓库,一个普通的上传头像功能就这样应该够用了!这里就不一一列举啦
如果觉得写得有不好的地方请多多指教,喜欢的话可以点个赞哈!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。