【小程序-拖拽组件】

卡片式-可重新调整位置

原文地址:https://www.cnblogs.com/gxLog/p/15876286.html

在这里插入图片描述

wxml代码:

<view class="container">
  <movable-area class="item_box" style="width: {{boxWeight}}rpx;height: {{boxHeight}}rpx">
    <movable-view class="item {{selectId === item.id?'item_show':'item_hide'}}" wx:for="{{healthItem}}" x="{{item.x}}rpx" y="{{item.y}}rpx" direction="all" bindchange="touchMove" bindtouchend="touchend" data-index="{{item.index}}" data-id="{{item.id}}" bindtouchstart="unlockItem">
      <view class="item_name">{{item.name}}</view>
    </movable-view>
  </movable-area>
 
  <view class="item_box layer_box" style="width: {{boxWeight}}rpx;height: {{boxHeight}}rpx">
    <view class="item layer_item {{selectId == item.id?'item_hide':''}}" wx:for="{{layerItem}}" style="left: {{item.x}}rpx;top: {{item.y}}rpx">
      <view class="item_name">{{item.name}}</view>
    </view>
  </view>
</view>

js代码:

const app = getApp();
Page({
  data: {
    arr: [
      {
        id: 1,
        name: '1号'
      },
      {
        id: 2,
        name: '2号'
      },
      {
        id: 3,
        name: '3号'
      },
      {
        id: 4,
        name: '4号'
      },
      {
        id: 5,
        name: '5号'
      },
      {
        id: 6,
        name: '6号'
      },
    ],
    boxWeight: 750, //容器宽度,100%为750,单位rpx
    boxHeight: 0, //容器高度
    height: 352, //滑块总高度,即滑块本身加上边距的高度
    selectId: 0, //当前选中滑块的id
    col: 3, //滑块列数
  },
  onload: function (options) {
 
  },
 
  onShow() {
    let {arr,height,boxWeight,col,boxHeight} = this.data;
    arr.forEach((item,i) => {
      item.x = (i % col) * Math.trunc(boxWeight / col)  //区域左上角横坐标
      item.y = Math.trunc(i / col) * height //区域左上角纵坐标
      item.index = i;
    })
    if (Math.trunc(arr.length % col)){
      boxHeight = (Math.trunc(arr.length / col) + 1) * height
    }else{
      boxHeight = Math.trunc(arr.length / col) * height
    }
    this.setData({
      healthItem: arr,
      layerItem: arr,
      boxHeight,
    })
  },
 
 
  /**
   * 点击到滑块时切换隐藏显示
   */
  unlockItem(e){
    this.setData({
      selectId: e.currentTarget.dataset.id
    })
  },
 
  /**
   * 拖动滑块
   */
  touchMove(e){
    const s = this;
    let {boxWeight,height,layerItem,col} = s.data
    let weight = Math.trunc(boxWeight / col); //每块区域的宽度
    if (e.detail.source === 'touch'){
      let arr = [...layerItem];
      let id = e.currentTarget.dataset.id;
      let centerX = (e.detail.x * 2) + (weight / col) //当前选中滑块的中心的x坐标
      let centerY = (e.detail.y * 2) + (height / col) //当前选中滑块的中心的y坐标
      let key = 0; //滑块滑动时的位置
      let index = 0; //滑块滑动前的位置
 
      //通过id判断当前滑块的index
      layerItem.forEach(item => {
        if (item.id === id){
          index = item.index
        }
      })
 
      //根据当前滑块位置确认当前所处在哪个区域
      for (let i = 0; i < arr.length + 1; i++){
        let x1 = (i % col) * (boxWeight / col) //第n个区域的左上角和左下角x坐标
        let x2 = (i % col + 1) * (boxWeight / col) //第n个区域的右上角和右下角x坐标
        let y1 = Math.trunc(i / col) * height //第n个区域的左上角和右上角y坐标
        let y2 = Math.trunc(i / col + 1) * height //第n个区域的左下角和右下角y坐标
        //判断当前滑块所属区域
        if (centerX > x1 && centerX < x2 && centerY > y1 && centerY < y2){
          key = i
        }
      }
      //当key值大于数组长度时,即数组长度为奇数,滑块位于容器右下方无滑块的位置,滑块实际的key值为数组长度减一
      if (key >= arr.length - 1){
        key = arr.length - 1
      }
 
      //滑动时位置与滑动前不同时
      if (index != key){
        //计算数组中其他数据变化后的index
        arr.forEach((item,i) => {
          if (item.id != id){
            //index前进到key位置
            if (index > key){
              if (item.index >= key && item.index < index){
                item.index = item.index + 1
              }
            }
            //index后退到key位置
            if (index < key){
              if (item.index > index && item.index <= key){
                item.index = item.index - 1
              }
            }
          }else{
            item.index = key
          }
        })
 
        //根据数据变化后的index计算改变顺序后的实际位置
        arr.forEach((item,i) => {
          item.x = (item.index % col) * (boxWeight / col)
          item.y = Math.trunc(item.index / col) * height
        })
 
        s.setData({
          layerItem: arr,
          key,index
        })
      }
    }
  },
 
  /**
   * 停止拖动,两数组同步
   */
  touchend(e){
    let {layerItem} = this.data;
    this.setData({
      healthItem: layerItem,
    })
  },
 
});

wxss代码:

/* pages/setting/drag/drag.wxss */

.container{
    position: relative;
}
.item_box{
  z-index: 9;
}
.item{
  width: 200rpx;
  height: 320rpx;
  background: #FFFFFF;
  box-shadow: 0 2rpx 20rpx rgba(208, 213, 221, 0.5);
  border-radius: 10px;
  margin-bottom: 32rpx;
}
.item_name{
  width: auto;
  margin: 32rpx 32rpx 0;
  font-size: 44rpx;
  font-weight: bold;
  line-height: 60rpx;
  color: #333333;
}

.layer_box{
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}
.layer_item{
  position: absolute;
  transition: left 1s,top 1s;
}
.item_show{
  opacity: 1;
}
.item_hide{
  opacity: 0;
}

上下拖动式

原文地址:https://blog.csdn.net/weixin_41192489/article/details/129593275

在这里插入图片描述

wxml代码:

<movable-area style="width: 100%;height:{{(dataList.length)*60}}px;">
  <movable-view class="itemBox" style="z-index:{{index == moveId ? 2 : 1}}" wx:for="{{dataList}}" wx:key="index" y="{{item.y}}" direction="all" bind:change="moving" bind:touchend='moved' data-moveid="{{index}}">
    {{item.content}}
  </movable-view>
</movable-area>

js代码:

Page({
  data: {
    // 列表数据
    dataList: [{
        content: "苹果"
      },
      {
        content: "香蕉"
      },
      {
        content: "梨子"
      },
    ],
    // 移动块的id
    moveId: null,
    // 最终停止的位置
    endY: 0,
  },
  onLoad() {
    this.init(this.data.dataList)
  },
  // 重置列表顺序
  init(dataList) {
    // 列表项高度
    const ITEM_HEIGHT = 40
    // 列表项上外边距
    const ITEM_MARGIN_TOP = 14
    let newDataList = dataList.map((item, index) => {
      item.id = index
      // 重置单项的y坐标(组件默认是绝对定位 left:0  top:0 )
      item.y = (ITEM_HEIGHT + ITEM_MARGIN_TOP) * index + ITEM_MARGIN_TOP
      return item
    })

    this.setData({
      dataList: newDataList
    })
  },
  // 移动中-获取移动元素的id,实时获取移动元素的y坐标
  moving(e) {
    this.setData({
      moveId: e.currentTarget.dataset.moveid,
      endY: e.detail.y,
    })
  },
  // 移动后
  moved() {
    let {
      dataList,
      moveId,
      endY
    } = this.data
    let newDataList = JSON.parse(JSON.stringify(dataList))
    newDataList[moveId].y = endY
    newDataList = newDataList.sort((a, b) => a.y - b.y)
    this.init(newDataList)
  }
})

wxss代码:

.itemBox {
  background: white;
  width: 100%;
  height: 80rpx;
  line-height: 80rpx;
  padding: 0rpx 20rpx;
  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .4);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值