用Vue2實現移動端圖片上傳、壓縮、拖拽排序、拖拽刪除功能 圖片上傳圖片壓縮拖拽排序、拖拽刪除
之前在公司開發過一段時間的移動端H5頁面,有個功能就是要上傳圖片+壓縮。參考了一下網上的方法,外加自己摸索的過程,最終實現了這個功能。后面在家閑的時候又加多了個長按選中圖片,并且可以拖拽排序、拖拽到指定位置刪除的功能。
github地址:代碼地址
下面直接進入正題:
圖片上傳
圖片上傳用的是HTML的input標簽實現的。核心就是把獲取到的文件通過FileReader轉換成圖片,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<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重繪的方法實現的,具體代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
// 省略上面的代碼 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方法。
如果不在刪除的區域中,則進行圖片位置排序,排序后還原圖片樣式。并強制重新渲染圖片列表。
代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
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' } } }) } } |
至此,圖片的上傳、壓縮、拖拽排序、拖拽刪除功能就已經完成了。
到此這篇關于基于Vue2實現移動端圖片上傳、壓縮、拖拽排序、拖拽刪除功能的文章就介紹到這了,更多相關vue實現圖片上傳拖拽排序內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/qq_18901079/article/details/112191132