微信小程序 多图上传转base64 九宫格 图片拖拽 单张点击放大

效果:
在这里插入图片描述
html:

<view class="release_box">
//顶部输入框 类似微信朋友圈
  <view class="release_text">
    <textarea bindinput='gaysText' placeholder='分享新鲜事~' maxlength='140' auto-height='true' style='height:{{textHeight}}rpx;' class='every'/>
  </view>

  <view class="clearfix">

    <view class='outer clearfix'>
      <view class='inner clearfix'>
        <movable-area class='clearfix'>
        //tempFilePaths是我上传base64后,后台传回来的图片数组
          <block wx:for="{{tempFilePaths}}">
            <view class='pic_box item' id="{{item.index}}" data-index='{{index}}' bindlongpress='_longtap' bindtouchstart='touchs' bindtouchend='touchend' bindtouchmove='touchm'  data-img='{{item.image_url}}'>
            //这里为什么要用data-list,因为九宫格,单张点击图片放大后,实现了左右滑动切换大图
              <image src="{{item.image_url}}" class='gays_pic_C' mode="widthFix" data-id="{{index}}" data-list="{{tempFilePaths}}" data-src="{{item.image_url}}" wx:for-item="item" bindtap='previewImage'></image>
              //关闭按钮 一个小×
              <image src="../../images/dynamic/close.png" class="del_pic" bindtap='deletePic' data-id="{{index}}"></image>
            </view>
          </block>
         //把长按图片时候的图片路径 传过来
          <movable-view x="{{x}}" y="{{y}}" direction="all" damping="{{5000}}" friction="{{1}}" disabled="{{disabled}}">
            <view class='item-move' hidden='{{hidden}}'>
             <image src="{{maskImg}}" mode="widthFix"></image>
            </view>
          </movable-view>
          <view class="nullPic" bindtap='choose' wx:if="{{tempFilePaths.length < 9}}">
            <image src="/images/release/cha.png"></image>
          </view>
        </movable-area>

      </view>
    </view>
  </view>

</view>

<button disabled="{{replayMore}}" class="{{arrayNull?'release_btn_null':'release_btn'}}" bindtap='submit'>发表</button>

js:

const app = getApp()
var util = require('../../utils/util');
Page({

  /**
   * 页面的初始数据
   */
  data: {
    arrayNull: true,
    releaseText: '',
    replayMore: false,
    hidden: true,
    flag: false,
    x: 0,
    y: 0,
    tempFilePaths: [],
    disabled: true,
    elements: [],
    textHeight:''
  },

  //上传图片,获取临时路径,然后循环单张去取base64--调用接口--取到返回图片url--contact
  choose: function () {
    var that = this,
      tempFilePaths = this.data.tempFilePaths;
    wx.chooseImage({
      count: 9 - tempFilePaths.length, // 最多可以选择的图片张数,默认9
      sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认二者都有
      sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
      success: function (res) {
        for (let i = 0; i < res.tempFilePaths.length; i++) {
          wx.getFileSystemManager().readFile({
            filePath: res.tempFilePaths[i], //选择图片返回的相对路径
            encoding: 'base64', //编码格式
            success: res => {
              var baseImg = 'data:image/png;base64,' + res.data;
              wx.showLoading({
                title: '上传中',
              })
              app.request({
                url: 'moments/uploadImage',
                method: "post",
                data: {
                  base64_img: baseImg
                },
                success: function (res) {
                  wx.hideLoading()
                  if (res.code == 1) {
                    tempFilePaths = tempFilePaths.concat(res.data);
                    that.setData({
                      tempFilePaths: tempFilePaths
                    },()=>{
                    //获取到图片url的数组后,回调里执行下面的原因是:为了拖拽初始化
                      var query = wx.createSelectorQuery();
                      var nodesRef = query.selectAll(".item");
                      nodesRef.fields({
                        dataset: true,
                        rect: true
                      }, (result) => {
                        that.setData({
                          elements: result
                        })
                      }).exec()
                    });
                  } else {
                    wx.showToast({
                      title: res.msg,
                      icon: 'none',
                      duration: 2000
                    })
                  }
                },
              });
            }
          })
        }
      }
    })
  },

  //获取输入内容并判断
  gaysText(e) {
    this.setData({
      releaseText: e.detail.value
    })
    if (e.detail.value != "" || this.data.tempFilePaths.length != 0) {
      this.setData({
        arrayNull: false
      })
    } else {
      this.setData({
        arrayNull: true
      })
    }
   //获取顶部textarea的高度,下面会用到,往下看
    var query = wx.createSelectorQuery();
    //选择id
    var that = this;
    query.select('.every').boundingClientRect(function (rect) {
      that.setData({
        textHeight: rect.height
      })
    }).exec();


  },
  //删除图片
  deletePic: function (e) {
    var images = this.data.tempFilePaths;
    var index = e.currentTarget.dataset.id;
    images.splice(index, 1);
    this.setData({
      tempFilePaths: images
    })
    if (this.data.tempFilePaths.length != 0 || this.data.releaseText != "") {
      this.setData({
        arrayNull: false
      })
    } else {
      this.setData({
        arrayNull: true
      })
    }
  },
  //放大图片
  previewImage: function (event) {
    var src = event.currentTarget.dataset.src; //获取data-src
    var imgList = event.currentTarget.dataset.list; //获取data-list
    //要把对象中需要的键值对拿出来,放进一个数组,Object.keys是为了取到对象的长度进行遍历
    var imgArr = [];
    var objkeys = Object.keys(imgList);
    for (var i = 0; i < objkeys.length; i++) {
      imgArr.push(imgList[i].image_url + '-default');
    }
    //图片预览
    wx.previewImage({
      current: src, // 当前显示图片的http链接
      urls: imgArr // 需要预览的图片http链接列表
    })
  },

//提交 提交没什么看头 就获取数据提交就行了
  submit() {
    wx.showLoading({
      title: '提交中',
      mask: true
    });

    var text = this.data.releaseText;
    var pic = this.data.tempFilePaths;
    var that = this;

    that.setData({
      replayMore: true
    })

    var imgArray = []
    for (var i in pic) {
      imgArray.push(pic[i].image_id)
    }
    var imgArrayFin = {}
    imgArrayFin = imgArray;
    var imgArrayFin = JSON.stringify(imgArrayFin)
    app.request({
      url: '/moments/sendMoment',
      method: "post",
      data: {
        content: text,
        images: imgArrayFin
      },
      success: function (res) {
        wx.hideLoading();
        if (res.code == 1) {
          wx.showToast({
            title: '发布成功',
            icon: 'none',
            duration: 1500
          })
          setTimeout(function () {
            wx.reLaunch({
              url: '../pageIndex/dynamic/index'
            })
          }, 1500)
        } else {
          wx.showToast({
            title: res.msg,
            icon: 'none',
            duration: 2000
          })
          that.setData({
            replayMore: false
          })
        }
      }
    })
  },

  //长按
  _longtap: function (e) {
     var maskImg = e.currentTarget.dataset.img
    this.setData({
      maskImg: maskImg
    })
    const detail = e.detail;
    this.setData({
      x: e.currentTarget.offsetLeft,
      y: e.currentTarget.offsetTop
    })
    this.setData({
      hidden: false,
      flag: true
    })
  },
  //触摸开始
  touchs: function (e) {
    this.setData({
      beginIndex: e.currentTarget.dataset.index
    })
  },
  //触摸结束
  touchend: function (e) {
    if (!this.data.flag) {
      return;
    }
    const x = e.changedTouches[0].pageX
    const y = e.changedTouches[0].pageY
    const list = this.data.elements;
    let data = this.data.tempFilePaths
    for (var j = 0; j < list.length; j++) {
      const item = list[j];
      if (x > item.left && x < item.right && y > item.top && y < item.bottom) {
        const endIndex = item.dataset.index;
        const beginIndex = this.data.beginIndex;
        //向后移动
        if (beginIndex < endIndex) {
          let tem = data[beginIndex];
          for (let i = beginIndex; i < endIndex; i++) {
            data[i] = data[i + 1]
          }
          data[endIndex] = tem;
        }
        //向前移动
        if (beginIndex > endIndex) {
          let tem = data[beginIndex];
          for (let i = beginIndex; i > endIndex; i--) {
            data[i] = data[i - 1]
          }
          data[endIndex] = tem;
        }

        this.setData({
          tempFilePaths: data
        })
      }
    }
    this.setData({
      hidden: true,
      flag: false
    })
  },
  //滑动
  touchm: function (e) {
  **//请着重 好好的 看看这里 朋友们 拖拽会不会出bug 就看这里了**
//===============================>
      this.setData({
          x: x - 75,
          y: y - this.data.textHeight*2
        })
        为什么这里要这么写,因为x,y是你拖拽view距离顶部和左边的距离,需要剪掉,如果不减,拖拽会很变态,我这里为什么用了 this.data.textHeight,因为我顶部有个textarea,高是auto的,所以我要获取textarea的高度,这里获取到的高度是px,*2变成rpx
//===============================>
    if (this.data.flag) {
      const x = e.touches[0].pageX
      const y = e.touches[0].pageY
      if (this.data.textHeight>70){
        this.setData({
          x: x - 75,
          y: y - this.data.textHeight*2
        })
      }else{
        this.setData({
          x: x - 75,
          y: y - 140
        })
      }
  
    }
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

css:

page{
  background: #F7F7F7
}

.clearfix::before,
.clearfix::after {
    content: ".";
    display: block;
    height: 0;
    visibility: hidden;
}
.clearfix:after {clear: both;}
.clearfix {zoom: 1;}

.release
_box{
  background: #fff;
  padding: 32rpx;
}
.nullPic{
  width: 222rpx;
  height: 222rpx;
  background: #E6E6E6;
  text-align: center;
  float: left;
  margin-left: 10rpx;
}

.nullPic image{
  width: 100rpx;
  height: 100rpx;
   position: relative;
  top: 60rpx;
}

.release_text{
  min-height: 132rpx;
}

.release_text textarea{
  width: 100%;
   min-height: 132rpx;
   height: auto;
   margin-bottom:30rpx;

}

.pic_box{
 float: left;
   margin-bottom: 16rpx !important;
  margin-left: 10rpx;
   width: 222rpx;
  height: 222rpx;
  overflow: hidden;
  position: relative
}


.gays_pic_C{
  width: 222rpx;
}

.pic_box:nth-child(1){
  margin: 0
}
.pic_box:nth-child(4){
  margin: 0
}
.pic_box:nth-child(7){
  margin: 0
}

.release_btn_null{
  width: 120rpx;
  height: 60rpx;
  background: #CCCCCC;
  font-size: 24rpx;
  color: #fff;
  float: right;
  margin-top: 40rpx;
  margin-right: 32rpx;
}

.release_btn{
    width: 120rpx;
  height: 60rpx;
  background: #FFA300;
  font-size: 24rpx;
  color: #fff;
  float: right;
  margin-top: 40rpx;
  margin-right: 32rpx;
}

.del_pic{
  width:40rpx;
  height: 40rpx;
  position: absolute;
  right: 0;
  top: 0 
}

/* ===> */

/* test/test.wxss */
.outer{
  width: 100%;
  max-height: 800rpx
}
.inner{
  width: 100%;
  height: 100%;
}
movable-area{
  width: 100%;
  height: 100%;
}
.item{
  float: left;
  width: 222rpx;
  height: 222rpx;
}

.index-first{
  display: inline-block;
  width: 15rpx;
  height: 222rpx;
  background: firebrick;
}

.item-move{
  display: inline-block;
 width: 222rpx;
  height: 222rpx;
  overflow: hidden
}

.item-move image{
  width: 222rpx;
}

//结束 我拖拽是参考这位大神的
https://blog.csdn.net/haicome/article/details/82664344

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值