一、实现效果
二、实现代码
所用到组件movable-area
movable-view
HTML
<movable-area class="areaBlock">
<view class="picList">
<view class="picRelative" wx:for="{{picList}}" bind:longpress="showMoveBlock" bind:touchend="hideMoveBlock" data-index="{{index}}">
// 占位图
<image class="dynamicImg" src="{{item.tempFilePath}}" mode="aspectFill" lazy-load="false" binderror="" bindload=""></image>
<image class="deleteImg" wx:if="{{picList.length !== 0}}" catchtap="deleteImg" src="/images/function/deleteImg.png" mode="scaleToFill" lazy-load="false" binderror="" bindload="" data-index="{{index}}" />
// 移动模块
<movable-view wx:if="{{!moveIng}}" class="areaMove" bindchange="bindchange" direction="all" damping="30" x="{{defaultX}}" y="{{defaultY}}" disabled="{{currentTouchIndex === index ? false : true}}" style="z-index: {{currentTouchIndex === index ? '3' : '1'}}">
<image class="{{currentTouchIndex === index ? 'areaImg' : ''}}" bindtap="previewImg" data-index="{{index}}" src="{{item.tempFilePath}}" mode="aspectFill" lazy-load="false" binderror="" bindload="" />
</movable-view>
</view>
</view>
</movable-area>
JS
data: {
currentTouchIndex: -1,
currentX: 0,
currentY: 0,
defaultX: 0,
defaultY: 0,
moveIng: false
},
methods: {
// 显示底层可移动模块
showMoveBlock(e){
const { index } = e.currentTarget.dataset
this.setData({
currentTouchIndex: index
})
},
// 滑动结束(判断滑块当前位置)
hideMoveBlock(e){
if(this.data.currentTouchIndex === -1){
return
}
const { index } = e.currentTarget.dataset
const boundary = 20
// 判断图片移动位置
const directionX = this.data.currentX < 0 ? 'left' : 'right'
const directionY = this.data.currentY < 0 ? 'top' : 'bottom'
const currentX = Math.abs(this.data.currentX)
const currentY = Math.abs(this.data.currentY)
// 判断是否需要交换位置
const needChangeFlag = (currentX % 96) - (Math.floor(currentX / 96) * 40) > boundary || (currentY % 96) - (Math.floor(currentY / 96) * 40) > boundary ? false : true
if(!needChangeFlag || (currentX < 20 && currentY < 20)){
this.setData({
defaultX: 0,
defaultY: 0
})
}else{
this.setData({
moveIng: true
})
const moveX = directionX === 'left' ? -Math.floor(currentX / 96) : Math.floor(currentX / 96)
const moveY = directionY === 'top' ? -Math.floor(currentY / 96) : Math.floor(currentY / 96)
let middleCount = 0
let changeIndex = -1
// 根据移动方向和个数获取移动后的index(3为一行数量)
if(Math.abs(moveY) > 1){
middleCount = 3 * (Math.abs(moveY) - 1)
}
if(Math.abs(moveY) === 0){
changeIndex = index + moveX
}else{
changeIndex = moveY < 0 ? index - (3 - moveX) - middleCount : index + (3 + moveX) + middleCount
}
this.exchangePosition(index,changeIndex)
}
setTimeout(()=>{
this.setData({
moveIng: false,
currentTouchIndex: -1
})
},300)
},
// 图片数组交换位置
exchangePosition(initIndex,changeIndex){
if(changeIndex > this.data.picList.length - 1){
return
}
let initPicList = this.data.picList
const before = this.data.picList[initIndex]
const after = this.data.picList[changeIndex]
initPicList[initIndex] = after
initPicList[changeIndex] = before
this.setData({
picList: initPicList,
defaultX: 0,
defaultY: 0,
})
},
// 获取滑动移动的xy
bindchange: throttle(function (e){
this.setData({
currentX: Math.floor(e.detail.x),
currentY: Math.floor(e.detail.y)
})
},150),
// 删除图片
deleteImg(e){
const indexs = e.currentTarget.dataset.index
const picList = this.data.picList
const picUrlList = this.data.picUrlList
picList.splice(indexs,1)
picUrlList.splice(indexs,1)
this.setData({
picList,
picUrlList
})
},
// 预览图片
previewImg(e){
const indexs = e.currentTarget.dataset.index
let urlList = []
this.data.picList.forEach((item)=>{
urlList.push(item.tempFilePath)
})
wx.previewImage({
current: this.data.picList[indexs].tempFilePath, // 当前显示图片的 http 链接
urls: urlList // 需要预览的图片 http 链接列表
})
},
}
CSS
.areaBlock{
width: 100%;
height: 100%;
}
.picList{
padding: 0 30rpx 0;
display: flex;
align-items: center;
flex-wrap: wrap;
position: relative;
}
.areaMove{
position: absolute;
left: 0;
top: 0;
width: 196rpx;
height: 196rpx;
}
.areaMove image{
width: 100%;
height: 100%;
border-radius: 10rpx;
}
.areaImg{
box-shadow: 0 2rpx 18rpx 0 #7BC4FF;
}
.picRelative{
position: relative;
width: 196rpx;
height: 196rpx;
margin-right: 40rpx;
margin-bottom: 40rpx;
border: 1rpx dashed rgba(0, 0, 0, 0.06);
}
.picRelative:nth-child(3n){
margin-right: 0;
}
.dynamicImg{
width: 100%;
height: 100%;
border-radius: 10rpx;
}
.deleteImg{
position: absolute;
top: -20rpx;
right: -20rpx;
z-index: 2;
width: 44rpx;
height: 44rpx;
}
三、总结
图片到达可交换位置的容错值及图片一行的数量可以因需求而异。文章来源:https://www.toymoban.com/news/detail-524852.html
如果有逻辑错误或冗余代码敬请指正。文章来源地址https://www.toymoban.com/news/detail-524852.html
到了这里,关于微信小程序实现图片拖拽切换位置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!