用Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能 图片上传图片压缩拖拽排序、拖拽删除
之前在公司开发过一段时间的移动端H5页面,有个功能就是要上传图片+压缩。参考了一下网上的方法,外加自己摸索的过程,最终实现了这个功能。后面在家闲的时候又加多了个长按选中图片,并且可以拖拽排序、拖拽到指定位置删除的功能。
github地址:代码地址
下面直接进入正题:
图片上传
图片上传用的是HTML的input标签实现的。核心就是把获取到的文件通过FileReader转换成图片,代码如下:
<input type="file" accept="image/*" capture="camera" @change="selectFile"> selectFile(event:any){ this.showAlert = false if (event.target.files && event.target.files.length > 0) { this.isLoading = true let file:any = event.target.files[0] let fr:any = new FileReader() fr.readAsDataURL(file) fr.onload = (imgObj:any) => { let img:any = new Image() img.src = imgObj.target.result img.onload = (e:any) => { // 这里就可以获取到上传的图片了 }) } } } }
图片压缩
图片压缩用的是canvas重绘的方法实现的,具体代码如下:
// 省略上面的代码 fr.onload = (imgObj:any) => { // 获取到图片文件后 let img:any = new Image() img.src = imgObj.target.result img.onload = (e:any) => { Compress(img,e.path[0].height,e.path[0].width,(newImg:any) => { this.imgList.push(newImg) this.isLoading = false // 待添加拖拽功能 }) } } /** * 图片压缩 * @param img 图片对象 */ export function Compress(img:any,height:number,width:number,callback:Function) { let canvas:any = document.createElement('canvas') let context:any = canvas.getContext('2d') canvas.width = width canvas.height = height context.clearRect(0,0,width,height) context.drawImage(img,0,0,width,height) callback(canvas.toDataURL("image/jpeg", 0.75)) }
拖拽排序、拖拽删除
拖拽排序、拖拽到指定位置删除是通过监听touch事件来实现的。
核心思路:
1、获取到图片dom元素,给图片dom元素添加ontouchstart、ontouchend、ontouchmove 方法。
2、在ontouchstart方法中new一个时间节点,在ontouchend中也new一个时间节点,通过判断两个时间节点之间的时间间隔判断是点击事件还是长按事件。
3、ontouchstart中设置settimeout方法是延时判断是点击方法还是长按方法,如果是长按方法的则获取图片的所在页面中的位置,设置图片的位置为点击屏幕的位置,改变图片的布局方式,在ontouchmove方法中设置图片的位置跟随触摸屏幕的位置变化。
4、移动图片后松开手时,触发ontouchend方法,判断手指离开后,图片所在的位置是否处在删除的区域当中,如果在则删除图片,并且重新渲染图片列表,重新添加touch方法。
如果不在删除的区域中,则进行图片位置排序,排序后还原图片样式。并强制重新渲染图片列表。
代码如下:
Compress(img,e.path[0].height,e.path[0].width,(newImg:any) => { this.imgList.push(newImg) this.isLoading = false // 在这里给加入方法 setTimeout(() => { this.addTouchEvent() }); }) addTouchEvent(){ let domList:any = document.querySelectorAll('.show-img') if (domList) { let domMoveFlag:boolean = true domList.forEach((item:any,index:any) => { item.ontouchstart = null item.ontouchmove = null item.ontouchend = null item.ontouchstart = (startEvent:any) => { startEvent.preventDefault() console.log(startEvent) this.touchStartTime = new Date() setTimeout(() => { if (domMoveFlag) { console.log('执行元素位置操作过程') this.showDeleteArea = true let domClient:any = item.getBoundingClientRect() console.log(domClient) this.firstPosition = { x:startEvent.changedTouches[0].pageX, y:startEvent.changedTouches[0].pageY } item.style.position = 'fixed' item.style.height = domClient.height + 'px' item.style.width = domClient.width + 'px' item.style.top = domClient.top + 'px' item.style.left = domClient.left + 'px' item.style.padding = 0 item.style.zIndex = 9 // 添加拖拽事件 item.ontouchmove = (moveEvent:any) => { // console.log(moveEvent) item.style.top = moveEvent.changedTouches[0].pageY - this.firstPosition.y + domClient.top + 'px' item.style.left = moveEvent.changedTouches[0].pageX - this.firstPosition.x + domClient.left + 'px' } } }, 600); } item.ontouchend = (endEvent:any) => { let time:any = new Date() console.log(time - this.touchStartTime) if (time - this.touchStartTime <= 400) { domMoveFlag = false item.click() setTimeout(() => { this.addTouchEvent() }); } else { let newItemCenter:any = item.getBoundingClientRect() let centerY:any = newItemCenter.top + newItemCenter.height / 2 let centerX:any = newItemCenter.left + newItemCenter.width / 2 let deleteDom:any = document.querySelector(".deleteImg") let deleteArea:any = deleteDom.getBoundingClientRect() if (centerY >= deleteArea.top) { let _imgList = JSON.parse(JSON.stringify(this.imgList)) let currentImg:any = _imgList.splice(index,1) this.imgList = [] this.showDeleteArea = false setTimeout(() => { this.imgList = _imgList setTimeout(() => { this.addTouchEvent() }); }); return } this.showDeleteArea = false // 计算所有图片元素所在页面位置 let domParentList:any = document.querySelectorAll('.imgCtn') domParentList && domParentList.forEach((domParent:any,cindex:any) => { let domPos:any = (domParent.getBoundingClientRect()) if ( centerY >= domPos.top && centerY <= domPos.bottom && centerX >= domPos.left && centerX <= domPos.right ) { // 重新排序 console.log('在目标区域内,重新排序') let _imgList = JSON.parse(JSON.stringify(this.imgList)) let currentImg:any = _imgList.splice(index,1) _imgList.splice(cindex,0,...currentImg) this.imgList = [] setTimeout(() => { this.imgList = _imgList setTimeout(() => { this.addTouchEvent() }); }); } }); // 还原样式 item.style.position = 'absolute'; item.style.height = '100%' item.style.width = '100%' item.style.top = '0' item.style.left = '0' item.style.padding = '10px' } } }) } }
至此,图片的上传、压缩、拖拽排序、拖拽删除功能就已经完成了。
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
暂无评论...
更新日志
2024年11月27日
2024年11月27日
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]