Процедуры малых квадратов микроканала для получения изображений перетаскивания

Апплет WeChat

Есть запрос на первое время реализовать картинки для сортировки перетаскиванием.Просто будет соприкасаться с апплетами WeChat,а у меня много информации,но еще много непонятных мест,и наконец это осознаю, поэтому я записываю это здесь.Я надеюсь помочь другим, если есть неправильная запись или ее можно улучшить, вы можете сказать мне, спасибо.

визуализация

Реализовать идеи

макет

moveable-areaа такжеmoveable-viewдве этикетки.

moveable-areaЭто область перетаскивания, ширина которой должна быть высокой. Из-за размера картинки у меня экран настраивается динамически, поэтомуmoveable-areaФиксированная ширина 100%, общая высота определяется высотой загруженных изображений, поэтому в начале времени я устанавливаю минимальную высоту.

moveable-viewmoveable-viewИзображение.

 <movable-area class="movable-area" style="min-height:{{imageWitdh}}px;height:{{areaHeight}}px">
      <!--图片上传-->
      <view class="image-choose-container">
        <view class="image-item" style="width:{{imageWitdh}}px;height:{{imageWitdh}}px" wx:for="{{images}}" wx:for-item="url" wx:key="url" data-url="{{url}}" data-index="{{index}}" >
            <image src="{{url}}" mode="aspectFill"></image>
            <view class="close">X</view>
        </view>
          <!--图片上传按钮-->
          <view class="add-button" style="width:{{imageWitdh}}px;height:{{imageWitdh}}px" wx:if="{{images.length >= 0 &&images.length < 9}}">+</view>
          <!--确保flex布局justify-content:space-between最后一行左对齐-->
          <view style="width:{{imageWitdh}}px" class="image-item image-item-temp" wx:if="{{images.length%3==1}}"></view>
      </view>
      
      <movable-view class="movable-view" style="width:{{imageWitdh}}px;height:{{imageWitdh}}px" hidden="{{hidden}}" x="{{x}}" y="{{y}}"  direction="all" damping="{{5000}}" friction="{{1}}">
        <image src="{{currentImg}}" wx:if="{{currentImg.length>0}}"></image>
      </movable-view>
    </movable-area>

js для расчета ширины и высоты при инициализации страницы

// 计算图片宽度
_handleComputedImage:function(e){
    const windowWidth = app.globalData.systemInfo.windowWidth;
    const width = windowWidth - 16;
    const imageWitdh = (width - 16) / 3;
    this.setData({
      imageWitdh
    })
},

загрузить изображение

После загрузки изображений нам нужно изменитьmoveable-areaвысота

// 选择图片
  handleChooseImage: function (e) {
    let length = this.data.images.length;
    if (length == 9) {
      wx.showToast({
        title: "亲,最多只能选择九张图哦~",
        icon: "none",
        duration: 2000
      })
      return false;
    }
    var that = this;
    wx.chooseImage({
      count: 9 - this.data.images.length,
      sizeType: ['compressed'], //可选择原图或压缩后的图片
      sourceType: ['album', 'camera'], //可选择性开放访问相册、相机
      success: res => {
        let images = that.data.images;
        for (let i = 0; i < res.tempFilePaths.length;i++){
          images.push(res.tempFilePaths[i]);
        }
        that.setData({
          images
        },function(){
          //上传完之后更新面积
          that._handleComputedArea();
        });
        
      },
      fail: err => console.log(err)
    })
  },

Обновляемая область рассчитывается следующим образом, ее высота определяется выражением.image-choose-containerВид решает:

// 计算movable-area的高度
  _handleComputedArea:function(e){
    let that = this;
    wx.createSelectorQuery().selectAll('.image-choose-container').boundingClientRect(function (rect) {
      that.setData({
        areaHeight: rect[0].height
      })
    }).exec()
  },

p.s. при удалении изображений нам тоже нужно пересчитыватьmoveable-areaвысота.

Длинная нажмите картину

Картинки могут перетащить вид триггерного механизма - это длительное прессование.

  • При длительном нажатии нам нужно вычислить координаты каждой картинки (координаты здесь не фиксированные, когда вашу страницу можно будет перетащить, координаты изменятся) и сохранить ее;
  • Запишите индекс и URL-адрес текущего изображения в массив изображений;
  • показыватьmoveable-view, установите его значения x и y и назначьте URL дочерним элементам под ним.
// 计算每张图片的坐标
  _handleComputedPoints(e){
    let that = this;
    var query = wx.createSelectorQuery();
    var nodesRef = query.selectAll(".image-item");
    nodesRef.fields({
      dataset: true,
      rect: true
    }, (result) => {
      that.setData({
        pointsArr: result
      })
    }).exec()
  },
 // 长按图片
  handleLongTap:function(e){
    // 计算每张图片的坐标
    this._handleComputedPoints();
    this.setData({
      currentImg: e.currentTarget.dataset.url,
      currentIndex: e.currentTarget.dataset.index,
      hidden: false,
      flag: true,
      x: e.currentTarget.offsetLeft,
      y: e.currentTarget.offsetTop
    })
  },

В этот момент нажмите и удерживайте изображение,moveable-view(С границами) появится на картинке.

Движущиеся картинки

мониторmoveable-viewСобытие Catchtouchmove (причина не используя BINDHTUCHMOVE, заключается в том, что в процессе перемещения изображения, если на странице промотана, она приведет к скользянию страницы), запишите текущую позицию пальца на странице E.touches [ 0] .pagex и e.touches [0] .pagey. Чтобы гарантировать, что картина может двигаться с пальцем во время движения пальца, тоmoveable-viewРасстояние x - это e.touches [0] .pagex от пальца, а расстояние y - это e.touches [0] .pagex - расстояние перемещения прокрутки - расстояние.

Для того, чтобы в процессе перемещения картинки картинка всегда могла оказаться в середине пальца, ширина картинки также вычитается из x и y соответственно. (Сравните две картинки, мышь иmoveable-view

  // 移动的过程中
  handleTouchMove:function(e){
    let x = e.touches[0].pageX;
    let y = e.touches[0].pageY;
   // 首先先获得当前image-choose-container距离顶部的距离
    let that = this;
    wx.createSelectorQuery().selectAll('.image-choose-container').boundingClientRect(function (rect) {
      let top = rect[0].top;
      y = y - that.data.scrollTop - top;
      that.setData({
        x: x - that.data.imageWitdh / 2 > 0 ? x - that.data.imageWitdh / 2:0,
        y: y - that.data.imageWitdh / 2 > 0 ? y - that.data.imageWitdh / 2:0,
      })

    }).exec()
  },
// 监听滚动
  onPageScroll:function(e){
    this.data.scrollTop = e.scrollTop;
  }

мониторmoveable-viewСобытие bindtouchend, вычисление текущего значения x, y, сравнение нижнего индекса каждого изображения, определение его перемещения, обновление массива и завершение.

// 移动结束的时候
  handleTouchEnd:function(e){
    if (!this.data.flag) {
      // 非长按情况下
      return;
    }
    let  x = e.changedTouches[0].pageX;
    let y = e.changedTouches[0].pageY - this.data.scrollTop;
    // 每张图片的地址
    const pointsArr = this.data.pointsArr;
    let data = this.data.images;
    for (var j = 0; j < pointsArr.length; j++) {
      const item = pointsArr[j];
      if (x > item.left && x < item.right && y > item.top && y < item.bottom) {
        const endIndex = item.dataset.index;
        const beginIndex = this.data.currentIndex;
        //临时保存移动的目标数据
        let temp = data[beginIndex];
        //将移动目标的下标值替换为被移动目标的下标值
        data[beginIndex] = data[endIndex];
        //将被移动目标的下标值替换为beginIndex
        data[endIndex] = temp;
      }
    }
    this.setData({
      images: data,
      hidden: true,
      flag: false,
      currentImg: ''
    })
  },

Наконец, прикрепите демонстрацию демонстрации:GitHub.com/средний два-К…