小程序中拖拽和缩放图片

需求:点击元素后选中,出现缩放按钮,拖动缩放按钮可实现元素的缩放;并且元素本身是可以拖动的。

html:

html 复制代码
  <block wx:for="{{imageControls}}" wx:key="index">
          <view hidden="{{item.hiddenModel}}" class='insertImg_item' style='transform: scale({{item.scale}});top:{{item.insertImgTop}}px;left:{{item.insertImgLeft}}px;z-index:{{levelNum[index]}}'>
            <view class='insertImg_box {{currentImgIndex == index ? "insertImg_active":""}}'>
              <image src='{{item.url}}' data-index='{{index}}' style='width:{{item.insertImgWidth}}px;height:{{item.insertImgHeight}}px;' bindtouchstart='imgTouchStart' catchtouchmove='imgTouchMove' bindtouchend='imgTouchEnd'></image>
              <image wx:if="{{currentImgIndex == index}}" class='delete_icon' src='/image/state_icon3.png' style='transform: scale({{item.oScale}});transform-origin:center;' data-index='{{index}}' bindtap='toDeleteImg'></image>
              <image wx:if="{{currentImgIndex == index}}" class='drag_icon' src='/image/scale_icon.png' style='transform: scale({{item.oScale}});transform-origin:center;' data-index='{{index}}' bindtouchstart='scaleTouchStart' catchtouchmove='scaleTouchMove' bindtouchend='scaleTouchEnd'></image>
            </view>
          </view>
        </block>

css:

css 复制代码
.insertImg_item {
  transform-origin: center;
  position: absolute;
  z-index: 100;
}
.insertImg_box {
  width: 100%;
  transform-origin: center;
  float: left;
  box-sizing: border-box;
  position: relative;
}
.insertImg_active {
  border: 4rpx solid #4672FF;
}
/* 删除按钮 */
.delete_icon {
  position: absolute;
  top: -20rpx;
  left: -20rpx;
  width: 40rpx;
  height: 40rpx;
  z-index: 99;
}
/* 缩放按钮 */
.drag_icon {
  position: absolute;
  bottom: -25rpx;
  right: -25rpx;
  width: 50rpx;
  height: 50rpx;
  z-index: 99;
}

js:

javascript 复制代码
  // 开始拖拽
  imgTouchStart(e) {
    let index = e.currentTarget.dataset.index
    this.activateComponent(index)
    initialImgArray[index].lx = e.touches[0].clientX;  // 记录点击时的坐标值
    initialImgArray[index].ly = e.touches[0].clientY;
    this.setData({
      imageControls: initialImgArray
    })
  },
  // 拖拽中
  imgTouchMove(e) {
    let index = e.currentTarget.dataset.index
    const { clientX, clientY } = e.touches[0];
    const dx = clientX - initialImgArray[index].lx;
    const dy = clientY - initialImgArray[index].ly;
    // 更新图片位置
    initialImgArray[index].insertImgLeft += dx;
    initialImgArray[index].insertImgTop += dy;
    initialImgArray[index].x += dx;
    initialImgArray[index].y += dy;
    // 更新 lx 和 ly
    initialImgArray[index].lx = clientX;
    initialImgArray[index].ly = clientY;
    // 更新数据
    this.setData({
      imageControls: initialImgArray
    });
  },
  // 拖拽结束
  imgTouchEnd(e) {
    console.log(e)
    let index = e.currentTarget.dataset.index
    //重新计算左上角的坐标(如果没有缩放需求,不需要写这段代码)
    const imageWidth = initialImgArray[index].insertImgWidth * initialImgArray[index].scale;
    const imageHeight = initialImgArray[index].insertImgHeight * initialImgArray[index].scale;
    initialImgArray[index].newInsertImgLeft = Math.round(initialImgArray[index].x - imageWidth / 2);
    initialImgArray[index].newInsertImgTop = Math.round(initialImgArray[index].y - imageHeight / 2);
    this.setData({
      imageControls: initialImgArray
    })
  },
  //开始缩放
  scaleTouchStart: function (e) {
    let index = e.currentTarget.dataset.index;
    let clientX = e.touches[0].clientX;
    let clientY = e.touches[0].clientY;
    // 记录触摸初始位置
    initialImgArray[index].touchX = clientX;
    initialImgArray[index].touchY = clientY;
  },
  //缩放中
  scaleTouchMove: function (e) {
    let index = e.currentTarget.dataset.index;
    let clientX = e.touches[0].clientX;
    let clientY = e.touches[0].clientY;
    // 获取当前元素的位置和大小信息
    let element = initialImgArray[index];
    // 计算手指移动的距离变化
    let diffX = clientX - element.touchX;
    let diffY = clientY - element.touchY;
    // 计算移动距离与初始元素宽高的比例变化
    let scaleChangeX = diffX / element.insertImgWidth;
    let scaleChangeY = diffY / element.insertImgHeight;
    // 设置缩放的灵敏度,根据需要调整
    let sensitivity = 0.9;
    // 计算新的缩放比例,这里可以根据X和Y方向的缩放变化来综合计算
    let newScale = element.scale + (scaleChangeX + scaleChangeY) * sensitivity;
    // 限制最小缩放比例
    if (newScale < 0.2) {
      newScale = 0.2;
    }
    // 更新元素的缩放比例
    element.scale = newScale;
    // 更新手指位置
    element.touchX = clientX;
    element.touchY = clientY;
    // 更新视图
    this.setData({
      imageControls: initialImgArray
    });
  },
  // 缩放完成
  scaleTouchEnd(e) {
    let index = e.currentTarget.dataset.index
    // 计算缩放后的图片宽高
    const imageWidth = initialImgArray[index].insertImgWidth * initialImgArray[index].scale;
    const imageHeight = initialImgArray[index].insertImgHeight * initialImgArray[index].scale;
    initialImgArray[index].scaleInsertImgWidth = imageWidth
    initialImgArray[index].scaleInsertImgHeight = imageHeight
    // 计算缩放后图片的坐标
    initialImgArray[index].newInsertImgLeft = Math.round(initialImgArray[index].x - imageWidth / 2);
    initialImgArray[index].newInsertImgTop = Math.round(initialImgArray[index].y - imageHeight / 2);
    this.setData({
      imageControls: initialImgArray
    })
    console.log(this.data.imageControls)
  },
    // 删除图片
  toDeleteImg(e) {
    let index = e.currentTarget.dataset.index
    initialImgArray.splice(index, 1);
    that.setData({
      imageControls: initialImgArray
    })
  },

效果图:

相关推荐
全职计算机毕业设计1 天前
基于微信小程序的城市特色旅游推荐应用的设计与实现
微信小程序·小程序
说私域1 天前
线下消费经济“举步维艰”,开源AI智能名片链动2+1+S2B2C小程序线上“狂飙突进”!
人工智能·小程序·开源·零售
JAVA叶知秋2 天前
uniapp自定义底部导航栏h5有效果小程序无效的解决方案
小程序·uni-app
沙尘暴炒饭2 天前
用uniapp在微信小程序实现画板(电子签名)功能,使用canvas实现功能
微信小程序·小程序·uni-app
PyAIGCMaster2 天前
Taro 编译不平不同平台小程序
小程序
fakaifa3 天前
【开源版】likeshop上门家政系统PHP版全开源+uniapp前端
小程序·uni-app·php·家政小程序源码·家政服务小程序·源码下载·上门家政
说私域3 天前
基于定制开发开源AI智能名片S2B2C商城小程序的公私域流量融合运营策略研究
人工智能·小程序·开源·零售
阿諪諪3 天前
uniapp小程序中实现无缝衔接滚动效果
小程序·uni-app
我是小伍同学3 天前
基于卷积神经网络和Pyqt5的猫狗识别小程序
人工智能·python·神经网络·qt·小程序·cnn
爱分享的程序员4 天前
小程序消息订阅的整个实现流程
小程序