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

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

一、效果展示在这里插入图片描述

**博主的小程序首页也采用了该示例代码,可以在威信中搜索:我的百宝工具箱
在这里插入图片描述

二、示例代码

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*100previewSize: {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><wxDragImgdefaultImgList="{{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"}
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/888824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过 FRP 实现 P2P 通信:控制端与被控制端配置指南

本文介绍了如何通过 FRP 实现 P2P 通信。FRP&#xff08;Fast Reverse Proxy&#xff09;是一款高效的内网穿透工具&#xff0c;能够帮助用户突破 NAT 和防火墙的限制&#xff0c;将内网服务暴露到公网。通过 P2P 通信方式&#xff0c;FRP 提供了更加高效、低延迟的网络传输方式…

php7.4安装pg扩展-contos7

今天接到一个需求&#xff0c;就是需要用thinkphp6链接pg(postgresql)数据库。废话不多说&#xff0c;直接上操作步骤 一、安装依赖 yum install -y sqlite-devel libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libcurl libcurl-devel libjpeg libjpeg-dev…

CentOS7.X 安装RustDesk自建服务器实现远程桌面控制

参照文章CentOS安装RustDesk自建服务器中间总有几个位置出错&#xff0c;经实践做个记录防止遗忘 一 环境&工具准备 1.1 阿里云轻量服务器、Centos7系统、目前最高1.1.11版本rustdesk-server-linux-amd64.zip 1.2 阿里云轻量服务器–安全组–开放端口&#xff1a;TCP(21…

TCP Analysis Flags 之 TCP Spurious Retransmission

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

Java线程的interrupt中断、wait-notify/all(源码级分析)

实例方法&#xff1a; interrupt()方法是设置结束阻塞(sleep、wait等)&#xff0c;并且设置中断标记true isInterrupted()判断当前是否中断 静态方法&#xff1a; Thread.interrupted():调用这个方法的线程中断标记位还原为false 那么好&#xff0c;既然上面的方法作用是清…

Burp Suite 实战指南:Proxy 捕获与修改流量、HTTP History 筛选与分析

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

12月第1周AI资讯

阅读时间:3-4min 更新时间:2024.12.2-2024.12.6 目录 OpenAI CEO Sam Altman 预告“12天OpenAI”系列活动 腾讯HunyuanVideo:130亿参数的开源视频生成模型 李飞飞的World Labs发布空间智能技术预览版 中科院联手腾讯打造“AI带货王”AnchorCrafter OpenAI CEO Sam Alt…

从零开始学TiDB(1) 核心组件架构概述

首先TiDB深度兼容MySQL 5.7 1. TiDB Server SQL语句的解析与编译&#xff1a;首先一条SQL语句最先到达的地方是TiDB Server集群&#xff0c;TiDB Server是无状态的&#xff0c;不存储数据&#xff0c;SQL 发过来之后TiDB Server 负责 解析&#xff0c;优化&#xff0c;编译 这…

记录一次使用git无权限的问题排查

正常的配置了公私钥之后&#xff0c;在gitlab中也存储了配对的公钥&#xff0c;但当使用git clone 时&#xff0c;总是报无权限 由于在这台机器中添加了多个公私钥&#xff0c;有点复杂&#xff0c;我们可以使用命令 ssh -vvvT 调试一下 ssh -vvvT yourGitlabAddr

python调用GPT-4o实时音频 Azure OpenAI GPT-4o Audio and /realtime

发现这块网上信息很少&#xff0c;记录一下 微软azure入口 https://learn.microsoft.com/zh-cn/azure/ai-services/openai/realtime-audio-quickstart?pivotsprogramming-language-ai-studio sdk文档 https://github.com/azure-samples/aoai-realtime-audio-sdk?tabread…

fastadmin 后台插件制作方法

目录 一&#xff1a;开发流程 二&#xff1a;开发过程 &#xff08;一&#xff09;&#xff1a;后台功能开发 &#xff08;二&#xff09;&#xff1a;功能打包到插件目录 &#xff08;三&#xff09;&#xff1a;打包插件 &#xff08;四&#xff09;&#xff1a;安装插件…

Kafka单机及集群部署及基础命令

目录 一、 Kafka介绍1、kafka定义2、传统消息队列应用场景3、kafka特点和优势4、kafka角色介绍5、分区和副本的优势6、kafka 写入消息的流程 二、Kafka单机部署1、基础环境2、iptables -L -n配置3、下载并解压kafka部署包至/usr/local/目录4、修改server.properties5、修改/etc…

Docker部署的gitlab升级的详细步骤(升级到17.6.1版本)

文章目录 一、Gitlab提示升级信息二、老版本的docker运行gitlab命令三、备份老版本Gitlab数据四、确定升级路线五、升级(共分3个版本升级)5.1 升级第一步(17.1.2 > 17.3.7)5.2 升级第二步(17.3.7 > 17.5.3)5.3 升级第三步(17.5.3 > 17.6.1) 六、web端访问gitlab服务 一…

在Java的xml的sql语句里面的某一个参数是list集合的时候

经常在Java里面&#xff0c;遇到这样的问题&#xff0c;sql的一个查询语句&#xff0c;它的某一个参数是一个List集合&#xff0c;然而&#xff0c;在xml.mapper文件里面的时候&#xff0c;不知道如何去组成这个查询语句&#xff0c;不知道兄弟们是否经常忘记如何去写这个语句&…

前端技术(23) : 聊天页面

来源: GPT生成之后微调 效果图 HTML代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>聊天</t…

内存图及其画法

所有的文件都存在硬盘上&#xff0c;首次使用的时候才会进入内存 进程&#xff1a;有自己的Main方法&#xff0c;并且依赖自己Main运行起来的程序。独占一块内存区域&#xff0c;互不干扰。内存中有一个一个的进程。 操作系统只认识c语言。操作系统调度驱动管理硬件&#xff0…

树与图深度优先遍历——acwing

题目一&#xff1a;树的重心 846. 树的重心 - AcWing题库 分析 采用暴力枚举&#xff0c;试探每个点&#xff0c;除去之后&#xff0c;连通分量最大值是多少&#xff0c; 各个点的最大值找最小的 因为可以通过 dfs 来得到 根u以下点数&#xff0c;以及可以求各分树的点数&am…

Qt Qtablewidget 标题 QHeaderView 增加可选框 QcheckBox

创建自定义QHeaderView #pragma once#include <QObject> #include <QHeaderView> #include <QPainter> #include <QMouseEvent>class SSHeaderView : public QHeaderView {Q_OBJECTprivate:bool isChecked;int m_checkColIdx; public:SSHeaderView(i…

Data Uncertainty Learning in Face Recognition 论文阅读

Data Uncertainty Learning in Face Recognition 论文阅读 Abstract1. Introduction2. Related Work3. Methodology3.1. Preliminaries3.2. Classification-based DUL for FR3.3. Regression-based DUL for FR3.4. Discussion of Related Works 4. Experiments4.1. Datasets an…

基础算法——搜索与图论

搜索与图论 图的存储方式2、最短路问题2.1、Dijkstra算法&#xff08;朴素版&#xff09;2.2、Dijkstra算法&#xff08;堆优化版&#xff09;2.3、Bellman-Ford算法2.4、SPFA求最短路2.5、SPFA判负环2.6、Floyd算法 图的存储方式 2、最短路问题 最短路问题可以分为单源最短路…