微信小程序实现图片拖拽调换位置效果(开箱即用)

 更新时间:2024年12月07日 10:37:44   作者:古口古  
本篇文章给大家介绍如何在微信小程序中实现图片的拖拽排序和删除功能,通过创建自定义组件并使用示例代码,代码简单易懂,感兴趣的朋友跟随小编一起看看吧

在编写类似发布朋友圈功能的功能时,需要实现图片的拖拽排序,删除图片等功能。

一、效果展示

二、示例代码

1.1、在自己的小程序中创建组件

1.2、组件源码 wxml代码

<view class="drag-container">
  <view wx:for="{{dragImgList}}" wx:key="id"
  style="transform: translate({{index === currentIndex ? tranX : item.tranX}}px, {{index === currentIndex ? tranY : item.tranY}}px); z-index: {{index === currentIndex ? 10 : 1}}; width: {{previewSize}}px; height: {{previewSize}}px;" 
  class="drag-item drag-item-transition" 
  mark:index="{{index}}" mark:key="{{item.key}}" 
  catch:longpress="longPress" 
  catch:touchmove="touchMove" 
  catch:touchend="touchEnd">
    <image class="drag-item-img" src="{{item.src}}" mode="aspectFill"/>
    <view catch:tap="deleteImg" mark:key="{{item.key}}" class="drag-item-delete">
      <view class="drag-item-delete_default" style="{{deleteStyle}}">x</view>
    </view>
  </view>
  <view bindtap="uploadImage" class="drag-item drag-upload" hidden="{{dragImgList.length >= maxCount}}" style="transform: translate({{uploadPosition.tranX}}px, {{uploadPosition.tranY}}px); width: {{previewSize}}px; height: {{previewSize}}px;">
    <text>+</text>
  </view>
</view>

wxss代码

.drag-container {
  position: relative;
  left: 30rpx;
  top: 20rpx;
}
.drag-item {
  position: absolute;
  top: 0;
  left: 0;
}
.drag-item-transition {
  transition: transform 0.1s
}
.drag-item-img {
  width: 100%;
  height: 100%;
}
.drag-item-delete {
  position: absolute;
  top: 0;
  right: 0;
}
.drag-item-delete_default {
  display: flex;
  width: 21px;
  height: 15px;
  line-height: 10px;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.7);
  border-radius: 0 0 0 12px;
  color: #FEFEFE;
}
.drag-upload {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 2px dashed silver;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  font-size: 70px;
}
.drag-upload text{
  margin-top: -20%;
  color: silver;
}

js代码

Component({
  properties: {
    // 每个格子的大小 100*100
    previewSize: {
      type: Number,
      value: 100
    },
    // 默认图片列表
    defaultImgList: {
      type: Array,
      value: [],
      observer(t) {
        if (t?.length && !this.data.dragImgList.length) {
          const e = this.getDragImgList(t);
          this.setUploaPosition(e.length), this.setData({
            dragImgList: e
          })
        }
      }
    },
    // 最大个数
    maxCount: {
      type: Number,
      value: 9
    },
    // 每行列数
    columns: {
      type: Number,
      value: 3
    },
    // 每个格子之间的间隔
    gap: {
      type: Number,
      value: 9
    },
    deleteStyle: {
      type: String,
      value: ""
    }
  },
  data: {
    dragImgList: [],
    containerRes: {
      top: 0,
      left: 0,
      width: 0,
      height: 0
    },
    currentKey: -1,
    currentIndex: -1,
    tranX: 0,
    tranY: 0,
    uploadPosition: {
      tranX: 0,
      tranY: 0
    }
  },
  lifetimes: {
    ready() {
      this.createSelectorQuery().select(".drag-container").boundingClientRect((({
        top: t,
        left: e
      }) => {
        this.setData({
          "containerRes.top": t,
          "containerRes.left": e
        })
      })).exec()
    }
  },
  methods: {
    longPress(t) {
      const e = t.mark.index,
        {
          pageX: a,
          pageY: i
        } = t.touches[0],
        {
          previewSize: s,
          containerRes: {
            top: n,
            left: r
          }
        } = this.data;
      this.setData({
        currentIndex: e,
        tranX: a - s / 2 - r,
        tranY: i - s / 2 - n
      })
    },
    touchMove(t) {
      if (this.data.currentIndex < 0) return;
      const {
        pageX: e,
        pageY: a
      } = t.touches[0], {
        previewSize: i,
        containerRes: {
          top: s,
          left: n
        }
      } = this.data, r = e - i / 2 - n, o = a - i / 2 - s;
      this.setData({
        tranX: r,
        tranY: o
      });
      const h = t.mark.key,
        g = this.getMoveKey(r, o);
      h !== g && this.data.currentKey !== h && (this.data.currentKey = h, this.replace(h, g))
    },
    getMoveKey(t, e) {
      const {
        dragImgList: a,
        previewSize: i,
        columns: s
      } = this.data, n = (t, e) => {
        const a = Math.round(t / i);
        return a >= e ? e - 1 : a < 0 ? 0 : a
      }, r = s * n(e, Math.ceil(a.length / s)) + n(t, s);
      return r >= a.length ? a.length - 1 : r
    },
    replace(t, e) {
      const a = this.data.dragImgList;
      a.forEach((a => {
        t < e ? a.key > t && a.key <= e ? a.key-- : a.key === t && (a.key = e) : t > e && (a.key >= e && a.key < t ? a.key++ : a.key === t && (a.key = e))
      })), this.getListPosition(a)
    },
    getListPosition(t) {
      const {
        previewSize: e,
        columns: a,
        gap: i
      } = this.data, s = t.map((t => (t.tranX = (e + i) * (t.key % a), t.tranY = Math.floor(t.key / a) * (e + i), t)));
      this.setData({
        dragImgList: s
      }), this.updateEvent(s)
    },
    touchEnd() {
      this.setData({
        tranX: 0,
        tranY: 0,
        currentIndex: -1
      }), this.data.currentKey = -1
    },
    updateEvent(t) {
      const e = [...t].sort(((t, e) => t.key - e.key)).map((t => t.src));
      this.triggerEvent("updateImageList", {
        list: e
      })
    },
    async uploadImage() {
      let {
        dragImgList: t,
        maxCount: e
      } = this.data;
      try {
        const a = await wx.chooseMedia({
            count: e - t.length,
            mediaType: ["image"]
          }),
          i = this.getDragImgList(a?.tempFiles?.map((({
            tempFilePath: t
          }) => t)) || [], !1);
        t = t.concat(i), this.setUploaPosition(t.length), this.setData({
          dragImgList: t
        }), this.updateEvent(t)
      } catch (t) {
        console.log(t)
      }
    },
    getContainerRect(t) {
      const {
        columns: e,
        previewSize: a,
        maxCount: i,
        gap: s
      } = this.data, n = t === i ? t : t + 1, r = Math.ceil(n / e);
      return {
        width: e * a + (e - 1) * s,
        height: r * a + s * (r - 1)
      }
    },
    getDragImgList(t, e = !0) {
      let {
        dragImgList: a,
        previewSize: i,
        columns: s,
        gap: n
      } = this.data;
      return t.map(((t, r) => {
        const o = (e ? 0 : a.length) + r;
        return {
          tranX: (i + n) * (o % s),
          tranY: Math.floor(o / s) * (i + n),
          src: t,
          id: o,
          key: o
        }
      }))
    },
    setUploaPosition(t) {
      const {
        previewSize: e,
        columns: a,
        gap: i
      } = this.data, s = {
        tranX: t % a * (e + i),
        tranY: Math.floor(t / a) * (e + i)
      }, {
        width: n,
        height: r
      } = this.getContainerRect(t);
      this.setData({
        uploadPosition: s,
        "containerRes.width": n,
        "containerRes.height": r
      })
    },
    deleteImg(t) {
      const e = t.mark.key,
        a = this.data.dragImgList.filter((t => t.key !== e));
      a.forEach((t => {
        t.key > e && t.key--
      })), this.getListPosition(a), this.setUploaPosition(a.length)
    }
  }
});

json代码

{
  "component": true,
  "usingComponents":{}
}

1.3、在自己的小程序中新建page

1.4、新建page的源码 wxml代码

<view>
	<wxDragImg
    	defaultImgList="{{imgList}}"
		previewSize="{{120}}"
		maxCount="{{9}}"
		columns="{{3}}"
		gap="{{10}}"
    	bind:updateImageList="updateImageList">
  </wxDragImg>
</view>

js代码

Page({
  data: {
    imgList: []
  },
  onLoad() {},
  updateImageList(e) {
    console.log(e)
  }
})

json代码

{
  "usingComponents": {
    "wxDragImg": "../wx-drag-img"
  }
}

到此这篇关于微信小程序实现图片拖拽调换位置效果 -- 开箱即用的文章就介绍到这了,更多相关微信小程序图片拖拽调换位置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解如何使用babel进行es6文件的编译

    详解如何使用babel进行es6文件的编译

    这篇文章主要介绍了详解如何使用babel进行es6文件的编译,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • options预检请求的前后端解决方式详解

    options预检请求的前后端解决方式详解

    这篇文章主要为大家介绍了options预检请求的前后端解决方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • javascript简单计算器 可美化

    javascript简单计算器 可美化

    javascript简单计算器 可美化,需要的朋友可以测试下。参考下实现原理。
    2011-10-10
  • JavaScript中的undefined学习总结

    JavaScript中的undefined学习总结

    这篇文章主要是对JavaScript中的undefined进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-11-11
  • fixedBox固定div漂浮代码支持ie6以上大部分主流浏览器

    fixedBox固定div漂浮代码支持ie6以上大部分主流浏览器

    本例为大家分享的是fixedBox固定div漂浮代码支持ie6以上大部分浏览器,需要的朋友可以参考下
    2014-06-06
  • 微信小程序分包加载代码实现方法详解

    微信小程序分包加载代码实现方法详解

    这篇文章主要介绍了微信小程序分包加载代码实现方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 一文搞懂Map与Set的用法和区别解析

    一文搞懂Map与Set的用法和区别解析

    这篇文章主要介绍了一文搞懂Map与Set的用法和区别,文章开头给大家介绍了map和set的基本概念,了解这些基础知识能够帮助我们更好的使用,需要的朋友可以参考下
    2022-06-06
  • Driver.js前端引导页组件的具体使用

    Driver.js前端引导页组件的具体使用

    Driver.js是一个引导插件,本文主要介绍了Driver.js前端引导页组件的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • javascript中比较字符串是否相等的方法

    javascript中比较字符串是否相等的方法

    使用js比较字符串是否相等的方法有很多,在本文为大家介绍一个从外国网站看到的方法,感兴趣的朋友可以参考下哈,希望对大家学习js有所帮助
    2013-07-07
  • 浅谈javascript中的闭包

    浅谈javascript中的闭包

    Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态语言C/C++的程序员来说是一个新的语言特性。本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包。
    2015-05-05

最新评论