(在真机上的效果就不演示了,是差不多的)
实现思路
布局
在这里运用到了微信小程序的moveable-area和moveable-view两个标签。
moveable-area是可拖拽的区域,需要设置其宽高。由于图片的大小我是根据屏幕来动态设置的,所以moveable-area的宽度是固定的100%,高度由上传的图片总高度决定,所以一开始的时候,我设置了最小高度。
moveable-view的宽高跟图片一致,也是动态设置,初始状态是隐藏的,当图片被长按时才会显示。当长按要排序的图片的时候,记录它的url,并赋值给moveable-view的image。
X
+
复制代码
页面初始化时计算宽高的js
// 计算图片宽度
_handleComputedImage:function(e){
const windowWidth = app.globalData.systemInfo.windowWidth;
const width = windowWidth - 16;
const imageWitdh = (width - 16) / 3;
this.setData({
imageWitdh
})
},复制代码
在上传图片之后,我们需要改变moveable-area的高度
// 选择图片
handleChooseImage: function (e) {
let length = this.data.images.length;
if (length == 9) {
wx.showToast({
title: "亲,最多只能选择九张图哦~",icon: "none",duration: 2000
})
return false;
}
var that = this;
wx.chooseImage({
count: 9 - this.data.images.length,sizeType: ['compressed'],//可选择原图或压缩后的图片
sourceType: ['album','camera'],//可选择性开放访问相册、相机
success: res => {
let images = that.data.images;
for (let i = 0; i < res.tempFilePaths.length;i++){
images.push(res.tempFilePaths[i]);
}
that.setData({
images
},function(){
//上传完之后更新面积
that._handleComputedArea();
});
},fail: err => console.log(err)
})
},复制代码
更新面积的计算如下,它的高度由.image-choose-container的view决定:
// 计算movable-area的高度
_handleComputedArea:function(e){
let that = this;
wx.createSelectorQuery().selectAll('.image-choose-container').boundingClientRect(function (rect) {
that.setData({
areaHeight: rect[0].height
})
}).exec()
},复制代码
p.s. 当删除图片的时候,我们也需要重新计算moveable-area的高度。
长按图片
图片可以拖拽排序的触发机制是长按。
在长按的时候,我们需要计算每张图片的坐标(这里的坐标不是固定的,当你的页面可以拖动的时候,坐标值是会发生改变)并保存;
记录当前图片在图片数组中的下标、url;
显示moveable-view,并设置其x、y值,将url赋值给其下的子元素。
// 计算每张图片的坐标
_handleComputedPoints(e){
let that = this;
var query = wx.createSelectorQuery();
var nodesRef = query.selectAll(".image-item");
nodesRef.fields({
dataset: true,rect: true
},(result) => {
that.setData({
pointsArr: result
})
}).exec()
},复制代码
// 长按图片
handleLongTap:function(e){
// 计算每张图片的坐标
this._handleComputedPoints();
this.setData({
currentImg: e.currentTarget.dataset.url,currentIndex: e.currentTarget.dataset.index,hidden: false,flag: true,x: e.currentTarget.offsetLeft,y: e.currentTarget.offsetTop
})
},复制代码
此时,长按图片,moveable-view(带有边框)将会出现在该图片之上。
移动图片
监听moveable-view的catchtouchmove事件,(不使用bindhtouchmove的原因是因为在图片移动的过程中,如果页面是可滑动的,会导致页面页跟着滑动),记录当前手指在页面上的位置e.touches[0].pageX和e.touches[0].pageY。
为了保证手指在移动的过程中,图片能跟着手指一起移动,则moveable-view的x距离是手指的e.touches[0].pageX,而y距离则是e.touches[0].pageX - 滚动条的移动距离-image-choose-container这个元素距离顶部的距离。
为了保证在移动图片的过程中,图片始终能在手指的中间,还将x,y分别减去图片的宽度。(对比两图,鼠标与moveable-view的位置)
// 移动的过程中
handleTouchMove:function(e){
let x = e.touches[0].pageX;
let y = e.touches[0].pageY;
// 首先先获得当前image-choose-container距离顶部的距离
let that = this;
wx.createSelectorQuery().selectAll('.image-choose-container').boundingClientRect(function (rect) {
let top = rect[0].top;
y = y - that.data.scrollTop - top;
that.setData({
x: x - that.data.imageWitdh / 2 > 0 ? x - that.data.imageWitdh / 2:0,y: y - that.data.imageWitdh / 2 > 0 ? y - that.data.imageWitdh / 2:0,})
}).exec()
},复制代码
// 监听滚动
onPageScroll:function(e){
this.data.scrollTop = e.scrollTop;
}
复制代码
停止拖拽时
监听moveable-view的bindtouchend事件,计算出当前的x,y值,对比每个图片的下标,得出它移动到哪个位置,更新数组,完毕。
// 移动结束的时候
handleTouchEnd:function(e){
if (!this.data.flag) {
// 非长按情况下
return;
}
let x = e.changedTouches[0].pageX;
let y = e.changedTouches[0].pageY - this.data.scrollTop;
// 每张图片的地址
const pointsArr = this.data.pointsArr;
let data = this.data.images;
for (var j = 0; j < pointsArr.length; j++) {
const item = pointsArr[j];
if (x > item.left && x < item.right && y > item.top && y < item.bottom) {
const endIndex = item.dataset.index;
const beginIndex = this.data.currentIndex;
//临时保存移动的目标数据
let temp = data[beginIndex];
//将移动目标的下标值替换为被移动目标的下标值
data[beginIndex] = data[endIndex];
//将被移动目标的下标值替换为beginIndex
data[endIndex] = temp;
}
}
this.setData({
images: data,hidden: true,flag: false,currentImg: ''
})
},复制代码
总结
以上是编程之家为你收集整理的微信小程序实现九宫格图片拖拽全部内容,希望文章能够帮你解决微信小程序实现九宫格图片拖拽所遇到的程序开发问题。
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
小编个人微信号 jb51ccc
喜欢与人分享编程技术与工作经验,欢迎加入编程之家官方交流群!
如果觉得《android可拖拽九宫格 微信小程序实现九宫格图片拖拽》对你有帮助,请点赞、收藏,并留下你的观点哦!