基于Vue2實(shí)現(xiàn)移動(dòng)端圖片上傳、壓縮、拖拽排序、拖拽刪除功能
用Vue2實(shí)現(xiàn)移動(dòng)端圖片上傳、壓縮、拖拽排序、拖拽刪除功能 圖片上傳圖片壓縮拖拽排序、拖拽刪除
之前在公司開發(fā)過一段時(shí)間的移動(dòng)端H5頁面,有個(gè)功能就是要上傳圖片+壓縮。參考了一下網(wǎng)上的方法,外加自己摸索的過程,最終實(shí)現(xiàn)了這個(gè)功能。后面在家閑的時(shí)候又加多了個(gè)長按選中圖片,并且可以拖拽排序、拖拽到指定位置刪除的功能。
github地址:代碼地址
下面直接進(jìn)入正題:
圖片上傳
圖片上傳用的是HTML的input標(biāo)簽實(shí)現(xiàn)的。核心就是把獲取到的文件通過FileReader轉(zhuǎn)換成圖片,代碼如下:
<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重繪的方法實(shí)現(xiàn)的,具體代碼如下:
// 省略上面的代碼
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 圖片對(duì)象
*/
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))
}
拖拽排序、拖拽刪除
拖拽排序、拖拽到指定位置刪除是通過監(jiān)聽touch事件來實(shí)現(xiàn)的。
核心思路:
1、獲取到圖片dom元素,給圖片dom元素添加ontouchstart、ontouchend、ontouchmove 方法。
2、在ontouchstart方法中new一個(gè)時(shí)間節(jié)點(diǎn),在ontouchend中也new一個(gè)時(shí)間節(jié)點(diǎn),通過判斷兩個(gè)時(shí)間節(jié)點(diǎn)之間的時(shí)間間隔判斷是點(diǎn)擊事件還是長按事件。
3、ontouchstart中設(shè)置settimeout方法是延時(shí)判斷是點(diǎn)擊方法還是長按方法,如果是長按方法的則獲取圖片的所在頁面中的位置,設(shè)置圖片的位置為點(diǎn)擊屏幕的位置,改變圖片的布局方式,在ontouchmove方法中設(shè)置圖片的位置跟隨觸摸屏幕的位置變化。
4、移動(dòng)圖片后松開手時(shí),觸發(fā)ontouchend方法,判斷手指離開后,圖片所在的位置是否處在刪除的區(qū)域當(dāng)中,如果在則刪除圖片,并且重新渲染圖片列表,重新添加touch方法。
如果不在刪除的區(qū)域中,則進(jìn)行圖片位置排序,排序后還原圖片樣式。并強(qiáng)制重新渲染圖片列表。
代碼如下:
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('執(zhí)行元素位置操作過程')
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
// 計(jì)算所有圖片元素所在頁面位置
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('在目標(biāo)區(qū)域內(nèi),重新排序')
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'
}
}
})
}
}
至此,圖片的上傳、壓縮、拖拽排序、拖拽刪除功能就已經(jīng)完成了。
到此這篇關(guān)于基于Vue2實(shí)現(xiàn)移動(dòng)端圖片上傳、壓縮、拖拽排序、拖拽刪除功能的文章就介紹到這了,更多相關(guān)vue實(shí)現(xiàn)圖片上傳拖拽排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue實(shí)現(xiàn)監(jiān)聽dom節(jié)點(diǎn)寬高變化方式
這篇文章主要介紹了Vue實(shí)現(xiàn)監(jiān)聽dom節(jié)點(diǎn)寬高變化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Vue3?vite配置css?的sourceMap及文件引用配置別名的過程
這篇文章主要介紹了Vue3 vite配置css的sourceMap,及文件引用配置別名的過程,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
vue.js實(shí)現(xiàn)的全選與全不選功能示例【基于elementui】
這篇文章主要介紹了vue.js實(shí)現(xiàn)的全選與全不選功能,結(jié)合實(shí)例形式分析了vue.js基于elementui實(shí)現(xiàn)全選與全不選功能的相關(guān)頁面渲染、初始化數(shù)據(jù)及功能函數(shù)等相關(guān)操作技巧,需要的朋友可以參考下2018-12-12
vue中手動(dòng)封裝iconfont組件解析(三種引用方式的封裝和使用)
這篇文章主要介紹了vue中手動(dòng)封裝iconfont組件(三種引用方式的封裝和使用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
關(guān)于vue-router路由的傳參方式params query
這篇文章主要介紹了關(guān)于vue-router路由的傳參方式params query,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Vue3計(jì)算屬性computed和監(jiān)聽屬性watch區(qū)別解析
計(jì)算屬性適用于對(duì)已有的數(shù)據(jù)進(jìn)行計(jì)算,派生新的數(shù)據(jù),并在模板中使用;而監(jiān)聽屬性適用于監(jiān)聽數(shù)據(jù)的變化,并執(zhí)行一些特定的操作,根據(jù)具體的需求和場(chǎng)景,選擇適合的機(jī)制這篇文章主要介紹了Vue3計(jì)算屬性computed和監(jiān)聽屬性watch,需要的朋友可以參考下2024-02-02
vue之webpack -v報(bào)錯(cuò)解決方案總結(jié)
這篇文章主要介紹了vue之webpack -v報(bào)錯(cuò)解決方案總結(jié),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09

