123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- Component({
- options: {
- multipleSlots: true,
- },
- properties: {
- // 图片大小,单位px
- previewSize: {
- type: Number,
- value: 100,
- },
- // 初始化图片数组,用于回显
- defaultImgList: {
- type: Array,
- value: [],
- observer(list) {
- if (list?.length && !this.data.dragImgList.length) {
- const dragImgList = this.getDragImgList(list);
- this.setUploaPosition(dragImgList.length);
- this.setData({
- dragImgList,
- });
- }
- }
- },
- // 图片上传数量限制
- maxCount: {
- type: Number,
- value: 9,
- },
- // 列数
- columns: {
- type: Number,
- value: 3,
- },
- // 图片间隔 单位:px
- gap: {
- type: Number,
- value: 9,
- },
- // 删除样式
- deleteStyle: {
- type: String,
- value: '',
- }
- },
- data: {
- /**
- * 拖拽图片列表
- * {
- * src: string, // 图片路径
- * key: number, //
- * id: number, // for循环遍历使用, 不会改变, 创建时自增id
- * tranX: number, // x轴位移距离
- * tranY: number, // y轴位移距离
- * }[]
- */
- dragImgList: [],
- containerRes: {
- top: 0, // 容器距离页面顶部距离 px
- left: 0, // 容器距离页面左边距离 px
- width: 0, // 容器宽度 px
- height: 0, // 容器高度 px
- }, // 拖拽容器属性
- currentKey: -1, // 正在拖拽图片的key
- currentIndex: -1, // 正在拖拽图片的index
- tranX: 0, // 正在拖拽图片移动的x距离
- tranY: 0, // 正在拖拽图片移动的y距离
- uploadPosition: { // upload上传图标位移距离
- tranX: 0,
- tranY: 0,
- }
- },
- lifetimes: {
- ready() {
- this.createSelectorQuery()
- .select(".drag-container")
- .boundingClientRect(({ top, left }) => {
- this.setData({
- ['containerRes.top']: top,
- ['containerRes.left']: left,
- });
- }).exec();
- }
- },
- methods: {
- /**
- * 长按图片
- */
- longPress(e) {
- const index = e.mark.index;
- const { pageX, pageY } = e.touches[0];
- const { previewSize, containerRes: { top, left } } = this.data;
- this.setData({
- currentIndex: index,
- tranX: pageX - previewSize / 2 - left,
- tranY: pageY - previewSize / 2 - top,
- });
- },
- /**
- * touchMove
- */
- touchMove(e) {
- // 如果currentIndex < 0,说明并没有触发longPress
- if (this.data.currentIndex < 0) {
- return;
- }
- const { pageX, pageY } = e.touches[0];
- const { previewSize, containerRes: { top, left } } = this.data;
- const tranX = pageX - previewSize / 2 - left;
- const tranY = pageY - previewSize / 2 - top;
- this.setData({
- tranX,
- tranY
- });
- // 对比当前移动的key和停放位置的key,如果不一样就修改位置
- const currentKey = e.mark.key;
- const moveKey = this.getMoveKey(tranX, tranY);
- // 当移动的key和正在停放位置的key相等,就无须处理
- if (currentKey === moveKey || this.data.currentKey === currentKey) {
- return;
- }
- this.data.currentKey = currentKey;
- this.replace(currentKey, moveKey);
- },
- /**
- * 计算移动中的key
- * @param tranX 正在拖拽图片的tranX
- * @param tranY 正在拖拽图片的tranY
- */
- getMoveKey(tranX, tranY) {
- const { dragImgList: list, previewSize, columns } = this.data;
- const _getPositionNumber = (drag, limit) => {
- const positionNumber = Math.round(drag / previewSize);
- return positionNumber >= limit ? limit - 1 : positionNumber < 0 ? 0 : positionNumber;
- }
- const endKey = columns * _getPositionNumber(tranY, Math.ceil(list.length / columns)) + _getPositionNumber(tranX, columns);
- return endKey >= list.length ? list.length - 1 : endKey;
- },
- /**
- * 生成拖拽后的新数组
- * @param start 拖拽起始的key
- * @param end 拖拽结束的key
- */
- replace(start, end) {
- const dragImgList = this.data.dragImgList;
- dragImgList.forEach((item) => {
- if (start < end) {
- if (item.key > start && item.key <= end) item.key--;
- else if (item.key === start) item.key = end;
- } else if (start > end) {
- if (item.key >= end && item.key < start) item.key++;
- else if (item.key === start) item.key = end;
- }
- });
- this.getListPosition(dragImgList);
- },
- /**
- * 计算数组的位移位置
- * @param list 拖拽图片数组
- */
- getListPosition(list) {
- const { previewSize, columns, gap } = this.data;
- const dragImgList = list.map((item) => {
- item.tranX = (previewSize + gap) * (item.key % columns);
- item.tranY = Math.floor(item.key / columns) * (previewSize + gap);
- return item;
- })
- this.setData({
- dragImgList,
- });
- this.updateEvent(dragImgList);
- },
- /**
- * touchEnd
- */
- touchEnd() {
- this.setData({
- tranX: 0,
- tranY: 0,
- currentIndex: -1,
- });
- this.data.currentKey = -1;
- },
- /**
- * updateEvent
- * @describe 上传删除拖拽后触发事件把列表数据发给页面
- */
- updateEvent(dragImgList) {
- const list = [...dragImgList].sort((a, b) => a.key - b.key).map((item) => item.src);
- this.triggerEvent('updateImageList', {
- list,
- });
- },
- /**
- * 上传图片
- */
- async uploadImage() {
- let { dragImgList, maxCount } = this.data;
- try {
- const res = await wx.chooseMedia({
- count: maxCount - dragImgList.length,
- mediaType: ['image'],
- });
- const imgList = this.getDragImgList(res?.tempFiles?.map(({ tempFilePath }) => tempFilePath) || [], false);
- dragImgList = dragImgList.concat(imgList);
- this.setUploaPosition(dragImgList.length);
- this.setData({
- dragImgList,
- });
- this.updateEvent(dragImgList);
- } catch (error) {
- console.log(error);
- }
- },
- /**
- * 改变图片数量后获取容器宽高
- * @parma listLength 数组长度
- */
- getContainerRect(listLength) {
- const { columns, previewSize, maxCount, gap } = this.data;
- const number = listLength === maxCount ? listLength : listLength + 1;
- const row = Math.ceil(number / columns)
- return {
- width: columns * previewSize + (columns - 1) * gap,
- height: row * previewSize + gap * (row - 1),
- };
- },
- /**
- * 根据图片列表生成拖拽列表数据结构
- * @param list 图片src列表
- * @param init 是否是初始化
- */
- getDragImgList(list, init = true) {
- let { dragImgList, previewSize, columns, gap } = this.data;
- return list.map((item, index) => {
- const i = (init ? 0 : dragImgList.length) + index;
- return {
- tranX: (previewSize + gap) * (i % columns),
- tranY: Math.floor(i / columns) * (previewSize + gap),
- src: item,
- id: i,
- key: i,
- };
- });
- },
- /**
- * 修改上传区域位置
- * @param listLength 数组长度
- */
- setUploaPosition(listLength) {
- const { previewSize, columns, gap } = this.data;
- const uploadPosition = {
- tranX: listLength % columns * (previewSize + gap),
- tranY: Math.floor(listLength / columns) * (previewSize + gap),
- };
- const { width, height } = this.getContainerRect(listLength);
- this.setData({
- uploadPosition,
- ['containerRes.width']: width,
- ['containerRes.height']: height,
- });
- },
- /**
- * 删除图片
- */
- deleteImg(e) {
- const key = e.mark.key;
- const list = this.data.dragImgList.filter((item) => item.key !== key);
- list.forEach((item) => {
- item.key > key && item.key--;
- });
- this.getListPosition(list);
- this.setUploaPosition(list.length);
- },
- }
- })
|